2013-03-06 19 views
9

私は割り込みを登録して処理できる単純なカーネルモジュールを作成しています。 私は 、request_irq関数を呼び出すことにより、割り込み登録しようとすると、それはエラーコード-22を返ししかし、私は信じてい単純な割り込みハンドラ:request_irqがエラーコード-22を返します

ERROR: Cannot request IRQ 30 - code -22 , EIO 5 , EINVAL 22

を、このエラーコードがEINVALに等しい(不正な引数)

教えてください私は間違ってやっています。

#include <linux/init.h> 
#include <linux/module.h> 
#include <linux/irq.h> 
#include <linux/io.h> 
#include <linux/irqdomain.h> 
#include <linux/interrupt.h> 
#include <linux/of.h> 
#include <linux/of_address.h> 

#include <asm/exception.h> 
#include <asm/mach/irq.h> 

void int068_interrupt(int irq, void *dev_id, struct pt_regs *regs) 
{ 
    printk("Interrupt should be handled there\n"); 
} 

static int __init 
clcdint_init(void) 
{ 
    unsigned int irq; 
    unsigned int irqflags; 
    int ret; 

    irq=68; 
    irqflags=IRQF_SHARED | IRQF_NO_SUSPEND; 

    ret = request_irq(irq, int068_interrupt, 
      irqflags, "clcdint-int068", NULL); 

    if (ret!=0) { 
      printk("ERROR: Cannot request IRQ %d", irq); 
      printk(" - code %d , EIO %d , EINVAL %d\n", ret, EIO, EINVAL); 
    } 

    printk("CLCDINT_INIT\n"); 
    return 0; 
} 

module_init(clcdint_init); 

static void __exit 
clcdint_exit(void) 
{ 
    unsigned int irq; 
    irq=68; 
    free_irq(irq, NULL); 
    printk("CLCDINT_EXIT\n"); 
} 

module_exit(clcdint_exit); 

答えて

12

あなたはNULLコンテキスト(request_irq()呼び出しの最後のパラメータ)は、共有割り込みラインを扱う(IRQF_SHAREDフラグがオンである)渡すことはできません:ここではモジュールです。

同じIRQを共有する2つの同一のネットワークカードがあるとします。同じドライバが同じ割り込みハンドラ関数、同じirq番号、同じ記述を渡します。 contextパラメータ以外の2つの登録インスタンスを区別する方法はありません。

したがって、IRQF_SHAREDフラグを渡すと、NULLコンテキストパラメータを渡すことはできません。

+0

はどうもありがとうございました! 'irqflags = IRQF_NO_SUSPEND;'を変更した後は、やっと動作しています! –

+0

最後のコメントに記載されている変更を適用した後でも、同じエラーメッセージ(「エラー:IRQ 68 - コード-22、EIO 5、EINVAL 22を要求できません」)が表示されます。これを引き起こしているのはあなたが知っていますか? (btw、私はカーネルバージョン2.6.32を使用しているので、インクルードされたファイルのいくつかはここには存在しません。これはおそらく関連しています) – jaff

+0

問題はIRQ番号と関係していました。 http://www.webopedia.com/quick_ref/IRQnumbers.aspを見て、IRQ番号を10、代わりに0fに変更して、すべてが機能しています。 – jaff

-2

irqflagsのタイプはunsigned intですが、元々はlongでした。

次の文を試してみてください、それは間違いなく動作します:

request_irq(irq, int068_interrupt,IRQF_SHARED | IRQF_NO_SUSPEND, "clcdint-int068", NULL);

関連する問題