Обработчик прерывания: request_irq возвращает код ошибки -16

Я пишу простой драйвер, который мог бы регистрировать прерывание и обрабатывать его. Я использую функцию request_irq, но она возвращает эту ошибку:

genirq: Flags mismatch irq 29. 00004004 (irq-test) vs. 00000004 (e000d000.spi)
- code -16 , EIO 5 , EINVAL 22

Это простой код модуля:

#define IRQ_Number 29

static irqreturn_t irq_handler( int irq, void *dev_id )
{
    static int mycount = 0;


printk("Interrupt! = %d\n", mycount);
    mycount++;

return IRQ_HANDLED;

}
static int __init my_init(void)
{
unsigned int irq;

int ret;

irq = IRQ_Number;   

ret = request_irq(irq, irq_handler , IRQF_NO_SUSPEND; , "irq-test", NULL);

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

}
static void __exit my_exit(void)
{

    unsigned int irq;
    irq=IRQ_Number;
    free_irq(irq, NULL);

    printk(KERN_INFO "my module: ----> exit\n" );

}

И это вывод из cat /proc/interrupts:

           CPU0       CPU1       
 16:          1          0     GIC-0  27 Edge      gt
 17:          0          0     GIC-0  43 Level     ttc_clockevent
 18:  140949401 1430637760     GIC-0  29 Edge      twd
 19:          0          0     GIC-0  37 Level     arm-pmu
 20:          0          0     GIC-0  38 Level     arm-pmu
 21:         43          0     GIC-0  39 Level     f8007100.adc
 23:          7          0     GIC-0  57 Level     cdns-i2c
 25:          0          0     GIC-0  35 Level     f800c000.ocmc
 26:        332          0     GIC-0  59 Level     xuartps
 27:   14833917          0     GIC-0  58 Level     e0006000.spi
 28:          2          0     GIC-0  81 Level     e0007000.spi
 29:          0          0     GIC-0  51 Level     e000d000.spi
 30:    3654689          0     GIC-0  54 Level     eth0
 31:        637          0     GIC-0  56 Level     mmc0
 32:          0          0     GIC-0  45 Level     f8003000.dmac
 33:          0          0     GIC-0  46 Level     f8003000.dmac
 34:          0          0     GIC-0  47 Level     f8003000.dmac
 35:          0          0     GIC-0  48 Level     f8003000.dmac
 36:          0          0     GIC-0  49 Level     f8003000.dmac
 37:          0          0     GIC-0  72 Level     f8003000.dmac
 38:          0          0     GIC-0  73 Level     f8003000.dmac
 39:          0          0     GIC-0  74 Level     f8003000.dmac
 40:          0          0     GIC-0  75 Level     f8003000.dmac
 41:          0          0     GIC-0  40 Level     f8007000.devcfg
 48:          0          0     GIC-0  41 Edge      f8005000.watchdog
IPI1:          0          0  Timer broadcast interrupts
IPI2:     371883   12507844  Rescheduling interrupts
IPI3:          4          1  Function call interrupts
IPI4:          0          0  CPU stop interrupts
IPI5:    2632663   10068764  IRQ work interrupts
IPI6:          0          0  completion interrupts

Я попытался изменить флаги на 0 и IRQF_SHARED, но получил ту же ошибку!


person Ahmed lazibi    schedule 27.04.2020    source источник


Ответы (1)


Возвращаемое значение -16 означает ошибку 16, то есть EBUSY, также известную как «устройство или ресурс занят». Вы пытаетесь запросить IRQ 29, и вы ясно видите, что IRQ 29 уже зарегистрирован e000d000.spi. Это означает, что тот, кто написал код для этого драйвера, решил не использовать IRQF_SHARED, и поэтому вы не можете запросить его, даже если укажете этот флаг. Используйте другой номер, чтобы запросить другую линию прерывания, или избегайте загрузки драйвера, который получает исключительный контроль над этой линией.

Кроме того, я не уверен, почему вы также печатаете два значения EIO и EINVAL, но это просто номера ошибок без какого-либо контекста, а не то, что возвращается функцией.

person Marco Bonelli    schedule 28.04.2020