Почему я не могу зарегистрировать прерывания, инициируемые по фронту, в Linux 2.6.26? - PullRequest
2 голосов
/ 12 апреля 2010

Первый постер, поэтому прошу прощения за любую глупость.

Я работаю над переносом пользовательского драйвера CPLD для ядра Linux, созданного для MPC83xx с 2.6.22 до 2.6.26, и получаю неожиданное упс. Драйвер прекрасно работает для ядра .22, но ядро ​​.26 заглушает мой вызов request_irq. Кто-нибудь знает, почему произошли изменения в поведении или, что еще лучше, что мне нужно сделать, чтобы решить эту проблему?

Я отследил источник Oops до вызова kernel / irq / manage.c, где setup_irq() вызывается desc->chip->enable(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");

Спасибо за помощь. Я бьюсь над этим уже несколько дней, и я открыт для любых предложений.

Ответы [ 2 ]

1 голос
/ 04 мая 2010

Ааа. Похоже, JayM был близок, хотя и не по той причине, о которой он думал. Я только что видел, как патч прошёл по списку рассылки linuxppc-dev, сообщая, что прерывания, поддерживаемые ребром, были прерваны. http://lkml.org/lkml/2010/5/3/363

Возможно, это не основная причина, но указывает на проблему, которую я не собираюсь исправлять.

1 голос
/ 12 апреля 2010

Моя копия ядра ipic_set_irq_type() ядра 2.6.26 ничего не делает с указателем 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, не поддерживалось оборудованием.

...