diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-11-03 21:44:21 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-11-03 21:44:21 -0500 |
commit | a37c6c7aec38a693f87ee5ccc6e60a5b3ee700f2 (patch) | |
tree | 725a5fcc4627d7e1896a3646f26687f714dba31d /arch/sh | |
parent | 45b9deaf14e74543371aa8faea69c14e27b038c6 (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.c | 32 | ||||
-rw-r--r-- | arch/sh/boards/mach-se/7722/setup.c | 15 | ||||
-rw-r--r-- | arch/sh/include/mach-se/mach/se7722.h | 11 |
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 | ||
19 | unsigned int se7722_fpga_irq[SE7722_FPGA_IRQ_NR] = { 0, }; | ||
20 | |||
19 | static void disable_se7722_irq(unsigned int irq) | 21 | static 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 | ||
25 | static void enable_se7722_irq(unsigned int irq) | 27 | static 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 = { | |||
38 | static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) | 40 | static 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 = { | |||
153 | static int __init se7722_devices_setup(void) | 151 | static 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 | } |
158 | device_initcall(se7722_devices_setup); | 164 | device_initcall(se7722_devices_setup); |
@@ -193,6 +199,5 @@ static void __init se7722_setup(char **cmdline_p) | |||
193 | static struct sh_machine_vector mv_se7722 __initmv = { | 199 | static 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 */ |
98 | extern unsigned int se7722_fpga_irq[]; | ||
99 | |||
107 | void init_se7722_IRQ(void); | 100 | void init_se7722_IRQ(void); |
108 | 101 | ||
109 | #define __IO_PREFIX se7722 | 102 | #define __IO_PREFIX se7722 |