Как получить прерывание GPIO от IOexpander в Linux

Я разрабатываю модуль ядра для встроенного устройства. Ядром устройства является Toradex iMX6DL.

Итак, у меня есть IO-Expander серии mcp23xxx на этом устройстве, и я могу работать с его GPIO. Я могу установить их как ввод/вывод и получить/установить их значения.

Мне нужно использовать один из них как прерывание, это часть моего кода для установки прерывания:

static irqreturn_t r_irq_handler(unsigned int irq, void *dev_id, struct pt_regs *regs)
 {
    printk(KERN_DEBUG "interrupt received (irq: %d)\n", irq);
    //do some stuff here
    return IRQ_HANDLED;
}


...

     if(gpio_request(497, 0)==0)
     {
         int result;             
         gpio_direction_input(497);
         gpio_set_debounce(497, 100);
         gpio_export(497,false);
         irqNumber =gpio_to_irq(497);        // map your GPIO to an IRQ
         printk("irq number : %d\r\n",irqNumber);
         result = request_irq(irqNumber,           // requested interrupt
                    (irq_handler_t) r_irq_handler, // pointer to handler function
                    IRQF_TRIGGER_RISING, // interrupt mode flag
                    "irqHandler",        // used in /proc/interrupts
                    NULL);               // the *dev_id shared interrupt lines, NULL is okay

         printk("irq request for pin %d result:%d  \r\n",497,result);
         if(result == SUCCESS)
            printk("irq request for pin %d succeeds\r\n",497);
     }

Результатом gpio_to_irq() является «-6», а результатом request_irq() является «-22». Что мне делать, чтобы получить прерывание этого GPIO?


person Ahmad Afkandeh    schedule 11.05.2020    source источник
comment
Откуда у тебя это 497?   -  person Marco Bonelli    schedule 11.05.2020
comment
@MarcoBonelli, вам, вероятно, нужно немного прочитать документацию о том, как в ядре Linux распределяются числа для контроллеров GPIO. Кроме того, этот ответ может помочь: stackoverflow.com/q/55532410/2511795   -  person 0andriy    schedule 11.05.2020
comment
@ 0andriy Мне обязательно нужно, я мало что знаю о GPIO. Мне просто интересно, использует ли OP правильное значение.   -  person Marco Bonelli    schedule 11.05.2020
comment
Вам нужно добавить проверку ошибок ко всем сделанным вами звонкам. Кроме того, для чего это gpio_export()?   -  person 0andriy    schedule 11.05.2020
comment
@MarcoBonelli (у меня есть унифицированные комментарии, чтобы избежать загрязнения): для меня это довольно разумно (512 - 16 + 1), поскольку GPIO 0 из 16 на этом расширителе. ОБНОВЛЕНИЕ: извините, я немного просчитался, ошибка на единицу, вы знаете, так что, похоже, GPIO 1.   -  person 0andriy    schedule 11.05.2020
comment
Основная проблема здесь в том, что вы пытаетесь использовать gpio_to_irq и gpios. Что вам нужно сделать, так это правильно использовать дерево устройств для вашего устройства и сделать так, чтобы свойство прерываний вашего узла указывало на mcp23xxx в качестве контроллера прерываний, а не на контроллер gpio. Затем вы можете просто использовать platform_get_irq(), чтобы получить номер прерывания.   -  person Alexandre Belloni    schedule 12.05.2020
comment
@MarcoBonelli, номер gpio правильный, в sys/class/gpio вы можете найти gpiochips и начальный номер этих чипов, мой — gpiochip496.   -  person Ahmad Afkandeh    schedule 12.05.2020
comment
@ 0andriy Я экспортировал этот пин-код только для теста, я хотел получить его значение, потому что я не получил прерывания. Извините, что включил это в мой код, это было просто для проверки моей схемы.   -  person Ahmad Afkandeh    schedule 12.05.2020
comment
@AlexandreBelloni Спасибо, я прочитаю о платформе_get_irq() и сообщу вам результат.   -  person Ahmad Afkandeh    schedule 12.05.2020