sh: mach-se: Convert SE7343 FPGA to dynamic IRQ allocation.
Paul Mundt [Tue, 12 Jan 2010 04:37:04 +0000 (13:37 +0900)]
This gets rid of the arbitrary set of vectors used by the SE7722 FPGA
interrupt controller and switches over to a completely dynamic set.
No assumptions regarding a contiguous range are made, and the platform
resources themselves need to be filled in lazily.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

arch/sh/boards/mach-se/7343/irq.c
arch/sh/boards/mach-se/7343/setup.c
arch/sh/include/mach-se/mach/se7343.h

index 051c29d..c60fd13 100644 (file)
 #include <linux/io.h>
 #include <mach-se/mach/se7343.h>
 
+unsigned int se7343_fpga_irq[SE7343_FPGA_IRQ_NR] = { 0, };
+
 static void disable_se7343_irq(unsigned int irq)
 {
-       unsigned int bit = irq - SE7343_FPGA_IRQ_BASE;
+       unsigned int bit = (unsigned int)get_irq_chip_data(irq);
        ctrl_outw(ctrl_inw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK);
 }
 
 static void enable_se7343_irq(unsigned int irq)
 {
-       unsigned int bit = irq - SE7343_FPGA_IRQ_BASE;
+       unsigned int bit = (unsigned int)get_irq_chip_data(irq);
        ctrl_outw(ctrl_inw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK);
 }
 
