upgrade to linux 2.6.10-1.12_FC2
[linux-2.6.git] / arch / arm / kernel / irq.c
index 9c65012..5b35e76 100644 (file)
@@ -86,7 +86,7 @@ static struct irqdesc bad_irq_desc = {
 };
 
 /**
- *     disable_irq - disable an irq and wait for completion
+ *     disable_irq_nosync - disable an irq without waiting
  *     @irq: Interrupt to disable
  *
  *     Disable the selected interrupt line.  Enables and disables
@@ -94,7 +94,7 @@ static struct irqdesc bad_irq_desc = {
  *
  *     This function may be called from IRQ context.
  */
-void disable_irq(unsigned int irq)
+void disable_irq_nosync(unsigned int irq)
 {
        struct irqdesc *desc = irq_desc + irq;
        unsigned long flags;
@@ -104,6 +104,28 @@ void disable_irq(unsigned int irq)
        list_del_init(&desc->pend);
        spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
+EXPORT_SYMBOL(disable_irq_nosync);
+
+/**
+ *     disable_irq - disable an irq and wait for completion
+ *     @irq: Interrupt to disable
+ *
+ *     Disable the selected interrupt line.  Enables and disables
+ *     are nested.  This functions 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(unsigned int irq)
+{
+       struct irqdesc *desc = irq_desc + irq;
+
+       disable_irq_nosync(irq);
+       if (desc->action)
+               synchronize_irq(irq);
+}
 EXPORT_SYMBOL(disable_irq);
 
 /**
@@ -175,17 +197,30 @@ EXPORT_SYMBOL(disable_irq_wake);
 
 int show_interrupts(struct seq_file *p, void *v)
 {
-       int i = *(loff_t *) v;
+       int i = *(loff_t *) v, cpu;
        struct irqaction * action;
        unsigned long flags;
 
+       if (i == 0) {
+               char cpuname[12];
+
+               seq_printf(p, "    ");
+               for_each_present_cpu(cpu) {
+                       sprintf(cpuname, "CPU%d", cpu);
+                       seq_printf(p, " %10s", cpuname);
+               }
+               seq_putc(p, '\n');
+       }
+
        if (i < NR_IRQS) {
                spin_lock_irqsave(&irq_controller_lock, flags);
                action = irq_desc[i].action;
                if (!action)
                        goto unlock;
 
-               seq_printf(p, "%3d: %10u ", i, kstat_irqs(i));
+               seq_printf(p, "%3d: ", i);
+               for_each_present_cpu(cpu)
+                       seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
                seq_printf(p, "  %s", action->name);
                for (action = action->next; action; action = action->next)
                        seq_printf(p, ", %s", action->name);
@@ -341,7 +376,6 @@ do_edge_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
 
        do {
                struct irqaction *action;
-               int ret;
 
                action = desc->action;
                if (!action)
@@ -352,9 +386,7 @@ do_edge_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
                        desc->chip->unmask(irq);
                }
 
-               ret = __do_irq(irq, action, regs);
-               if (ret != IRQ_HANDLED)
-                       report_bad_irq(irq, regs, desc, ret);
+               __do_irq(irq, action, regs);
        } while (desc->pending && !desc->disable_depth);
 
        desc->running = 0;