OK6410 linux3.0.1 外部中断组1~9无法request_irq的解决方法
来源:互联网 发布:医学数据分析软件 编辑:程序博客网 时间:2024/06/05 11:44
因项目需求远程遥控,准备在OK6410上使用红外线控制板子。由于板子上自带的红外所接引脚GPE1几乎等同于摆设,故需要外加红外头。在写驱动的时候发现中断组1~9无法request_irq成功,咨询官方技术支持和论坛没有任何答复,只好自己改内核了。仔细看源码,飞凌居然没初始化19组的中断,我和我的小伙伴都惊呆了
以下代码加入到irq-eint.c中
static inline void s3c_irq_eint_group_78_mask(struct irq_data *data){ u32 mask; mask = __raw_readl(S3C64XX_EINT78MASK); mask |= (u32)data->chip_data; __raw_writel(mask, S3C64XX_EINT78MASK);}static void s3c_irq_eint_group_78_unmask(struct irq_data *data){ u32 mask; mask = __raw_readl(S3C64XX_EINT78MASK); mask &= ~((u32)data->chip_data); __raw_writel(mask, S3C64XX_EINT78MASK);}static inline void s3c_irq_eint_group_78_ack(struct irq_data *data){ //__raw_writel(__raw_readl(S3C64XX_EINT78PEND)&~((u32)data->chip_data), S3C64XX_EINT78PEND); __raw_writel((u32)data->chip_data, S3C64XX_EINT78PEND);//此处不知为何}static void s3c_irq_eint_group_78_maskack(struct irq_data *data){ /* compiler should in-line these */ s3c_irq_eint_group_78_mask(data); s3c_irq_eint_group_78_ack(data);}static int s3c_irq_eint_set_group_78_type(struct irq_data *data, unsigned int type){ int offs = (data->irq - IRQ_EINT_GROUP(7, 0)); int pin, pin_val; int shift; u32 ctrl, mask; u32 newvalue = 0; void __iomem *reg; if (offs > 31) { printk(KERN_EMERG"offs in s3c_irq_eint_set_group_78_type %d\n", offs); return -EINVAL; } reg = S3C64XX_EINT78CON; switch (type) { case IRQ_TYPE_NONE: printk(KERN_WARNING "No edge setting!\n"); break; case IRQ_TYPE_EDGE_RISING: newvalue = S3C2410_EXTINT_RISEEDGE; break; case IRQ_TYPE_EDGE_FALLING: newvalue = S3C2410_EXTINT_FALLEDGE; break; case IRQ_TYPE_EDGE_BOTH: newvalue = S3C2410_EXTINT_BOTHEDGE; break; case IRQ_TYPE_LEVEL_LOW: newvalue = S3C2410_EXTINT_LOWLEV; break; case IRQ_TYPE_LEVEL_HIGH: newvalue = S3C2410_EXTINT_HILEV; break; default: printk(KERN_ERR "No such irq type %d", type); return -1; } shift = (offs / 4) * 4; mask = 0x7 << shift; ctrl = __raw_readl(reg); ctrl &= ~mask; ctrl |= newvalue << shift; __raw_writel(ctrl, reg); /* set the GPIO pin appropriately */ if (offs <= 15) { pin = S3C64XX_GPO(offs); pin_val = S3C_GPIO_SFN(3); //GPO口0x11表示外部中断 } else { pin = S3C64XX_GPP(offs - 16); pin_val = S3C_GPIO_SFN(3); } s3c_gpio_cfgpin(pin, pin_val); return 0;}static struct irq_chip s3c_irq_eint_group78 ={ .name = "s3c-eintgroup78", .irq_mask = s3c_irq_eint_group_78_mask, .irq_unmask = s3c_irq_eint_group_78_unmask, .irq_mask_ack = s3c_irq_eint_group_78_maskack, .irq_ack = s3c_irq_eint_group_78_ack, .irq_set_type = s3c_irq_eint_set_group_78_type, .irq_set_wake = s3c_irqext_wake,};static inline void zc_irq_demux_eint_group78(){ u32 status = __raw_readl(S3C64XX_EINT78PEND); u32 mask = __raw_readl(S3C64XX_EINT78MASK); unsigned int irq; status &= ~mask; status >>= 0; status &= (1 << (31 - 0 + 1)) - 1; for (irq = IRQ_EINT_GROUP(7, 0); irq <= IRQ_EINT_GROUP(8, 14); irq++) { if (status & 1) generic_handle_irq(irq); else printk("%d status is not 1\n", irq); status >>= 1; }}//注册78组外部中断static inline void zc_init_irq_data_chip_group78(){ int i = 0; for (i = 0; i < 31; i++) { if (i <= 15) { //设置desc.irq_data.chip函数组和desc->handle_irq默认触发函数 irq_set_chip_and_handler(IRQ_EINT_GROUP(7, i), &s3c_irq_eint_group78, handle_level_irq); //设置desc.irq_data.chip_data irq_set_chip_data(IRQ_EINT_GROUP(7, i), (void *)((u32)(1 << (IRQ_EINT_GROUP(7, i) - IRQ_EINT_GROUP(7, 0))))); set_irq_flags(IRQ_EINT_GROUP(7, i), IRQF_VALID); } else { irq_set_chip_and_handler(IRQ_EINT_GROUP(8, i - 16), &s3c_irq_eint_group78, handle_level_irq); irq_set_chip_data(IRQ_EINT_GROUP(8, i - 16), (void *)((u32)(1 << (IRQ_EINT_GROUP(8, i - 16) - IRQ_EINT_GROUP(7, 0))))); set_irq_flags(IRQ_EINT_GROUP(8, i - 16), IRQF_VALID); } } irq_set_chained_handler(S3C64XX_IRQ_VIC1(21), zc_irq_demux_eint_group78);}
- OK6410 linux3.0.1 外部中断组1~9无法request_irq的解决方法
- ZC301摄像头,OK6410的开发板,linux3.0.1,内核Oops的解决方法
- WIN8.1为OK6410安装linux3.0.1遇到的若干问题总结以及解决方案
- 移植Linux3.0.1到OK6410上
- OK6410移植linux3.5(1)
- s3c6410---外部中断---key (基于OK6410)
- s3c6410---外部中断---key (基于OK6410)
- s3c6410---外部中断---key (基于OK6410)
- STM32外部中断无法触发的问题
- stm32 EXTI中断BUG,无法进入外部中断的问题
- OK6410移植linux3.3.1
- OK6410移植linux3.3.5
- OK6410移植linux3.3.5
- OK6410移植Linux3.12.16
- warning: passing argument 2 of 'request_irq' from incompatible pointer type导致的中断申请失败和模块无法加载
- Linux3.6.7在OK6410平台的移植(六)按键
- Linux3.6.7在OK6410平台的移植(七)DM9000
- Linux3.6.7在OK6410平台的移植(八)NFS
- EXt js 学习笔记总结
- 链表——约瑟夫问题 百练2746
- Linux下pppd拨号脚本配置
- couchDB权限设置问题
- hdu2209翻纸牌游戏
- OK6410 linux3.0.1 外部中断组1~9无法request_irq的解决方法
- MFC 快速建立线程
- 解决ViewFlipper的OnClick方法与手势冲突的方法
- 买笔记本的“艰辛”
- 对C++默认构造函数的理解
- mailto 参数说明
- DUI控件
- 几个有用的php字符串过滤,转换函数代码
- ExtJs修改字体大小格式