@@ -38,18 +40,15 @@ static struct irq_chip se7343_irq_chip __read_mostly = {
 static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
        unsigned short intv = ctrl_inw(PA_CPLD_ST);
-       struct irq_desc *ext_desc;
-       unsigned int ext_irq = SE7343_FPGA_IRQ_BASE;
+       unsigned int ext_irq = 0;
 
        intv &= (1 << SE7343_FPGA_IRQ_NR) - 1;
 
-       while (intv) {
-               if (intv & 1) {
-                       ext_desc = irq_desc + ext_irq;
-                       handle_level_irq(ext_irq, ext_desc);
-               }
-               intv >>= 1;
-               ext_irq++;
+       for (; intv; intv >>= 1, ext_irq++) {
+               if (!(intv & 1))
+                       continue;
+
+               generic_handle_irq(se7343_fpga_irq[ext_irq]);
        }
 }
 
@@ -58,16 +57,24 @@ static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc)
  */
 void __init init_7343se_IRQ(void)
 {
-       int i;
+       int i, irq;
 
        ctrl_outw(0, PA_CPLD_IMSK);     /* disable all irqs */
        ctrl_outw(0x2000, 0xb03fffec);  /* mrshpc irq enable */
 
-       for (i = 0; i < SE7343_FPGA_IRQ_NR; i++)
-               set_irq_chip_and_handler_name(SE7343_FPGA_IRQ_BASE + i,
+       for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) {
+               irq = create_irq();
+               if (irq < 0)
+                       return;
+               se7343_fpga_irq[i] = irq;
+
+               set_irq_chip_and_handler_name(se7343_fpga_irq[i],
                                              &se7343_irq_chip,
                                              handle_level_irq, "level");
 
+               set_irq_chip_data(se7343_fpga_irq[i], (void *)i);
+       }
+
        set_irq_chained_handler(IRQ0_IRQ, se7343_irq_demux);
        set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
        set_irq_chained_handler(IRQ1_IRQ, se7343_irq_demux);
index 4de56f3..292cc47 100644 (file)
@@ -82,7 +82,6 @@ static struct plat_serial8250_port serial_platform_data[] = {
                .mapbase        = 0x16000000,
                .regshift       = 1,
                .flags          = ST16C2550C_FLAGS,
-               .irq            = UARTA_IRQ,
                .uartclk        = 7372800,
        },
        [1] = {
@@ -90,7 +89,6 @@ static struct plat_serial8250_port serial_platform_data[] = {
                .mapbase        = 0x17000000,
                .regshift       = 1,
                .flags          = ST16C2550C_FLAGS,
-               .irq            = UARTB_IRQ,
                .uartclk        = 7372800,
        },
        { },
@@ -121,7 +119,7 @@ static struct resource usb_resources[] = {
                .flags  = IORESOURCE_MEM,
        },
        [2] = {
-               .start  = USB_IRQ,
+               /* Filled in later */
                .flags  = IORESOURCE_IRQ,
        },
 };
@@ -138,8 +136,8 @@ static struct isp116x_platform_data usb_platform_data = {
 static struct platform_device usb_device = {
        .name                   = "isp116x-hcd",
        .id                     = -1,
-       .num_resources          = ARRAY_SIZE(usb_resources),
-       .resource               = usb_resources,
+       .num_resources          = ARRAY_SIZE(usb_resources),
+       .resource               = usb_resources,
        .dev                    = {
                .platform_data  = &usb_platform_data,
        },
@@ -155,6 +153,13 @@ static struct platform_device *sh7343se_platform_devices[] __initdata = {
 
 static int __init sh7343se_devices_setup(void)
 {
+       /* Wire-up dynamic vectors */
+       serial_platform_data[0].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTA];
+       serial_platform_data[1].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTB];
+
+       usb_resources[2].start = usb_resources[2].end =
+               se7343_fpga_irq[SE7343_FPGA_IRQ_USB];
+
        return platform_add_devices(sh7343se_platform_devices,
                                    ARRAY_SIZE(sh7343se_platform_devices));
 }
@@ -179,6 +184,5 @@ static void __init sh7343se_setup(char **cmdline_p)
 static struct sh_machine_vector mv_7343se __initmv = {
        .mv_name = "SolutionEngine 7343",
        .mv_setup = sh7343se_setup,
-       .mv_nr_irqs = SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_NR,
        .mv_init_irq = init_7343se_IRQ,
 };
index 749914b..8d8170d 100644 (file)
 
 #define PORT_DRVCR     0xA4050180
 
-#define PORT_PADR      0xA4050120
-#define PORT_PBDR      0xA4050122
-#define PORT_PCDR      0xA4050124
-#define PORT_PDDR      0xA4050126
-#define PORT_PEDR      0xA4050128
-#define PORT_PFDR      0xA405012A
-#define PORT_PGDR      0xA405012C
-#define PORT_PHDR      0xA405012E
-#define PORT_PJDR      0xA4050130
-#define PORT_PKDR      0xA4050132
-#define PORT_PLDR      0xA4050134
-#define PORT_PMDR      0xA4050136
-#define PORT_PNDR      0xA4050138
-#define PORT_PQDR      0xA405013A
-#define PORT_PRDR      0xA405013C
-#define PORT_PTDR      0xA4050160
-#define PORT_PUDR      0xA4050162
-#define PORT_PVDR      0xA4050164
-#define PORT_PWDR      0xA4050166
-#define PORT_PYDR      0xA4050168
+#define PORT_PADR      0xA4050120
+#define PORT_PBDR      0xA4050122
+#define PORT_PCDR      0xA4050124
+#define PORT_PDDR      0xA4050126
+#define PORT_PEDR      0xA4050128
+#define PORT_PFDR      0xA405012A
+#define PORT_PGDR      0xA405012C
+#define PORT_PHDR      0xA405012E
+#define PORT_PJDR      0xA4050130
+#define PORT_PKDR      0xA4050132
+#define PORT_PLDR      0xA4050134
+#define PORT_PMDR      0xA4050136
+#define PORT_PNDR      0xA4050138
+#define PORT_PQDR      0xA405013A
+#define PORT_PRDR      0xA405013C
+#define PORT_PTDR      0xA4050160
+#define PORT_PUDR      0xA4050162
+#define PORT_PVDR      0xA4050164
+#define PORT_PWDR      0xA4050166
+#define PORT_PYDR      0xA4050168
 
 #define FPGA_IN                0xb1400000
 #define FPGA_OUT       0xb1400002
 #define SE7343_FPGA_IRQ_UARTB  11
 
 #define SE7343_FPGA_IRQ_NR     12
-#define SE7343_FPGA_IRQ_BASE   120
-
-#define MRSHPC_IRQ3            (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC3)
-#define MRSHPC_IRQ2            (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC2)
-#define MRSHPC_IRQ1            (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC1)
-#define MRSHPC_IRQ0            (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC0)
-#define SMC_IRQ                (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_SMC)
-#define USB_IRQ                (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_USB)
-#define UARTA_IRQ      (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_UARTA)
-#define UARTB_IRQ      (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_UARTB)
 
 /* arch/sh/boards/se/7343/irq.c */
+extern unsigned int se7343_fpga_irq[];
+
 void init_7343se_IRQ(void);
 
 #endif  /* __ASM_SH_HITACHI_SE7343_H */