/** * disable_irq_nosync - disable an irq without waiting * @irq: Interrupt to disable * * Disable the selected interrupt line. Disables and Enables are * nested. * Unlike disable_irq(),this function does not ensure existing * instances of the IRQ handler have completed before returning. * *This function may be called from IRQ context. */ void disable_irq_nosync(unsigned int irq) { struct irq_desc *desc = irq_to_desc(irq); unsigned long flags;
/** * disable_irq - disable an irq and wait for completion * @irq: Interrupt to disable * * Disable the selected interrupt line. Enables and Disables are * nested. * This function waits for any pending IRQ handlers for this interrupt * to complete before returning. If you use this function while * holding a resource the IRQ handler may need you will deadlock. * * This function may be called - with care - from IRQ context. */ void disable_irq(unsignedint irq) { struct irq_desc *desc = irq_desc + irq; if(irq >= NR_IRQS) return; disable_irq_nosync(irq); if(desc->action) synchronize_irq(irq); }
/** * synchronize_irq - wait for pending IRQ handlers (on other CPUs) * @irq: interrupt number to wait for * * This function waits for any pending IRQ handlers for this interrupt * to complete before returning. If you use this function while * holding a resource the IRQ handler may need you will deadlock. * * This function may be called - with care - from IRQ context. */ void synchronize_irq(unsignedint irq) { struct irq_desc *desc = irq_to_desc(irq); unsignedint status; if(!desc) return; do{ unsignedlong flags; /* * Wait until we're out of the critical section. This might * give the wrong answer due to the lack of memory barriers. */ while(desc->status & IRQ_INPROGRESS) cpu_relax(); /* Ok, that indicated we're done: double-check carefully. */ spin_lock_irqsave(&desc->lock, flags); status = desc->status; spin_unlock_irqrestore(&desc->lock, flags); /* Oops, that failed? */ }while(status & IRQ_INPROGRESS); /* * We made sure that no hardirq handler is running. Now verify * that no threaded handlers are active. */ wait_event(desc->wait_for_threads,!atomic_read(&desc->threads_active)); }