rt5350 中断初始化

来源:互联网 发布:内蒙古七二三工程知乎 编辑:程序博客网 时间:2024/05/23 00:50

linux 下的中断初始化,实际就是对 irq_desc 这个结构体进行初始化,其中最关键莫过于

irq_flow_handler_t    handle_irq            中断处理函数

struct irqaction         *action                   用户自己设置的处理函数链表,由handle_irq调用

struct irq_chip        *chip                        硬件相关的操作,比如设置管脚为中断模式,使能中断等等。

这三个结构体成员变量的赋值了,其中handle_irq和chip一般官方的bsp里会为我们设置好,而action链表是我们自己的中断处理函数,handle_irq会去遍历action链表并执行。系统中每一个中断号会对应一个irq_desc结构体。

kernel/irq/handle.c,系统为我们定义并初始化了一个irq_desc的结构体数组,中断号为数组下标。也就是

说每一个中断号会对应一个irq_desc结构体。linux整个中断机制实际就是围绕这个结构体数组进行的,即,

赋值,调用等等。



1. arch/mips/kernel/irq_cpu.c

    mips_cpu_irq_init

            for (i = irq_base + 2; i < irq_base + 8; i++)
                    set_irq_chip_and_handler(i, &mips_cpu_irq_controller,handle_level_irq);

         irq_base为0,实际上注册了2 -- 7 中断号的处理函数

2. kernel/irq/chip.c

    set_irq_chip_and_handler

           __set_irq_handler

                desc->handle_irq = handle

       最终是把handle_level_irq作为这个6个中断号的中断处理函数


handle_level_irq

1.  kernel/irq/chip.c

     handle_level_irq

            handle_IRQ_event(irq, action)

2.kernel/irq/handle.c

      handle_IRQ_event

                   do {
                      ret = action->handler(irq, action->dev_id);
                     if (ret == IRQ_HANDLED)
                             status |= action->flags;
                      retval |= ret;
                     action = action->next;
               } while (action);

                 这里挨个调用desc中action链表中的处理函数进行真正的中断处理


下面分析rt5350中对gpio中断的初始化,从 include/asm-mips/rt2880/surfboardint.h 中可以看到

#define SURFBOARDINT_GPIO     6    /* GPIO */

说明GPIO中断的中断号为6,这块和三星的芯片差别比较大,三星的芯片有专门的外部中断管脚(虽然也是

GPIO管脚复用),但是每个外部中断管脚对应一个中断号。而且ralink的是所有的GPIO复用中断管脚共用一个

中断号6. 而且ralink的bsp中给6号中断已经注册了action链表,那,我想我们就不用自己调用request_irq函数去

给他注册action链表了吧,直接修改ralink_gpio_irqaction应该就行了吧

1. arch/mips/kernel/head.S

    j        start_kernel

2. init/main.c

      start_kernel

                     init_IRQ

3.  arch/mips/kernel/irq.c

     init_IRQ

                    arch_init_irq

4.  arch/mips/rt2880/irq.c

        arch_init_irq

                   ralink_gpio_init_irq

5. drivers/char/ralink_gpio.c

        ralink_gpio_init_irq

             setup_irq(SURFBOARDINT_GPIO, &ralink_gpio_irqaction);

            实际上request_irq也是调用setup_irq来注册中断处理函数,那么我们就不应该再去调用request_irq了,实际上系统已经为我们做好了6号中断的注册,我们应该只需要将我们需要的GPIO管脚设置为中断模式即可。

             其中SURFBOARDINT_GPIO=6,在这个函数中注册action,以供handle_IRQ_event调用

  使用cat /proc/interrupts命令可以看到gpio中断号的确是6


1 0
原创粉丝点击