5350和我之前用的三星和全志的芯片在中断这块有点差别,三星和全志的都是有专门的外部中断管脚,并且每个中断管脚对应一个中断号,对管脚寄存器的配置即irq_desc里chip变量,都是bsp里自带的,我们只需要用request_irq来注册irqaction就可以了。
而5350所有的gpio共用一个中断号6,所以想用哪个管脚都得自己配。有可能能用request_irq,但是驱动里已经有
setup_irq(SURFBOARDINT_GPIO,&ralink_gpio_irqaction);
所以我觉的还是在他这个基础上改比较好
1. 在5350 中断初始化的时候会调用ralink_gpio_init_irq函数
ralink_gpio_init_irq定义在driver/char/ralink_gpio.c
void __init ralink_gpio_init_irq(void)
{
setup_irq(SURFBOARDINT_GPIO,&ralink_gpio_irqaction);
}
这里已经调用了setup_irq函数来给irq_desc设置了irqaction,那么我们就不用再自己来用request_irq函数来设置irqaction了。
因为5350里所有的gpio中断都共享了6号中断,那么我们如果想让哪个gpio产生中断的话,需要自己来对相关的gpio进行配置。
2. 现在我们想让i2c clk管脚配置为中断模式的话,需要以下几个步骤
1) 查看datasheet 第1.3节 pin sharing scheme
确定I2C_SCLK 为2号GPIO
2) 查看datasheet第3.4节 system control
将GPIOMODE寄存器的第0位设置为1,即将I2C设置为gpio模式。
代码如下:
gpiotmp = le32_to_cpu(*(volatile u32 *)(RALINK_REG_GPIOMODE));
gpiotmp |= 0x1;
*(volatile u32 *)(RALINK_REG_GPIOMODE) = cpu_to_le32(gpiotmp);
3) 查看datasheet 第3.6节 interrupt controller
将INTENA寄存器的第6位设置为1,即使能PIO中断。
代码如下:
gpiotmp = le32_to_cpu(*(volatile u32*)(RALINK_REG_INTENA));
gpiotmp |= (0x01 << 6);
*(volatile u32 *)(RALINK_REG_INTENA) =cpu_to_le32(gpiotmp);
4) 查看datasheet 第3.10节 programmable I/O
将GPIO21_00_RENA和GPIO21_00_FENA这两个寄存器的第2位设置为1,即2号GPIO的上升沿和下降沿的中断使能。
代码如下:
gpiotmp = le32_to_cpu(*(volatile u32*)(RALINK_REG_PIORENA));
gpiotmp |= (0x01 << 2);
*(volatile u32 *)(RALINK_REG_PIORENA) =cpu_to_le32(gpiotmp);
gpiotmp = le32_to_cpu(*(volatile u32*)(RALINK_REG_PIOFENA));
gpiotmp |= (0x01 << 2);
*(volatile u32 *)(RALINK_REG_PIOFENA) =cpu_to_le32(gpiotmp);
将GPIO21_00_DIR寄存器的第2位设置为0,即为输入模式。
代码如下
gpiotmp = le32_to_cpu(*(volatile u32*)(RALINK_REG_PIODIR));
gpiotmp &= ~cpu_to_le32(0x01<< 2);
*(volatile u32 *)(RALINK_REG_PIODIR) =cpu_to_le32(gpiotmp);
以上代码都是放置在ralink_gpio_init函数中
3. 通过上面的设置,ralink_gpio_irq_handler这个中断处理函数就可以被调用了。