[ARM] pxa: integrate low IRQ chip (ICIP) and high IRQ chip (ICIP2) into one
authoreric miao <eric.miao@marvell.com>
Tue, 4 Mar 2008 05:53:05 +0000 (13:53 +0800)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 19 Apr 2008 10:29:04 +0000 (11:29 +0100)
This makes the code better organized and simplified a bit.  The change
will lose a bit of performance when performing IRQ ack/mask/unmask,but
that's not too much after checking the result binary.

This patch also removes the ugly #ifdef CONFIG_PXA27x .. #endif by
carefully not to access those pxa{27x,3xx} specific registers, this
is done by keeping an internal IRQ number variable.  The pxa-regs.h
is also modified so registers for IRQ > PXA_IRQ(31) are made public
even if CONFIG_PXA{27x,3xx} isn't defined (for pxa25x's sake)

The incorrect assumption in the original code that internal irq starts
from 0 is also corrected by comparing with PXA_IRQ(0).

"struct sys_device" for the IRQ are reduced into one single device on
pxa{27x,3xx}.

Signed-off-by: eric miao <eric.miao@marvell.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/mach-pxa/generic.h
arch/arm/mach-pxa/irq.c
arch/arm/mach-pxa/pxa25x.c
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-pxa/pxa3xx.c
include/asm-arm/arch-pxa/pxa-regs.h

index cbe6693..0e3e058 100644 (file)
@@ -12,8 +12,7 @@
 struct sys_timer;
 
 extern struct sys_timer pxa_timer;
-extern void __init pxa_init_irq_low(void);
-extern void __init pxa_init_irq_high(void);
+extern void __init pxa_init_irq(int irq_nr);
 extern void __init pxa_init_irq_gpio(int gpio_nr);
 extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int));
 extern void __init pxa_init_gpio_set_wake(int (*set_wake)(unsigned int, unsigned int));
index da3a44a..cccc3ed 100644 (file)
 
 #include "generic.h"
 
+#define IRQ_BIT(n)     (((n) - PXA_IRQ(0)) & 0x1f)
+#define _ICMR(n)       (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICMR2 : &ICMR))
+#define _ICLR(n)       (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICLR2 : &ICLR))
 
 /*
  * This is for peripheral IRQs internal to the PXA chip.
  */
 
-static void pxa_mask_low_irq(unsigned int irq)
+static int pxa_internal_irq_nr;
+
+static void pxa_mask_irq(unsigned int irq)
 {
-       ICMR &= ~(1 << irq);
+       _ICMR(irq) &= ~(1 << IRQ_BIT(irq));
 }
 
-static void pxa_unmask_low_irq(unsigned int irq)
+static void pxa_unmask_irq(unsigned int irq)
 {
-       ICMR |= (1 << irq);
+       _ICMR(irq) |= 1 << IRQ_BIT(irq);
 }
 
-static struct irq_chip pxa_internal_chip_low = {
+static struct irq_chip pxa_internal_irq_chip = {
        .name           = "SC",
-       .ack            = pxa_mask_low_irq,
-       .mask           = pxa_mask_low_irq,
-       .unmask         = pxa_unmask_low_irq,
+       .ack            = pxa_mask_irq,
+       .mask           = pxa_mask_irq,
+       .unmask         = pxa_unmask_irq,
 };
 
-void __init pxa_init_irq_low(void)
+void __init pxa_init_irq(int irq_nr)
 {
        int irq;
 
-       /* disable all IRQs */
-       ICMR = 0;
+       pxa_internal_irq_nr = irq_nr;
 
-       /* all IRQs are IRQ, not FIQ */
-       ICLR = 0;
+       for (irq = 0; irq < irq_nr; irq += 32) {
+               _ICMR(irq) = 0; /* disable all IRQs */
+               _ICLR(irq) = 0; /* all IRQs are IRQ, not FIQ */
+       }
 
        /* only unmasked interrupts kick us out of idle */
        ICCR = 1;
 
-       for (irq = PXA_IRQ(0); irq <= PXA_IRQ(31); irq++) {
-               set_irq_chip(irq, &pxa_internal_chip_low);
-               set_irq_handler(irq, handle_level_irq);
-               set_irq_flags(irq, IRQF_VALID);
-       }
-}
-
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
-
-/*
- * This is for the second set of internal IRQs as found on the PXA27x.
- */
-
-static void pxa_mask_high_irq(unsigned int irq)
-{
-       ICMR2 &= ~(1 << (irq - 32));
-}
-
-static void pxa_unmask_high_irq(unsigned int irq)
-{
-       ICMR2 |= (1 << (irq - 32));
-}
-
-static struct irq_chip pxa_internal_chip_high = {
-       .name           = "SC-hi",
-       .ack            = pxa_mask_high_irq,
-       .mask           = pxa_mask_high_irq,
-       .unmask         = pxa_unmask_high_irq,
-};
-
-void __init pxa_init_irq_high(void)
-{
-       int irq;
-
-       ICMR2 = 0;
-       ICLR2 = 0;
-
-       for (irq = PXA_IRQ(32); irq < PXA_IRQ(64); irq++) {
-               set_irq_chip(irq, &pxa_internal_chip_high);
+       for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq++) {
+               set_irq_chip(irq, &pxa_internal_irq_chip);
                set_irq_handler(irq, handle_level_irq);
                set_irq_flags(irq, IRQF_VALID);
        }
 }
-#endif
 
 void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int))
 {
-       pxa_internal_chip_low.set_wake = set_wake;
-#ifdef CONFIG_PXA27x
-       pxa_internal_chip_high.set_wake = set_wake;
-#endif
+       pxa_internal_irq_chip.set_wake = set_wake;
        pxa_init_gpio_set_wake(set_wake);
 }
 
@@ -118,19 +83,11 @@ static unsigned long saved_icmr[2];
 
 static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
 {
-       switch (dev->id) {
-       case 0:
-               saved_icmr[0] = ICMR;
-               ICMR = 0;
-               break;
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
-       case 1:
-               saved_icmr[1] = ICMR2;
-               ICMR2 = 0;
-               break;
-#endif
-       default:
-               return -EINVAL;
+       int i, irq = PXA_IRQ(0);
+
+       for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
+               saved_icmr[i] = _ICMR(irq);
+               _ICMR(irq) = 0;
        }
 
        return 0;
@@ -138,22 +95,14 @@ static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
 
 static int pxa_irq_resume(struct sys_device *dev)
 {
-       switch (dev->id) {
-       case 0:
-               ICMR = saved_icmr[0];
-               ICLR = 0;
-               ICCR = 1;
-               break;
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
-       case 1:
-               ICMR2 = saved_icmr[1];
-               ICLR2 = 0;
-               break;
-#endif
-       default:
-               return -EINVAL;
+       int i, irq = PXA_IRQ(0);
+
+       for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
+               _ICMR(irq) = saved_icmr[i];
+               _ICLR(irq) = 0;
        }
 
+       ICCR = 1;
        return 0;
 }
 #else
index f379928..bb0bf51 100644 (file)
@@ -267,7 +267,7 @@ set_pwer:
 
 void __init pxa25x_init_irq(void)
 {
-       pxa_init_irq_low();
+       pxa_init_irq(32);
        pxa_init_irq_gpio(85);
        pxa_init_irq_set_wake(pxa25x_set_wake);
 }
index c186bd1..54d8448 100644 (file)
@@ -340,8 +340,7 @@ set_pwer:
 
 void __init pxa27x_init_irq(void)
 {
-       pxa_init_irq_low();
-       pxa_init_irq_high();
+       pxa_init_irq(34);
        pxa_init_irq_gpio(128);
        pxa_init_irq_set_wake(pxa27x_set_wake);
 }
@@ -389,10 +388,6 @@ static struct platform_device *devices[] __initdata = {
 
 static struct sys_device pxa27x_sysdev[] = {
        {
-               .id     = 0,
-               .cls    = &pxa_irq_sysclass,
-       }, {
-               .id     = 1,
                .cls    = &pxa_irq_sysclass,
        }, {
                .cls    = &pxa_gpio_sysclass,
index 93f3236..8f8179b 100644 (file)
@@ -513,8 +513,7 @@ void __init pxa3xx_init_irq(void)
        value |= (1 << 6);
        __asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value));
 
-       pxa_init_irq_low();
-       pxa_init_irq_high();
+       pxa_init_irq(56);
        pxa_init_irq_gpio(128);
        pxa3xx_init_irq_pm();
 }
@@ -538,10 +537,6 @@ static struct platform_device *devices[] __initdata = {
 
 static struct sys_device pxa3xx_sysdev[] = {
        {
-               .id     = 0,
-               .cls    = &pxa_irq_sysclass,
-       }, {
-               .id     = 1,
                .cls    = &pxa_irq_sysclass,
        }, {
                .cls    = &pxa_gpio_sysclass,
index fd81e55..e659be4 100644 (file)
 #define ICPR           __REG(0x40D00010)  /* Interrupt Controller Pending Register */
 #define ICCR           __REG(0x40D00014)  /* Interrupt Controller Control Register */
 
+#define ICIP2          __REG(0x40D0009C)  /* Interrupt Controller IRQ Pending Register 2 */
+#define ICMR2          __REG(0x40D000A0)  /* Interrupt Controller Mask Register 2 */
+#define ICLR2          __REG(0x40D000A4)  /* Interrupt Controller Level Register 2 */
+#define ICFP2          __REG(0x40D000A8)  /* Interrupt Controller FIQ Pending Register 2 */
+#define ICPR2          __REG(0x40D000AC)  /* Interrupt Controller Pending Register 2 */
 
 /*
  * General Purpose I/O
 
 /* Interrupt Controller */
 
-#define ICIP2          __REG(0x40D0009C)  /* Interrupt Controller IRQ Pending Register 2 */
-#define ICMR2          __REG(0x40D000A0)  /* Interrupt Controller Mask Register 2 */
-#define ICLR2          __REG(0x40D000A4)  /* Interrupt Controller Level Register 2 */
-#define ICFP2          __REG(0x40D000A8)  /* Interrupt Controller FIQ Pending Register 2 */
-#define ICPR2          __REG(0x40D000AC)  /* Interrupt Controller Pending Register 2 */
-
 #define _GPLR(x)       __REG2(0x40E00000, ((x) & 0x60) >> 3)
 #define _GPDR(x)       __REG2(0x40E0000C, ((x) & 0x60) >> 3)
 #define _GPSR(x)       __REG2(0x40E00018, ((x) & 0x60) >> 3)