vserver 1.9.3
[linux-2.6.git] / arch / arm / kernel / irq.c
index dac499c..9c65012 100644 (file)
@@ -46,8 +46,9 @@
  */
 #define MAX_IRQ_CNT    100000
 
+static int noirqdebug;
 static volatile unsigned long irq_err_count;
-static spinlock_t irq_controller_lock;
+static spinlock_t irq_controller_lock = SPIN_LOCK_UNLOCKED;
 static LIST_HEAD(irq_pending);
 
 struct irqdesc irq_desc[NR_IRQS];
@@ -103,6 +104,7 @@ void disable_irq(unsigned int irq)
        list_del_init(&desc->pend);
        spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
+EXPORT_SYMBOL(disable_irq);
 
 /**
  *     enable_irq - enable interrupt handling on an irq
@@ -142,6 +144,7 @@ void enable_irq(unsigned int irq)
        }
        spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
+EXPORT_SYMBOL(enable_irq);
 
 /*
  * Enable wake on selected irq
@@ -156,6 +159,7 @@ void enable_irq_wake(unsigned int irq)
                desc->chip->wake(irq, 1);
        spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
+EXPORT_SYMBOL(enable_irq_wake);
 
 void disable_irq_wake(unsigned int irq)
 {
@@ -167,6 +171,7 @@ void disable_irq_wake(unsigned int irq)
                desc->chip->wake(irq, 0);
        spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
+EXPORT_SYMBOL(disable_irq_wake);
 
 int show_interrupts(struct seq_file *p, void *v)
 {
@@ -231,7 +236,7 @@ report_bad_irq(unsigned int irq, struct pt_regs *regs, struct irqdesc *desc, int
        static int count = 100;
        struct irqaction *action;
 
-       if (!count)
+       if (!count || noirqdebug)
                return;
 
        count--;
@@ -257,7 +262,7 @@ static int
 __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
 {
        unsigned int status;
-       int retval = 0;
+       int ret, retval = 0;
 
        spin_unlock(&irq_controller_lock);
 
@@ -266,8 +271,10 @@ __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
 
        status = 0;
        do {
-               status |= action->flags;
-               retval |= action->handler(irq, action->dev_id, regs);
+               ret = action->handler(irq, action->dev_id, regs);
+               if (ret == IRQ_HANDLED)
+                       status |= action->flags;
+               retval |= ret;
                action = action->next;
        } while (action);
 
@@ -443,7 +450,7 @@ static void do_pending_irqs(struct pt_regs *regs)
  * come via this function.  Instead, they should provide their
  * own 'handler'
  */
-asmlinkage void asm_do_IRQ(int irq, struct pt_regs *regs)
+asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
 {
        struct irqdesc *desc = irq_desc + irq;
 
@@ -541,6 +548,7 @@ int set_irq_type(unsigned int irq, unsigned int type)
 
        return ret;
 }
+EXPORT_SYMBOL(set_irq_type);
 
 void set_irq_flags(unsigned int irq, unsigned int iflags)
 {
@@ -669,7 +677,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_
 
        action->handler = handler;
        action->flags = irq_flags;
-       action->mask = 0;
+       cpus_clear(action->mask);
        action->name = devname;
        action->next = NULL;
        action->dev_id = dev_id;
@@ -798,6 +806,7 @@ unsigned int probe_irq_mask(unsigned long irqs)
 
        return mask;
 }
+EXPORT_SYMBOL(probe_irq_mask);
 
 /*
  * Possible return values:
@@ -855,3 +864,11 @@ void __init init_IRQ(void)
        init_arch_irq();
        init_dma();
 }
+
+static int __init noirqdebug_setup(char *str)
+{
+       noirqdebug = 1;
+       return 1;
+}
+
+__setup("noirqdebug", noirqdebug_setup);