2010-04-12 21 views
2

第一次張貼,所以請原諒任何愚蠢。爲什麼我不能在Linux 2.6.26中註冊邊沿觸發的中斷?

我正在爲從2.6.22到2.6.26爲MPC83xx構建的Linux內核上移植定製CPLD驅動程序,並且正在接收意外的Oops。該驅動程序對.22內核工作正常,但在我對request_irq的調用中,.26內核窒息。有人知道爲什麼行爲發生了變化,或者更好,我需要做些什麼來解決它?

我的哎呀來源追查到調用內核/ IRQ/manage.c,其中desc->chip->enable(irq)被稱爲setup_irq(),它看起來像函數指針,以使在以ipic_set_irq_type()通話被清除在arch/powerpc/sysdev/ipic.c中。不幸的是,我不知道爲什麼。

我已經包含Oops和複製問題的示例內核模塊。

哎呀 -

Unable to handle kernel paging request for instruction fetch 
Faulting instruction address: 0x00000000 
Oops: Kernel access of bad area, sig: 11 [#1] 
PREEMPT SCPA-G2 
Modules linked in: cpld(+) 
NIP: 00000000 LR: c004b930 CTR: 00000000 
REGS: df8b5df0 TRAP: 0400 Not tainted (2.6.26-twacs-100.0.0) 
MSR: 20001032 <ME,IR,DR> CR: 24022422 XER: 20000000 
TASK = dfbcfc00[488] 'insmod' THREAD: df8b4000 
GPR00: 00000000 df8b5ea0 dfbcfc00 00000017 00000001 00000001 00000000 c02d1fb4 
GPR08: 00002268 00000000 00000000 00000000 44022484 10073f68 1ffcb000 007ffeb0 
GPR16: 00000000 00000000 00800000 00000000 bffff7f0 00000000 1006e3dc 00000000 
GPR24: 00000002 00000000 00000000 00009032 df9d04c0 00000017 df8b4000 c02d40e4 
NIP [00000000] 0x0 
LR [c004b930] setup_irq+0x404/0x430 
Call Trace: 
[df8b5ea0] [c004b8ec] setup_irq+0x3c0/0x430 (unreliable) 
[df8b5ed0] [c004bbd8] request_irq+0xe0/0x130 
[df8b5f00] [e1078054] cpld_init+0x54/0xd0 [cpld] 
[df8b5f10] [c0048ba0] sys_init_module+0x14c/0x1d8 
[df8b5f40] [c0010008] ret_from_syscall+0x0/0x38 
--- Exception: c01 at 0xff27bb0 
    LR = 0x10019ca8 
Instruction dump: 
XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX 
XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX 
Kernel panic - not syncing: Fatal exception 

模塊 -

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

static unsigned int cpld_virq = NO_IRQ; 
unsigned value = 0xdeadbeef; 

static irqreturn_t cpld_isr(int irq, void *dev_id) { 
    return IRQ_HANDLED; 
} 

void __exit cpld_cleanup(void) { 
    free_irq(cpld_interrupt, &value); 
    irq_dispose_mapping(cpld_virq); 
    return; 
} 

int __init cpld_init(void) { 
    int retval; 
    unsigned long cpld_interrupt = 23; 

    cpld_virq = irq_create_mapping(NULL, cpld_interrupt); 
    if (cpld_virq == NO_IRQ) { 
     return -EBUSY; 
    } 

    retval = request_irq(cpld_virq, cpld_isr, 
      IRQF_DISABLED | IRQF_SHARED | IRQF_TRIGGER_FALLING, 
      "CPLD", &value); 
    if (retval) { 
     irq_dispose_mapping(cpld_virq); 
     return retval; 
    } 

    return 0; 
} 

module_init(cpld_init); 
module_exit(cpld_cleanup); 
MODULE_LICENSE("Dual BSD/GPL"); 

感謝您的幫助。我已經打了好幾天了,並且歡迎提供任何建議。

+0

它看起來特定於邊緣觸發的IRQ。級別觸發的外部IRQ不會導致Oops。也許我錯過了一些額外的設置? – Sam 2010-04-12 21:18:14

回答

1

Aaah。聽起來像JayM很接近,但不是因爲他的想法。我剛剛在linuxppc-dev郵件列表中看到一個補丁,指出邊緣支持的中斷已被破壞。 http://lkml.org/lkml/2010/5/3/363

這可能不是根本原因,但表示我不打算解決的問題。

1

我的2.6.26內核的副本ipic_set_irq_type()不會對enable()指針做任何事情。它,然而,有沒有在2.6.22以下意見:

/* ipic only supports low assertion and high-to-low change senses 
*/ 

/* ipic supports only edge mode on external interrupts */ 

看起來你對2.6.22在做什麼,不是由硬件支持。

+0

後者的聲明實際上是指內部中斷,而不是外部中斷(就像這個一樣)。我越來越接近造成它的根源,我認爲你在這裏很親密。謝謝! – Sam 2010-04-12 20:59:26

相關問題