irq: Remove unused debug_poll_all_shared_irqs()
[safe/jmp/linux-2.6] / kernel / irq / chip.c
index 7de11bd..ba566c2 100644 (file)
@@ -46,7 +46,10 @@ void dynamic_irq_init(unsigned int irq)
        desc->irq_count = 0;
        desc->irqs_unhandled = 0;
 #ifdef CONFIG_SMP
-       cpumask_setall(&desc->affinity);
+       cpumask_setall(desc->affinity);
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+       cpumask_clear(desc->pending_mask);
+#endif
 #endif
        spin_unlock_irqrestore(&desc->lock, flags);
 }
@@ -78,6 +81,7 @@ void dynamic_irq_cleanup(unsigned int irq)
        desc->handle_irq = handle_bad_irq;
        desc->chip = &no_irq_chip;
        desc->name = NULL;
+       clear_kstat_irqs(desc);
        spin_unlock_irqrestore(&desc->lock, flags);
 }
 
@@ -162,11 +166,11 @@ int set_irq_data(unsigned int irq, void *data)
 EXPORT_SYMBOL(set_irq_data);
 
 /**
- *     set_irq_data - set irq type data for an irq
+ *     set_irq_msi - set MSI descriptor data for an irq
  *     @irq:   Interrupt number
  *     @entry: Pointer to MSI descriptor data
  *
- *     Set the hardware irq controller data for an irq
+ *     Set the MSI descriptor entry for an irq
  */
 int set_irq_msi(unsigned int irq, struct msi_desc *entry)
 {
@@ -218,6 +222,34 @@ int set_irq_chip_data(unsigned int irq, void *data)
 }
 EXPORT_SYMBOL(set_irq_chip_data);
 
+/**
+ *     set_irq_nested_thread - Set/Reset the IRQ_NESTED_THREAD flag of an irq
+ *
+ *     @irq:   Interrupt number
+ *     @nest:  0 to clear / 1 to set the IRQ_NESTED_THREAD flag
+ *
+ *     The IRQ_NESTED_THREAD flag indicates that on
+ *     request_threaded_irq() no separate interrupt thread should be
+ *     created for the irq as the handler are called nested in the
+ *     context of a demultiplexing interrupt handler thread.
+ */
+void set_irq_nested_thread(unsigned int irq, int nest)
+{
+       struct irq_desc *desc = irq_to_desc(irq);
+       unsigned long flags;
+
+       if (!desc)
+               return;
+
+       spin_lock_irqsave(&desc->lock, flags);
+       if (nest)
+               desc->status |= IRQ_NESTED_THREAD;
+       else
+               desc->status &= ~IRQ_NESTED_THREAD;
+       spin_unlock_irqrestore(&desc->lock, flags);
+}
+EXPORT_SYMBOL_GPL(set_irq_nested_thread);
+
 /*
  * default enable function
  */
@@ -290,10 +322,50 @@ static inline void mask_ack_irq(struct irq_desc *desc, int irq)
                desc->chip->mask_ack(irq);
        else {
                desc->chip->mask(irq);
-               desc->chip->ack(irq);
+               if (desc->chip->ack)
+                       desc->chip->ack(irq);
        }
 }
 
+/*
+ *     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();
+
+       spin_lock_irq(&desc->lock);
+
+       kstat_incr_irqs_this_cpu(irq, desc);
+
+       action = desc->action;
+       if (unlikely(!action || (desc->status & IRQ_DISABLED)))
+               goto out_unlock;
+
+       desc->status |= IRQ_INPROGRESS;
+       spin_unlock_irq(&desc->lock);
+
+       action_ret = action->thread_fn(action->irq, action->dev_id);
+       if (!noirqdebug)
+               note_interrupt(irq, desc, action_ret);
+
+       spin_lock_irq(&desc->lock);
+       desc->status &= ~IRQ_INPROGRESS;
+
+out_unlock:
+       spin_unlock_irq(&desc->lock);
+}
+EXPORT_SYMBOL_GPL(handle_nested_irq);
+
 /**
  *     handle_simple_irq - Simple and software-decoded IRQs.
  *     @irq:   the interrupt number
@@ -354,7 +426,6 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
 
        spin_lock(&desc->lock);
        mask_ack_irq(desc, irq);
-       desc = irq_remap_to_desc(irq, desc);
 
        if (unlikely(desc->status & IRQ_INPROGRESS))
                goto out_unlock;
@@ -378,7 +449,10 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
 
        spin_lock(&desc->lock);
        desc->status &= ~IRQ_INPROGRESS;
-       if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
+
+       if (unlikely(desc->status & IRQ_ONESHOT))
+               desc->status |= IRQ_MASKED;
+       else if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
                desc->chip->unmask(irq);
 out_unlock:
        spin_unlock(&desc->lock);
@@ -433,7 +507,6 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
        desc->status &= ~IRQ_INPROGRESS;
 out:
        desc->chip->eoi(irq);
-       desc = irq_remap_to_desc(irq, desc);
 
        spin_unlock(&desc->lock);
 }
@@ -470,14 +543,13 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
                    !desc->action)) {
                desc->status |= (IRQ_PENDING | IRQ_MASKED);
                mask_ack_irq(desc, irq);
-               desc = irq_remap_to_desc(irq, desc);
                goto out_unlock;
        }
        kstat_incr_irqs_this_cpu(irq, desc);
 
        /* Start handling the irq */
-       desc->chip->ack(irq);
-       desc = irq_remap_to_desc(irq, desc);
+       if (desc->chip->ack)
+               desc->chip->ack(irq);
 
        /* Mark the IRQ currently in progress.*/
        desc->status |= IRQ_INPROGRESS;
@@ -518,7 +590,7 @@ out_unlock:
 }
 
 /**
- *     handle_percpu_IRQ - Per CPU local irq handler
+ *     handle_percpu_irq - Per CPU local irq handler
  *     @irq:   the interrupt number
  *     @desc:  the interrupt description structure for this irq
  *
@@ -538,10 +610,8 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc)
        if (!noirqdebug)
                note_interrupt(irq, desc, action_ret);
 
-       if (desc->chip->eoi) {
+       if (desc->chip->eoi)
                desc->chip->eoi(irq);
-               desc = irq_remap_to_desc(irq, desc);
-       }
 }
 
 void
@@ -572,14 +642,13 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
                desc->chip = &dummy_irq_chip;
        }
 
+       chip_bus_lock(irq, desc);
        spin_lock_irqsave(&desc->lock, flags);
 
        /* Uninstall? */
        if (handle == handle_bad_irq) {
-               if (desc->chip != &no_irq_chip) {
+               if (desc->chip != &no_irq_chip)
                        mask_ack_irq(desc, irq);
-                       desc = irq_remap_to_desc(irq, desc);
-               }
                desc->status |= IRQ_DISABLED;
                desc->depth = 1;
        }
@@ -593,6 +662,7 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
                desc->chip->startup(irq);
        }
        spin_unlock_irqrestore(&desc->lock, flags);
+       chip_bus_sync_unlock(irq, desc);
 }
 EXPORT_SYMBOL_GPL(__set_irq_handler);