]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - kernel/irq/handle.c
Merge ssh://git.infradead.org/~/public_git/hdroneline
[linux-2.6-omap-h63xx.git] / kernel / irq / handle.c
index 3a2dbcc9e215d21e8423180c57fd8e172f1735b9..48a53f68af96452dd77ef113cb6b8ec1ce915276 100644 (file)
 
 /**
  * handle_bad_irq - handle spurious and unhandled irqs
+ * @irq:       the interrupt number
+ * @desc:      description of the interrupt
+ * @regs:      pointer to a register structure
+ *
+ * Handles spurious and unhandled IRQ's. It also prints a debugmessage.
  */
 void fastcall
 handle_bad_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
 {
+       print_irq_desc(irq, desc);
        kstat_this_cpu.irqs[irq]++;
        ack_bad_irq(irq);
 }
@@ -45,7 +51,7 @@ handle_bad_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
 struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned = {
        [0 ... NR_IRQS-1] = {
                .status = IRQ_DISABLED,
-               .chip = &no_irq_type,
+               .chip = &no_irq_chip,
                .handle_irq = handle_bad_irq,
                .depth = 1,
                .lock = SPIN_LOCK_UNLOCKED,
@@ -61,6 +67,7 @@ struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned = {
  */
 static void ack_bad(unsigned int irq)
 {
+       print_irq_desc(irq, irq_desc + irq);
        ack_bad_irq(irq);
 }
 
@@ -79,8 +86,8 @@ static unsigned int noop_ret(unsigned int irq)
 /*
  * Generic no controller implementation
  */
-struct hw_interrupt_type no_irq_type = {
-       .typename       = "none",
+struct irq_chip no_irq_chip = {
+       .name           = "none",
        .startup        = noop_ret,
        .shutdown       = noop,
        .enable         = noop,
@@ -89,6 +96,22 @@ struct hw_interrupt_type no_irq_type = {
        .end            = noop,
 };
 
+/*
+ * Generic dummy implementation which can be used for
+ * real dumb interrupt sources
+ */
+struct irq_chip dummy_irq_chip = {
+       .name           = "dummy",
+       .startup        = noop_ret,
+       .shutdown       = noop,
+       .enable         = noop,
+       .disable        = noop,
+       .ack            = noop,
+       .mask           = noop,
+       .unmask         = noop,
+       .end            = noop,
+};
+
 /*
  * Special, empty irq handler:
  */
@@ -111,8 +134,10 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
        irqreturn_t ret, retval = IRQ_NONE;
        unsigned int status = 0;
 
-       if (!(action->flags & SA_INTERRUPT))
-               local_irq_enable();
+       handle_dynamic_tick(action);
+
+       if (!(action->flags & IRQF_DISABLED))
+               local_irq_enable_in_hardirq();
 
        do {
                ret = action->handler(irq, action->dev_id, regs);
@@ -122,7 +147,7 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
                action = action->next;
        } while (action);
 
-       if (status & SA_SAMPLE_RANDOM)
+       if (status & IRQF_SAMPLE_RANDOM)
                add_interrupt_randomness(irq);
        local_irq_disable();
 
@@ -229,3 +254,19 @@ out:
        return 1;
 }
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+
+/*
+ * lockdep: we want to handle all irq_desc locks as a single lock-class:
+ */
+static struct lock_class_key irq_desc_lock_class;
+
+void early_init_irq_lock_class(void)
+{
+       int i;
+
+       for (i = 0; i < NR_IRQS; i++)
+               lockdep_set_class(&irq_desc[i].lock, &irq_desc_lock_class);
+}
+
+#endif