/** * handle_IRQ_event - irq action chain handler * @irq: the interrupt number * @action: the interrupt action chain for this irq * * Handles the action chain of an irq event */ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action) { irqreturn_t ret, retval = IRQ_NONE; unsigned int status = 0; #ifdef __i386__ if (debug_direct_keyboard && irq == 1) lockdep_off(); #endif handle_dynamic_tick(action); /* * Unconditionally enable interrupts for threaded * IRQ handlers: */ if (!hardirq_count() || !(action->flags & IRQF_DISABLED)) local_irq_enable(); do { unsigned int preempt_count = preempt_count(); ret = action->handler(irq, action->dev_id); if (preempt_count() != preempt_count) { stop_trace(); print_symbol("BUG: unbalanced irq-handler preempt count in %s!\n", (unsigned long) action->handler); printk("entered with %08x, exited with %08x.\n", preempt_count, preempt_count()); dump_stack(); preempt_count() = preempt_count; } if (ret == IRQ_HANDLED) status |= action->flags; retval |= ret; action = action->next; } while (action); if (status & IRQF_SAMPLE_RANDOM) { local_irq_enable(); add_interrupt_randomness(irq); } local_irq_disable(); #ifdef __i386__ if (debug_direct_keyboard && irq == 1) lockdep_on(); #endif return retval; }
/** * handle_IRQ_event - irq action chain handler * @irq: the interrupt number * @regs: pointer to a register structure * @action: the interrupt action chain for this irq * * Handles the action chain of an irq event */ irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs, struct irqaction *action) { irqreturn_t ret, retval = IRQ_NONE; unsigned int status = 0; MARK(kernel_irq_entry, "%u %u", irq, (regs)?(!user_mode(regs)):(1)); handle_dynamic_tick(action); /* * Unconditionally enable interrupts for threaded * IRQ handlers: */ if (!hardirq_count() || !(action->flags & IRQF_DISABLED)) local_irq_enable(); do { unsigned int preempt_count = preempt_count(); ret = action->handler(irq, action->dev_id, regs); if (preempt_count() != preempt_count) { stop_trace(); print_symbol("BUG: unbalanced irq-handler preempt count in %s!\n", (unsigned long) action->handler); printk("entered with %08x, exited with %08x.\n", preempt_count, preempt_count()); dump_stack(); preempt_count() = preempt_count; } if (ret == IRQ_HANDLED) status |= action->flags; retval |= ret; action = action->next; } while (action); if (status & IRQF_SAMPLE_RANDOM) { local_irq_enable(); add_interrupt_randomness(irq); } local_irq_disable(); MARK(kernel_irq_exit, MARK_NOARGS); return retval; }
/** * handle_IRQ_event - irq action chain handler * @irq: the interrupt number * @action: the interrupt action chain for this irq * * Handles the action chain of an irq event */ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action) { irqreturn_t ret, retval = IRQ_NONE; unsigned int status = 0; handle_dynamic_tick(action); if (!(action->flags & IRQF_DISABLED)) local_irq_enable_in_hardirq(); do { ret = action->handler(irq, action->dev_id); if (ret == IRQ_HANDLED) status |= action->flags; retval |= ret; action = action->next; } while (action); if (status & IRQF_SAMPLE_RANDOM) add_interrupt_randomness(irq); local_irq_disable(); return retval; }