亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 3096 | 回復: 0
打印 上一主題 下一主題

[驅(qū)動] 求助,移植ADC驅(qū)動時kernel panic [復制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2011-11-15 13:37 |只看該作者 |倒序瀏覽
昨天移植了ADC驅(qū)動,但內(nèi)核啟動過程中會崩掉。

看內(nèi)核警告應該是 ioremap處出現(xiàn)了空指針(我是這么判斷的。。),但我看不出來。
麻煩高手指點一二~感激不盡~

以下是錯誤信息:
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
[00000000] *pgd=00000000
Internal error: Oops: 805 [#1]
last sysfs file:
Modules linked in:
CPU: 0    Not tainted  (2.6.32.46 #1
PC is at adc_init+0x78/0xb4
LR is at __arm_ioremap_pfn+0x120/0x138
pc : [<c0019ec0>]    lr : [<c00365bc>]    psr: a0000013
sp : c3823fb0  ip : 00000000  fp : 00000000
r10: 00000000  r9 : 00000000  r8 : 00000000
r7 : 00000000  r6 : 00000000  r5 : c0022680  r4 : c0443d34
r3 : 00000000  r2 : c486e004  r1 : ffffffe0  r0 : c0400384
Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: c000717f  Table: 30004000  DAC: 00000017
Process swapper (pid: 1, stack limit = 0xc3822270)
Stack: (0xc3823fb0 to 0xc3824000)
3fa0:                                     c0019e48 c002f37c c0019e48 00000000
3fc0: c040dbe0 c040dbe0 c00224c4 c0022680 00000000 00000000 00000000 00000000
3fe0: 00000000 c00083fc 00000000 00000000 00000000 c0030868 11cc37dc 33ec33cc
[<c0019ec0>] (adc_init+0x78/0xb4) from [<c002f37c>] (do_one_initcall+0x5c/0x1bc)
[<c002f37c>] (do_one_initcall+0x5c/0x1bc) from [<c00083fc>] (kernel_init+0xa0/0x1)
[<c00083fc>] (kernel_init+0xa0/0x11 from [<c0030868>] (kernel_thread_exit+0x0/0)
Code: ea000007 e2802004 e3a03000 e59f0030 (e5832000)
---[ end trace 0cab6b11a4649c09 ]---

這個是驅(qū)動源碼:
  1. #include <linux/errno.h>
  2. #include <linux/kernel.h>
  3. #include <linux/module.h>
  4. #include <linux/fs.h>
  5. #include <linux/init.h>
  6. #include <linux/serio.h>
  7. #include <linux/delay.h>
  8. #include <linux/miscdevice.h>
  9. #include <linux/clk.h>
  10. #include <linux/wait.h>
  11. #include <linux/irq.h>
  12. #include <linux/sched.h>
  13. #include <asm/io.h>
  14. #include <asm/irq.h>
  15. #include <asm/uaccess.h>
  16. #include <plat/regs-adc.h>

  17. #define DEVICE_NAME        "adc"

  18. static void __iomem *base_addr;

  19. typedef struct {
  20.         wait_queue_head_t wait;
  21.         int channel;
  22.         int prescale;
  23. }ADC_DEV;

  24. DECLARE_MUTEX(ADC_LOCK);

  25. static ADC_DEV adc_dev;
  26. static volatile int ev_adc = 0;
  27. static int adc_finish=0;
  28. static int owned_adc=0;
  29. static int adc_data;
  30. static struct clk    *adc_clock;

  31. #define ADCCON (base_addr + S3C2410_ADCCON)    //ADC control

  32. #define ADCTSC (base_addr + S3C2410_ADCTSC)    //ADC touch screen control

  33. #define ADCDLY (base_addr + S3C2410_ADCDLY)    //ADC start or Interval Delay

  34. #define ADCDAT0 (base_addr + S3C2410_ADCDAT0)    //ADC conversion data 0

  35. #define ADCDAT1 (base_addr + S3C2410_ADCDAT1)    //ADC conversion data 1

  36. #define ADCUPDN (base_addr + 0x14)    //Stylus Up/Down interrupt status

  37. /* ADCCON寄存器設置 */
  38. #define PRESCALE_DIS (0 << 14)                //預分頻禁止
  39. #define PRESCALE_EN (1 << 14)                //預分頻使能
  40. #define PRSCVL(x) ((x) << 6)                //預分頻系數(shù),0~255之間
  41. #define ADC_INPUT(x) ((x) << 3)                //設置模擬信號輸入頻道
  42. #define ADC_START (1 << 0)                //通過讀取啟動ADC
  43. #define ADC_ENDCVT (1 << 15)                //轉(zhuǎn)換結(jié)束標志

  44. /* 設置輸入頻道為ch,預分頻系數(shù)為prescale,并使能ADC轉(zhuǎn)換 */
  45. static void start_adc(int ch,int prescale)
  46. {
  47.         unsigned int tmp;

  48.         tmp = PRESCALE_EN | PRSCVL(prescale) | ADC_INPUT(ch);
  49.         writel(tmp,ADCCON);

  50.         tmp = readl(ADCCON);
  51.         tmp |= ADC_START;
  52.         writel(tmp,ADCCON);
  53. }

  54. static irqreturn_t adc_interrupt(int irq,void *dev_id)
  55. {
  56.         if(owned_adc){       
  57.                 adc_data = readl(ADCDAT0)& 0x3ff;
  58.                 adc_finish = 1 ;
  59.                 wake_up_interruptible(&adc_dev.wait);
  60.         }
  61.         return IRQ_HANDLED;
  62. }

  63. static ssize_t adc_read(struct file *filp,char *buffer , size_t count ,loff_t *ppos)
  64. {
  65.         if(down_trylock(&ADC_LOCK)==0){
  66.                 owned_adc = 1;
  67.                 start_adc(adc_dev.channel,adc_dev.prescale);
  68.                 wait_event_interruptible(adc_dev.wait,adc_finish);
  69.                
  70.                 adc_finish = 0;

  71.                 copy_to_user(buffer,(char *)&adc_data,sizeof(adc_data));
  72.                 owned_adc = 0;

  73.                 up(&ADC_LOCK);
  74.                 return sizeof(adc_data);
  75.         }
  76.         return -EINVAL;
  77. }

  78. static int adc_open(struct inode *inode,struct file *filp)
  79. {
  80.         int ret;
  81.         init_waitqueue_head(&(adc_dev.wait));

  82.         adc_dev.channel = 0;
  83.         adc_dev.prescale = 0xff;

  84.         ret = request_irq(IRQ_ADC,adc_interrupt,IRQF_SHARED,DEVICE_NAME,&adc_dev);
  85.         if(ret){
  86.                 free_irq(IRQ_ADC,&adc_dev);
  87.                 return ret;
  88.         }
  89.         return 0;
  90. }

  91. static int adc_release(struct inode *inode , struct file *filp)
  92. {
  93.         free_irq(IRQ_ADC,&adc_dev);
  94.         return 0;
  95. }

  96. static struct file_operations adc_fops = {
  97.         .owner        =        THIS_MODULE,
  98.         .open         =        adc_open,
  99.         .read        =        adc_read,
  100.         .release=        adc_release,
  101. };

  102. static struct miscdevice adc_misc ={
  103.         .minor        =        MISC_DYNAMIC_MINOR,
  104.         .name        =        DEVICE_NAME,
  105.         .fops        =        &adc_fops,
  106. };

  107. static int __init adc_init(void)
  108. {
  109.         int ret;
  110.         printk("func:%s",__FUNCTION__);
  111.        
  112.         adc_clock = clk_get(NULL,"adc");

  113.         if(!adc_clock){
  114.                 printk(KERN_ERR "failed to get adc clock source \n");
  115.                 return -ENOENT;
  116.         }

  117.         clk_enable(adc_clock);
  118.        
  119.         base_addr = ioremap(S3C2410_PA_ADC,0x20);
  120.         if(base_addr == NULL){
  121.                 printk(KERN_ERR "Failed to remap register block\n");
  122.                 return -ENOMEM;
  123.         }

  124.         writel(ADCTSC,0);
  125.        
  126.         ret = misc_register(&adc_misc);
  127.        
  128.         printk(DEVICE_NAME "\t :initiated!\n");

  129.         return ret;
  130. }

  131. static void __exit adc_exit(void)
  132. {
  133.     free_irq(IRQ_ADC, &adc_dev);
  134.     iounmap(base_addr);

  135.     if (adc_clock) {
  136.         clk_disable(adc_clock);
  137.         clk_put(adc_clock);
  138.         adc_clock = NULL;
  139.     }

  140.     misc_deregister(&adc_misc);
  141. }

  142. EXPORT_SYMBOL(ADC_LOCK);
  143. module_init(adc_init);
  144. module_exit(adc_exit);
  145. MODULE_LICENSE("GPL");
  146. M
復制代碼
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP