aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-11-03 21:44:21 -0500
committerPaul Mundt <lethal@linux-sh.org>2009-11-03 21:44:21 -0500
commita37c6c7aec38a693f87ee5ccc6e60a5b3ee700f2 (patch)
tree725a5fcc4627d7e1896a3646f26687f714dba31d /arch/sh
parent45b9deaf14e74543371aa8faea69c14e27b038c6 (diff)
sh: mach-se: Convert SE7722 FPGA to dynamic IRQ allocation.
This gets rid of the arbitrary set of vectors used by the SE7722 FPGA interrupt controller and witches 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')
-rw-r--r--arch/sh/boards/mach-se/7722/irq.c32
-rw-r--r--arch/sh/boards/mach-se/7722/setup.c15
-rw-r--r--arch/sh/include/mach-se/mach/se7722.h11
3 files changed, 31 insertions, 27 deletions
diff --git a/arch/sh/boards/mach-se/7722/irq.c b/arch/sh/boards/mach-se/7722/irq.c
index 02d21a3e2a8f..4eb31acfafef 100644
--- a/arch/sh/boards/mach-se/7722/irq.c
+++ b/arch/sh/boards/mach-se/7722/irq.c
@@ -16,15 +16,17 @@
16#include <asm/io.h> 16#include <asm/io.h>
17#include <mach-se/mach/se7722.h> 17#include <mach-se/mach/se7722.h>
18 18
19unsigned int se7722_fpga_irq[SE7722_FPGA_IRQ_NR] = { 0, };
20
19static void disable_se7722_irq(unsigned int irq) 21static void disable_se7722_irq(unsigned int irq)
20{ 22{
21 unsigned int bit = irq - SE7722_FPGA_IRQ_BASE; 23 unsigned int bit = (unsigned int)get_irq_chip_data(irq);
22 ctrl_outw(ctrl_inw(IRQ01_MASK) | 1 << bit, IRQ01_MASK); 24 ctrl_outw(ctrl_inw(IRQ01_MASK) | 1 << bit, IRQ01_MASK);
23} 25}
24 26
25static void enable_se7722_irq(unsigned int irq) 27static void enable_se7722_irq(unsigned int irq)
26{ 28{
27 unsigned int bit = irq - SE7722_FPGA_IRQ_BASE; 29 unsigned int bit = (unsigned int)get_irq_chip_data(irq);
28 ctrl_outw(ctrl_inw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK); 30 ctrl_outw(ctrl_inw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK);
29} 31}
30 32
@@ -38,18 +40,15 @@ static struct irq_chip se7722_irq_chip __read_mostly = {
38static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) 40static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc)
39{ 41{
40 unsigned short intv = ctrl_inw(IRQ01_STS); 42 unsigned short intv = ctrl_inw(IRQ01_STS);
41 struct irq_desc *ext_desc; 43 unsigned int ext_irq = 0;
42 unsigned int ext_irq = SE7722_FPGA_IRQ_BASE;
43 44
44 intv &= (1 << SE7722_FPGA_IRQ_NR) - 1; 45 intv &= (1 << SE7722_FPGA_IRQ_NR) - 1;
45 46
46 while (intv) { 47 for (; intv; intv >>= 1, ext_irq++) {
47 if (intv & 1) { 48 if (!(intv & 1))
48 ext_desc = irq_desc + ext_irq; 49 continue;
49 handle_level_irq(ext_irq, ext_desc); 50
50 } 51 generic_handle_irq(se7722_fpga_irq[ext_irq]);
51 intv >>= 1;
52 ext_irq++;
53 } 52 }
54} 53}
55 54
@@ -63,11 +62,18 @@ void __init init_se7722_IRQ(void)
63 ctrl_outw(0, IRQ01_MASK); /* disable all irqs */ 62 ctrl_outw(0, IRQ01_MASK); /* disable all irqs */
64 ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */ 63 ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */
65 64
66 for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) 65 for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) {
67 set_irq_chip_and_handler_name(SE7722_FPGA_IRQ_BASE + i, 66 se7722_fpga_irq[i] = create_irq();
67 if (se7722_fpga_irq[i] < 0)
68 return;
69
70 set_irq_chip_and_handler_name(se7722_fpga_irq[i],
68 &se7722_irq_chip, 71 &se7722_irq_chip,
69 handle_level_irq, "level"); 72 handle_level_irq, "level");
70 73
74 set_irq_chip_data(se7722_fpga_irq[i], (void *)i);
75 }
76
71 set_irq_chained_handler(IRQ0_IRQ, se7722_irq_demux); 77 set_irq_chained_handler(IRQ0_IRQ, se7722_irq_demux);
72 set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); 78 set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
73 79
diff --git a/arch/sh/boards/mach-se/7722/setup.c b/arch/sh/boards/mach-se/7722/setup.c
index 36374078e521..d05f34f6528e 100644
--- a/arch/sh/boards/mach-se/7722/setup.c
+++ b/arch/sh/boards/mach-se/7722/setup.c
@@ -60,8 +60,7 @@ static struct resource smc91x_eth_resources[] = {
60 .flags = IORESOURCE_MEM, 60 .flags = IORESOURCE_MEM,
61 }, 61 },
62 [1] = { 62 [1] = {
63 .start = SMC_IRQ, 63 /* Filled in later */
64 .end = SMC_IRQ,
65 .flags = IORESOURCE_IRQ, 64 .flags = IORESOURCE_IRQ,
66 }, 65 },
67}; 66};
@@ -90,8 +89,7 @@ static struct resource cf_ide_resources[] = {
90 .flags = IORESOURCE_IO, 89 .flags = IORESOURCE_IO,
91 }, 90 },
92 [2] = { 91 [2] = {
93 .start = MRSHPC_IRQ0, 92 /* Filled in later */
94 .end = MRSHPC_IRQ0,
95 .flags = IORESOURCE_IRQ, 93 .flags = IORESOURCE_IRQ,
96 }, 94 },
97}; 95};
@@ -153,6 +151,14 @@ static struct platform_device *se7722_devices[] __initdata = {
153static int __init se7722_devices_setup(void) 151static int __init se7722_devices_setup(void)
154{ 152{
155 mrshpc_setup_windows(); 153 mrshpc_setup_windows();
154
155 /* Wire-up dynamic vectors */
156 cf_ide_resources[2].start = cf_ide_resources[2].end =
157 se7722_fpga_irq[SE7722_FPGA_IRQ_MRSHPC0];
158
159 smc91x_eth_resources[1].start = smc91x_eth_resources[1].end =
160 se7722_fpga_irq[SE7722_FPGA_IRQ_SMC];
161
156 return platform_add_devices(se7722_devices, ARRAY_SIZE(se7722_devices)); 162 return platform_add_devices(se7722_devices, ARRAY_SIZE(se7722_devices));
157} 163}
158device_initcall(se7722_devices_setup); 164device_initcall(se7722_devices_setup);
@@ -193,6 +199,5 @@ static void __init se7722_setup(char **cmdline_p)
193static struct sh_machine_vector mv_se7722 __initmv = { 199static struct sh_machine_vector mv_se7722 __initmv = {
194 .mv_name = "Solution Engine 7722" , 200 .mv_name = "Solution Engine 7722" ,
195 .mv_setup = se7722_setup , 201 .mv_setup = se7722_setup ,
196 .mv_nr_irqs = SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_NR,
197 .mv_init_irq = init_se7722_IRQ, 202 .mv_init_irq = init_se7722_IRQ,
198}; 203};
diff --git a/arch/sh/include/mach-se/mach/se7722.h b/arch/sh/include/mach-se/mach/se7722.h
index e971d9a82f4a..16505bfb8a9e 100644
--- a/arch/sh/include/mach-se/mach/se7722.h
+++ b/arch/sh/include/mach-se/mach/se7722.h
@@ -92,18 +92,11 @@
92#define SE7722_FPGA_IRQ_MRSHPC1 3 /* IRQ1 */ 92#define SE7722_FPGA_IRQ_MRSHPC1 3 /* IRQ1 */
93#define SE7722_FPGA_IRQ_MRSHPC2 4 /* IRQ1 */ 93#define SE7722_FPGA_IRQ_MRSHPC2 4 /* IRQ1 */
94#define SE7722_FPGA_IRQ_MRSHPC3 5 /* IRQ1 */ 94#define SE7722_FPGA_IRQ_MRSHPC3 5 /* IRQ1 */
95
96#define SE7722_FPGA_IRQ_NR 6 95#define SE7722_FPGA_IRQ_NR 6
97#define SE7722_FPGA_IRQ_BASE 110
98
99#define MRSHPC_IRQ3 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC3)
100#define MRSHPC_IRQ2 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC2)
101#define MRSHPC_IRQ1 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC1)
102#define MRSHPC_IRQ0 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC0)
103#define SMC_IRQ (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_SMC)
104#define USB_IRQ (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_USB)
105 96
106/* arch/sh/boards/se/7722/irq.c */ 97/* arch/sh/boards/se/7722/irq.c */
98extern unsigned int se7722_fpga_irq[];
99
107void init_se7722_IRQ(void); 100void init_se7722_IRQ(void);
108 101
109#define __IO_PREFIX se7722 102#define __IO_PREFIX se7722