summaryrefslogtreecommitdiffstats
path: root/arch/sh/boards
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-01-12 13:37:04 +0900
committerPaul Mundt <lethal@linux-sh.org>2010-01-12 13:37:04 +0900
commit53e6d8e0060fe2bb9b11238f8250fdfbb0589425 (patch)
tree16b89577dc64437d1d6fbb670c527d1b1cfe3ea2 /arch/sh/boards
parent8c0b8139c87cfe8b95c6e763b4ca3190aa9b1ad0 (diff)
sh: mach-se: Convert SE7343 FPGA to dynamic IRQ allocation.
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>
Diffstat (limited to 'arch/sh/boards')
-rw-r--r--arch/sh/boards/mach-se/7343/irq.c35
-rw-r--r--arch/sh/boards/mach-se/7343/setup.c16
2 files changed, 31 insertions, 20 deletions
diff --git a/arch/sh/boards/mach-se/7343/irq.c b/arch/sh/boards/mach-se/7343/irq.c
index 051c29d4eae..c60fd13608d 100644
--- a/arch/sh/boards/mach-se/7343/irq.c
+++ b/arch/sh/boards/mach-se/7343/irq.c
@@ -16,15 +16,17 @@
#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);
diff --git a/arch/sh/boards/mach-se/7343/setup.c b/arch/sh/boards/mach-se/7343/setup.c
index 4de56f35f41..292cc47d853 100644
--- a/arch/sh/boards/mach-se/7343/setup.c
+++ b/arch/sh/boards/mach-se/7343/setup.c
@@ -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,
};