Обработчик прерываний: request_irq возвращает код ошибки -16 - PullRequest
0 голосов
/ 27 апреля 2020

Я пишу простой драйвер, который может зарегистрировать прерывание и обработать его. Я использую функцию 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, но получил ту же ошибку!

1 Ответ

1 голос
/ 29 апреля 2020

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

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

...