4

私は、cortex-A9 開発ボードで実験を行いました。gpio_to_irq() を使用して irq num を取得し、irq を要求して小さなドライバーを作成しました。syslog では 196 でした。そして、asm_do_IRQ にいくつかの printks を追加しました。gpio 割り込みをトリガーしたとき、ドライバーは正常に動作しますが、asm_do_IRQ の irq num は 62 でした。理解できません。irq 番号が要求したものと異なっていたのはなぜですか? ドライバーは以下の通りです。

    #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");

arch/arm/kernel/irq.c の asm_do_IRQ

    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

1 に答える 1

4

この観察結果は、物理 IRQ 番号と仮想 IRQ 番号の間のマッピングが原因である可能性があります。ドライバーに表示される数値は仮想 IRQ 数値であり、Linux の汎用割り込み処理サブシステムを使用している場合にのみ有効です。割り込み番号asm_do_IRQは、コアの割り込みファブリックによって提供される物理的な割り込み番号になります。

OMAP プロセッサは GPIO ピンの割り込みをサポートしていると思います。これが通常実装される方法は、GPIO 入力のバンク (たとえば 32 ビット) に単一の IRQ ラインを割り当てることです。いずれかの GPIO で割り込みが発生すると、その IRQ ラインがアクティブになります。これはおそらく、プロセッサーの 62 番です。プロセッサのマニュアルを見ると、IRQ 62 が GPIO バンクの割り込みに対応していることがわかります。

これで、Linux GPIO サブシステムにより、任意の GPIO に割り込みハンドラーを割り当てることができるようになり、Linux irq 番号から物理 irq 番号へのマッピングが提供されます。この場合の Linux irq 番号は 196 です。GPIO サブシステムは、すべての GPIO 割り込み (割り込み 62 など) を処理し、GPIO レジスタを読み取って、バンク内のどの GPIO ビットが割り込みを生成した可能性があるかを判断し、次に呼び出すように構成されています。で割り当てた割り込みハンドラ request_irq

GPIO 割り込みの基本的な制御フローは次のとおりです。

  1. GPIO バンクの割り込みで変更が発生します。IRQ 62 が発生します。
  2. asm_do_IRQIRQ 62 で実行されます。GPIO サブシステムは、プラットフォームの初期化コードによって IRQ 62 を処理するように登録されています。
  3. GPIO サブシステムは、GPIO レジスタを読み取り、GPIO ビット X が割り込みを発生させたと判断します。ビット X から Linux 仮想 IRQ 番号 (この場合は 196) へのマッピングを計算します。
  4. 次に、GPIO 割り込みハンドラーは、割り込みハンドラーをgeneric_handle_irq呼び出す 196 で関数を呼び出します。

通常、仮想 IRQ 番号と物理 IRQ 番号の間には、プラットフォームによって定義された静的マッピングがあります。このマッピングを表示するには、

  • CONFIG_VIRQ_DEBUGlinux-3.4 より古いカーネルで有効にする、または
  • CONFIG_IRQ_DOMAIN_DEBUG新しいカーネルで有効にします。

次に、irq_domain_mappingdebugfs ファイルを確認します。たとえば、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  /soc8347@e0000000/pic@700
   18  0x00012  IPIC             0xcf801c80  /soc8347@e0000000/pic@700
   19  0x0000e  IPIC             0xcf801c80  /soc8347@e0000000/pic@700
   20  0x0000f  IPIC             0xcf801c80  /soc8347@e0000000/pic@700
   21  0x00010  IPIC             0xcf801c80  /soc8347@e0000000/pic@700
   77  0x0004d  IPIC             0xcf801c80  /soc8347@e0000000/pic@700
于 2013-04-08T07:48:41.767 に答える