/* * handle_nested_irq - Handle a nested irq from a irq thread * @irq: the interrupt number * * Handle interrupts which are nested into a threaded interrupt * handler. The handler function is called inside the calling * threads context. */ void handle_nested_irq(unsigned int irq) { struct irq_desc *desc = irq_to_desc(irq); struct irqaction *action; irqreturn_t action_ret; might_sleep(); raw_spin_lock_irq(&desc->lock); kstat_incr_irqs_this_cpu(irq, desc); action = desc->action; if (unlikely(!action || (desc->istate & IRQS_DISABLED))) goto out_unlock; irq_compat_set_progress(desc); desc->istate |= IRQS_INPROGRESS; raw_spin_unlock_irq(&desc->lock); action_ret = action->thread_fn(action->irq, action->dev_id); if (!noirqdebug) note_interrupt(irq, desc, action_ret); raw_spin_lock_irq(&desc->lock); desc->istate &= ~IRQS_INPROGRESS; irq_compat_clr_progress(desc); out_unlock: raw_spin_unlock_irq(&desc->lock); }
irqreturn_t handle_irq_event(struct irq_desc *desc) { struct irqaction *action = desc->action; irqreturn_t ret; irq_compat_clr_pending(desc); desc->istate &= ~IRQS_PENDING; irq_compat_set_progress(desc); irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS); raw_spin_unlock(&desc->lock); ret = handle_irq_event_percpu(desc, action); raw_spin_lock(&desc->lock); irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS); irq_compat_clr_progress(desc); return ret; }