Estoy implementando un módulo de manejo de interrupciones usando el hilo irq. Estoy enfrentando este error:
1983.150961] Shut down eMMC app module init. [ 1983.151115] genirq: Flags mismatch irq 49. 00000004 (eMMC_power_shutdown_irq_ handler) vs. 00000004 (xuartps) fio@uz3cg-dgw:~$ (edited)Estoy eligiendo un indicador #define IRQF_TRIGGER_HIGH 0x00000004 y lo asigno a IRQ número 49 en este caso.
Aquí está mi código:
static int __init shutdownemmc_module_init(void) { printk("Shut down eMMC app module init. "); if (request_threaded_irq( IRQ_NO, //IRQ number (void *) emmc_irq_handler, //IRQ handler (Top half) emmc_interrupt_thread_fn, //IRQ Thread handler (Bottom half).When the handler function returns IRQ_WAKE_THREAD IRQF_TRIGGER_HIGH, //Handler will be called in raising edge "eMMC_power_shutdown_irq_handler", //used to identify the device name using this IRQ (void *)(emmc_irq_handler))) //device id for shared IRQ { pr_err("Cannot register IRQ "); pr_err(" EIO %d , EINVAL %d\n", EIO, EINVAL); return 0; } pr_info("Interrupt handler...Done!!!\n"); return 0; }¿Alguien podría explicar qué es el problema de irq de discrepancia de banderas y cómo puedo solucionar este problema? Gracias, Anh
Es porque "xuartps" ya solicitó el número de IRQ y no solicitó que se comparta.
Extractos de __setup_irq() en "kernel/irq/manage.c":
/* * If nobody did set the configuration before, inherit * the one provided by the requester. */ if (irqd_trigger_type_was_set(&desc->irq_data)) { oldtype = irqd_get_trigger_type(&desc->irq_data); } else { oldtype = new->flags & IRQF_TRIGGER_MASK; irqd_set_trigger_type(&desc->irq_data, oldtype); } if (!((old->flags & new->flags) & IRQF_SHARED) || (oldtype != (new->flags & IRQF_TRIGGER_MASK)) || ((old->flags ^ new->flags) & IRQF_ONESHOT)) goto mismatch; En lo anterior, old es el controlador existente configurado por "xuartps". new es el nuevo controlador que está configurando su código. Para que se comparta la IRQ, una de las condiciones anteriores es que tanto el controlador antiguo como el nuevo deben solicitar la IRQ con el indicador IRQF_SHARED . Sin embargo, los controladores solo deben configurar IRQF_SHARED si se supone que la interrupción subyacente se puede compartir; por ejemplo: todas las interrupciones PCI se pueden compartir y los controladores para dispositivos PCI deben solicitar interrupciones con el conjunto IRQF_SHARED .
mismatch: if (!(new->flags & IRQF_PROBE_SHARED)) { pr_err("Flags mismatch irq %d. %08x (%s) vs. %08x (%s)\n", irq, new->flags, new->name, old->flags, old->name); #ifdef CONFIG_DEBUG_SHIRQ dump_stack(); #endif } ret = -EBUSY;Lo anterior es donde el mensaje "Banderas no coinciden" se imprime en el registro del kernel.
Si no esperaba que ya se solicitara la IRQ, compruebe que está solicitando la IRQ correcta.