2013-04-08 85 views
4

請求我做了一些實驗用皮質-A9開發板不同。我用gpio_to_irq()來獲取一個IRQ Num和我要求的IRQ和寫了一個小驅動程序,它是在系統日誌196。我在asm_do_IRQ中添加了一些printks。當我觸發gpio中斷時,驅動程序工作正常,但asm_do_IRQ中的irq num是62,我無法理解。爲什麼irq號碼與我要求的不一樣?該驅動程序是如下:的內核函數asm_do_IRQ()IRQ是從一個I在模塊

#include <linux/module.h> 
    #include <linux/interrupt.h> 
    #include <linux/irq.h> 
    #include <linux/gpio.h> 

    #define GPIO_N 36  //gpio number 

    int flag = 0; 

    static irqreturn_t handler(int irq,void *dev_id) 
    { 
      printk("hello world hahahahahhahahah \n\n"); 
      return 0; 
    } 

    static int __init gpio_test_init(void) 
    { 
      if(gpio_request_one(GPIO_N,GPIOF_DIR_IN,"some test")<0) 
      { 
        printk(KERN_ERR "Oops! BAD! BAD! BAD!\n\n"); 
        return 0; 
      } 

      int irq,irq2; 
      irq = OMAP_GPIO_IRQ(TEST_GPIO); 
      printk("irq : %d \n",irq,irq2); 
      // .................. 
      // irq : 196 in dmesg 
      //...................... 
      set_irq_type(irq,IRQ_TYPE_EDGE_FALLING); 
      enable_irq(gpio_to_irq(GPIO_N)); 
      int err; 
      // request the irq ... 
      if((err = request_irq(irq,&handler,0,NULL,NULL))<0) 
      { 
        printk("err : %d\n",err); 
        return 0; 
      } 
      printk("gpio test init success!\n"); 
      flag = 1; 
      return 0; 
    } 
    static void __exit gpio_test_exit(void) 
    { 
      int irq = gpio_to_irq(TEST_GPIO); 
      if(flag == 1)free_irq(irq,NULL); 
      gpio_free(TEST_GPIO); 
      printk("gpio test exit byebye!\n"); 
    } 

    module_init(gpio_test_init); 
    module_exit(gpio_test_exit); 
    MODULE_LICENSE("GPL"); 

asm_do_IRQ在arch /臂/內核/ irq.c

asmlinkage void __exception_irq_entry 
    asm_do_IRQ(unsigned int irq, struct pt_regs *regs) 
    { 
      struct pt_regs *old_regs = set_irq_regs(regs); 
      printk("the irq : %d\n",irq); 
      //............... 
      // I get 62 here 
      //............... 
      irq_enter(); 

      /* 
      * Some hardware gives randomly wrong interrupts. Rather 
      * than crashing, do something sensible. 
      */ 
      if (unlikely(irq >= nr_irqs)) { 
        if (printk_ratelimit()) 
          printk(KERN_WARNING "Bad IRQ%u\n", irq); 
        ack_bad_irq(irq); 
      } else { 
        generic_handle_irq(irq); 
      } 

      /* AT91 specific workaround */ 
      irq_finish(irq); 

      irq_exit(); 

      set_irq_regs(old_regs); 

    } 

回答

4

這個觀察可能是由於物理和虛擬IRQ號之間的映射。您的驅動程序中顯示的數字是虛擬IRQ編號,僅在使用通用Linux中斷處理子系統時纔有效。 asm_do_IRQ中的中斷號將是內核中斷結構提供的物理中斷號。

相信OMAP處理器的支持上GPIO引腳中斷。通常實現的方式是爲一組GPIO輸入分配一個IRQ線,比如說32位。當任何GPIO發生中斷時,該IRQ線路將被激活。這可能是您的處理器上的數字62。如果您查看處理器的手冊,您應該看到IRQ 62對應於GPIO bank上的中斷。現在

,Linux的GPIO子系統將允許您將中斷處理程序分配給任何的GPIO,爲您提供從Linux IRQ號到物理IRQ號的映射。在你的情況下,linux irq編號爲196. GPIO子系統配置爲處理所有GPIO中斷(比如中斷62),讀取GPIO寄存器以確定bank中哪些GPIO位可能產生中斷,然後調出您分配的中斷處理程序爲request_irq

這裏是控制的一個GPIO中斷基本流程:在一個GPIO銀行發生中斷時

  1. 的變化。 IRQ 62被提出。
  2. asm_do_IRQ上IRQ 62. GPIO子系統運行遭搶注的平臺初始化代碼來處理IRQ 62。
  3. 的GPIO子系統讀取GPIO寄存器並確定GPIO位X已經導致了中斷。它計算從位X到linux虛擬IRQ編號的映射(在本例中爲196)。
  4. GPIO中斷處理程序然後調用generic_handle_irq函數,196調用中斷處理函數。

通常有由虛擬IRQ號和物理IRQ數之間的平臺中定義的靜態映射。要查看該映射,

  • 內核上實現CONFIG_VIRQ_DEBUG比Linux-3.4年紀大了,或者
  • 在新的內核啓用CONFIG_IRQ_DOMAIN_DEBUG

然後看看irq_domain_mapping debugfs文件。例如。在PowerPC上:

# mount -t debugfs none /sys/kernel/debug 
# cat /sys/kernel/debug/irq_domain_mapping 
irq hwirq chip name  chip data domain name 
    16 0x00009 IPIC    0xcf801c80 /[email protected]/[email protected] 
    18 0x00012 IPIC    0xcf801c80 /[email protected]/[email protected] 
    19 0x0000e IPIC    0xcf801c80 /[email protected]/[email protected] 
    20 0x0000f IPIC    0xcf801c80 /[email protected]/[email protected] 
    21 0x00010 IPIC    0xcf801c80 /[email protected]/[email protected] 
    77 0x0004d IPIC    0xcf801c80 /[email protected]/[email protected] 
+0

+1您可以使用術語* virtual *和* physical * IRQ。但是,它實際上更像一個*主/父* IRQ控制器和*從/子* IRQ控制器。由於Linux只使用一個編號和* master *映射,所以對應於1-1。對於其他*鏈接* IRQ,通常從偏移量開始。這是分裂的頭髮,並且可能以任何一種方式看待它都會讓你有同樣的觀點。更重要的是,'asm_do_IRQ'只涉及* master/parent * IRQ控制器。 – 2013-04-08 19:39:49

+0

@artless噪聲,也就是說,62是主/從IRQ控制器上的irq num,而196是從/子IRQ控制器上的irq num。 – goodjesse 2013-04-09 01:55:47

+0

@goodjesse沒錯。奧斯汀的描述是正確的,但*主/從*可能更適合代碼的結構;或者至少是另一種理解相同事物的方式。 GPIO模塊可能有一些像微型中斷控制器一樣的寄存器。 – 2013-04-09 03:22:48