/** * disable_irq_nosync - disable an irq without waiting * @irq: Interrupt to disable * * Disable the selected interrupt line. Disablesand Enables are * nested. * Unlike disable_irq(),this function doesnot 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)); }