ARM: 6806/1: irq: introduce entry and exit functions for chained handlers
authorWill Deacon <will.deacon@arm.com>
Mon, 14 Mar 2011 13:00:30 +0000 (14:00 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 15 Mar 2011 09:42:28 +0000 (09:42 +0000)
Some chained IRQ handlers are written to cope with primary chips of
potentially different flow types. Whether this a sensible thing to do
is a point of contention.

This patch introduces entry/exit functions for chained handlers which
infer the flow type of the primary chip as fasteoi or level-type by
checking whether or not the ->irq_eoi function pointer is present and
calling back to the primary chip as necessary. Other methods of flow
control are not considered.

Acked-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/include/asm/mach/irq.h

index 22ac140edd9efb83ee2b770636d6ef32e7916f1e..febe495d0c6e15777b9e393a50cc08d7fbdd917c 100644 (file)
@@ -34,4 +34,35 @@ do {                                                 \
        raw_spin_unlock(&desc->lock);                   \
 } while(0)
 
+#ifndef __ASSEMBLY__
+/*
+ * Entry/exit functions for chained handlers where the primary IRQ chip
+ * may implement either fasteoi or level-trigger flow control.
+ */
+static inline void chained_irq_enter(struct irq_chip *chip,
+                                    struct irq_desc *desc)
+{
+       /* FastEOI controllers require no action on entry. */
+       if (chip->irq_eoi)
+               return;
+
+       if (chip->irq_mask_ack) {
+               chip->irq_mask_ack(&desc->irq_data);
+       } else {
+               chip->irq_mask(&desc->irq_data);
+               if (chip->irq_ack)
+                       chip->irq_ack(&desc->irq_data);
+       }
+}
+
+static inline void chained_irq_exit(struct irq_chip *chip,
+                                   struct irq_desc *desc)
+{
+       if (chip->irq_eoi)
+               chip->irq_eoi(&desc->irq_data);
+       else
+               chip->irq_unmask(&desc->irq_data);
+}
+#endif
+
 #endif