IRQ: Typedef the IRQ flow handler function type
[powerpc.git] / kernel / irq / chip.c
index 54105bd..53e9dce 100644 (file)
 
 #include "internals.h"
 
+/**
+ *     dynamic_irq_init - initialize a dynamically allocated irq
+ *     @irq:   irq number to initialize
+ */
+void dynamic_irq_init(unsigned int irq)
+{
+       struct irq_desc *desc;
+       unsigned long flags;
+
+       if (irq >= NR_IRQS) {
+               printk(KERN_ERR "Trying to initialize invalid IRQ%d\n", irq);
+               WARN_ON(1);
+               return;
+       }
+
+       /* Ensure we don't have left over values from a previous use of this irq */
+       desc = irq_desc + irq;
+       spin_lock_irqsave(&desc->lock, flags);
+       desc->status = IRQ_DISABLED;
+       desc->chip = &no_irq_chip;
+       desc->handle_irq = handle_bad_irq;
+       desc->depth = 1;
+       desc->handler_data = NULL;
+       desc->chip_data = NULL;
+       desc->action = NULL;
+       desc->irq_count = 0;
+       desc->irqs_unhandled = 0;
+#ifdef CONFIG_SMP
+       desc->affinity = CPU_MASK_ALL;
+#endif
+       spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/**
+ *     dynamic_irq_cleanup - cleanup a dynamically allocated irq
+ *     @irq:   irq number to initialize
+ */
+void dynamic_irq_cleanup(unsigned int irq)
+{
+       struct irq_desc *desc;
+       unsigned long flags;
+
+       if (irq >= NR_IRQS) {
+               printk(KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq);
+               WARN_ON(1);
+               return;
+       }
+
+       desc = irq_desc + irq;
+       spin_lock_irqsave(&desc->lock, flags);
+       if (desc->action) {
+               spin_unlock_irqrestore(&desc->lock, flags);
+               printk(KERN_ERR "Destroying IRQ%d without calling free_irq\n",
+                       irq);
+               WARN_ON(1);
+               return;
+       }
+       desc->handle_irq = handle_bad_irq;
+       desc->chip = &no_irq_chip;
+       spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+
 /**
  *     set_irq_chip - set the irq chip for an irq
  *     @irq:   irq number
@@ -40,10 +103,6 @@ int set_irq_chip(unsigned int irq, struct irq_chip *chip)
        spin_lock_irqsave(&desc->lock, flags);
        irq_chip_set_defaults(chip);
        desc->chip = chip;
-       /*
-        * For compatibility only:
-        */
-       desc->chip = chip;
        spin_unlock_irqrestore(&desc->lock, flags);
 
        return 0;
@@ -146,7 +205,7 @@ static void default_disable(unsigned int irq)
        struct irq_desc *desc = irq_desc + irq;
 
        if (!(desc->status & IRQ_DELAYED_DISABLE))
-               irq_desc[irq].chip->mask(irq);
+               desc->chip->mask(irq);
 }
 
 /*
@@ -252,7 +311,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
        mask_ack_irq(desc, irq);
 
        if (unlikely(desc->status & IRQ_INPROGRESS))
-               goto out;
+               goto out_unlock;
        desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
        kstat_cpu(cpu).irqs[irq]++;
 
@@ -261,10 +320,13 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
         * keep it masked and get out of here
         */
        action = desc->action;
-       if (unlikely(!action || (desc->status & IRQ_DISABLED)))
-               goto out;
+       if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
+               desc->status |= IRQ_PENDING;
+               goto out_unlock;
+       }
 
        desc->status |= IRQ_INPROGRESS;
+       desc->status &= ~IRQ_PENDING;
        spin_unlock(&desc->lock);
 
        action_ret = handle_IRQ_event(irq, regs, action);
@@ -273,9 +335,9 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
 
        spin_lock(&desc->lock);
        desc->status &= ~IRQ_INPROGRESS;
-out:
        if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
                desc->chip->unmask(irq);
+out_unlock:
        spin_unlock(&desc->lock);
 }
 
@@ -443,10 +505,7 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
 #endif /* CONFIG_SMP */
 
 void
-__set_irq_handler(unsigned int irq,
-                 void fastcall (*handle)(unsigned int, irq_desc_t *,
-                                         struct pt_regs *),
-                 int is_chained)
+__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained)
 {
        struct irq_desc *desc;
        unsigned long flags;
@@ -499,9 +558,7 @@ __set_irq_handler(unsigned int irq,
 
 void
 set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip,
-                        void fastcall (*handle)(unsigned int,
-                                                struct irq_desc *,
-                                                struct pt_regs *))
+                        irq_flow_handler_t handle)
 {
        set_irq_chip(irq, chip);
        __set_irq_handler(irq, handle, 0);
@@ -512,8 +569,7 @@ set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip,
  * /proc/interrupts output:
  */
 const char *
-handle_irq_name(void fastcall (*handle)(unsigned int, struct irq_desc *,
-                                       struct pt_regs *))
+handle_irq_name(irq_flow_handler_t handle)
 {
        if (handle == handle_level_irq)
                return "level  ";