aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-01-11 23:37:04 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-01-11 23:37:04 -0500
commit53e6d8e0060fe2bb9b11238f8250fdfbb0589425 (patch)
tree16b89577dc64437d1d6fbb670c527d1b1cfe3ea2
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>
-rw-r--r--arch/sh/boards/mach-se/7343/irq.c35
-rw-r--r--arch/sh/boards/mach-se/7343/setup.c16
-rw-r--r--arch/sh/include/mach-se/mach/se7343.h52
3 files changed, 53 insertions, 50 deletions
diff --git a/arch/sh/boards/mach-se/7343/irq.c b/arch/sh/boards/mach-se/7343/irq.c
index 051c29d4eae0..c60fd13608d0 100644
--- a/arch/sh/boards/mach-se/7343/irq.c
+++ b/arch/sh/boards/mach-se/7343/irq.c
@@ -16,15 +16,17 @@
16#include <linux/io.h> 16#include <linux/io.h>
17#include <mach-se/mach/se7343.h> 17#include <mach-se/mach/se7343.h>
18 18
19unsigned int se7343_fpga_irq[SE7343_FPGA_IRQ_NR] = { 0, };
20
19static void disable_se7343_irq(unsigned int irq) 21static void disable_se7343_irq(unsigned int irq)
20{ 22{
21 unsigned int bit = irq - SE7343_FPGA_IRQ_BASE; 23 unsigned int bit = (unsigned int)get_irq_chip_data(irq);
22 ctrl_outw(ctrl_inw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK); 24 ctrl_outw(ctrl_inw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK);
23} 25}
24 26
25static void enable_se7343_irq(unsigned int irq) 27static void enable_se7343_irq(unsigned int irq)
26{ 28{
27 unsigned int bit = irq - SE7343_FPGA_IRQ_BASE; 29 unsigned int bit = (unsigned int)get_irq_chip_data(irq);
28 ctrl_outw(ctrl_inw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK); 30 ctrl_outw(ctrl_inw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK);
29} 31}
30 32
@@ -38,18 +40,15 @@ static struct irq_chip se7343_irq_chip __read_mostly = {
38static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc) 40static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc)
39{ 41{
40 unsigned short intv = ctrl_inw(PA_CPLD_ST); 42 unsigned short intv = ctrl_inw(PA_CPLD_ST);
41 struct irq_desc *ext_desc; 43 unsigned int ext_irq = 0;
42 unsigned int ext_irq = SE7343_FPGA_IRQ_BASE;
43 44
44 intv &= (1 << SE7343_FPGA_IRQ_NR) - 1; 45 intv &= (1 << SE7343_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(se7343_fpga_irq[ext_irq]);
51 intv >>= 1;
52 ext_irq++;
53 } 52 }
54} 53}
55 54
@@ -58,16 +57,24 @@ static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc)
58 */ 57 */
59void __init init_7343se_IRQ(void) 58void __init init_7343se_IRQ(void)
60{ 59{
61 int i; 60 int i, irq;
62 61
63 ctrl_outw(0, PA_CPLD_IMSK); /* disable all irqs */ 62 ctrl_outw(0, PA_CPLD_IMSK); /* 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 < SE7343_FPGA_IRQ_NR; i++) 65 for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) {
67 set_irq_chip_and_handler_name(SE7343_FPGA_IRQ_BASE + i, 66 irq = create_irq();
67 if (irq < 0)
68 return;
69 se7343_fpga_irq[i] = irq;
70
71 set_irq_chip_and_handler_name(se7343_fpga_irq[i],
68 &se7343_irq_chip, 72 &se7343_irq_chip,
69 handle_level_irq, "level"); 73 handle_level_irq, "level");
70 74
75 set_irq_chip_data(se7343_fpga_irq[i], (void *)i);
76 }
77
71 set_irq_chained_handler(IRQ0_IRQ, se7343_irq_demux); 78 set_irq_chained_handler(IRQ0_IRQ, se7343_irq_demux);
72 set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); 79 set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
73 set_irq_chained_handler(IRQ1_IRQ, se7343_irq_demux); 80 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 4de56f35f419..292cc47d853f 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[] = {
82 .mapbase = 0x16000000, 82 .mapbase = 0x16000000,
83 .regshift = 1, 83 .regshift = 1,
84 .flags = ST16C2550C_FLAGS, 84 .flags = ST16C2550C_FLAGS,
85 .irq = UARTA_IRQ,
86 .uartclk = 7372800, 85 .uartclk = 7372800,
87 }, 86 },
88 [1] = { 87 [1] = {
@@ -90,7 +89,6 @@ static struct plat_serial8250_port serial_platform_data[] = {
90 .mapbase = 0x17000000, 89 .mapbase = 0x17000000,
91 .regshift = 1, 90 .regshift = 1,
92 .flags = ST16C2550C_FLAGS, 91 .flags = ST16C2550C_FLAGS,
93 .irq = UARTB_IRQ,
94 .uartclk = 7372800, 92 .uartclk = 7372800,
95 }, 93 },
96 { }, 94 { },
@@ -121,7 +119,7 @@ static struct resource usb_resources[] = {
121 .flags = IORESOURCE_MEM, 119 .flags = IORESOURCE_MEM,
122 }, 120 },
123 [2] = { 121 [2] = {
124 .start = USB_IRQ, 122 /* Filled in later */
125 .flags = IORESOURCE_IRQ, 123 .flags = IORESOURCE_IRQ,
126 }, 124 },
127}; 125};
@@ -138,8 +136,8 @@ static struct isp116x_platform_data usb_platform_data = {
138static struct platform_device usb_device = { 136static struct platform_device usb_device = {
139 .name = "isp116x-hcd", 137 .name = "isp116x-hcd",
140 .id = -1, 138 .id = -1,
141 .num_resources = ARRAY_SIZE(usb_resources), 139 .num_resources = ARRAY_SIZE(usb_resources),
142 .resource = usb_resources, 140 .resource = usb_resources,
143 .dev = { 141 .dev = {
144 .platform_data = &usb_platform_data, 142 .platform_data = &usb_platform_data,
145 }, 143 },
@@ -155,6 +153,13 @@ static struct platform_device *sh7343se_platform_devices[] __initdata = {
155 153
156static int __init sh7343se_devices_setup(void) 154static int __init sh7343se_devices_setup(void)
157{ 155{
156 /* Wire-up dynamic vectors */
157 serial_platform_data[0].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTA];
158 serial_platform_data[1].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTB];
159
160 usb_resources[2].start = usb_resources[2].end =
161 se7343_fpga_irq[SE7343_FPGA_IRQ_USB];
162
158 return platform_add_devices(sh7343se_platform_devices, 163 return platform_add_devices(sh7343se_platform_devices,
159 ARRAY_SIZE(sh7343se_platform_devices)); 164 ARRAY_SIZE(sh7343se_platform_devices));
160} 165}
@@ -179,6 +184,5 @@ static void __init sh7343se_setup(char **cmdline_p)
179static struct sh_machine_vector mv_7343se __initmv = { 184static struct sh_machine_vector mv_7343se __initmv = {
180 .mv_name = "SolutionEngine 7343", 185 .mv_name = "SolutionEngine 7343",
181 .mv_setup = sh7343se_setup, 186 .mv_setup = sh7343se_setup,
182 .mv_nr_irqs = SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_NR,
183 .mv_init_irq = init_7343se_IRQ, 187 .mv_init_irq = init_7343se_IRQ,
184}; 188};
diff --git a/arch/sh/include/mach-se/mach/se7343.h b/arch/sh/include/mach-se/mach/se7343.h
index 749914b400fb..8d8170d6cc43 100644
--- a/arch/sh/include/mach-se/mach/se7343.h
+++ b/arch/sh/include/mach-se/mach/se7343.h
@@ -94,26 +94,26 @@
94 94
95#define PORT_DRVCR 0xA4050180 95#define PORT_DRVCR 0xA4050180
96 96
97#define PORT_PADR 0xA4050120 97#define PORT_PADR 0xA4050120
98#define PORT_PBDR 0xA4050122 98#define PORT_PBDR 0xA4050122
99#define PORT_PCDR 0xA4050124 99#define PORT_PCDR 0xA4050124
100#define PORT_PDDR 0xA4050126 100#define PORT_PDDR 0xA4050126
101#define PORT_PEDR 0xA4050128 101#define PORT_PEDR 0xA4050128
102#define PORT_PFDR 0xA405012A 102#define PORT_PFDR 0xA405012A
103#define PORT_PGDR 0xA405012C 103#define PORT_PGDR 0xA405012C
104#define PORT_PHDR 0xA405012E 104#define PORT_PHDR 0xA405012E
105#define PORT_PJDR 0xA4050130 105#define PORT_PJDR 0xA4050130
106#define PORT_PKDR 0xA4050132 106#define PORT_PKDR 0xA4050132
107#define PORT_PLDR 0xA4050134 107#define PORT_PLDR 0xA4050134
108#define PORT_PMDR 0xA4050136 108#define PORT_PMDR 0xA4050136
109#define PORT_PNDR 0xA4050138 109#define PORT_PNDR 0xA4050138
110#define PORT_PQDR 0xA405013A 110#define PORT_PQDR 0xA405013A
111#define PORT_PRDR 0xA405013C 111#define PORT_PRDR 0xA405013C
112#define PORT_PTDR 0xA4050160 112#define PORT_PTDR 0xA4050160
113#define PORT_PUDR 0xA4050162 113#define PORT_PUDR 0xA4050162
114#define PORT_PVDR 0xA4050164 114#define PORT_PVDR 0xA4050164
115#define PORT_PWDR 0xA4050166 115#define PORT_PWDR 0xA4050166
116#define PORT_PYDR 0xA4050168 116#define PORT_PYDR 0xA4050168
117 117
118#define FPGA_IN 0xb1400000 118#define FPGA_IN 0xb1400000
119#define FPGA_OUT 0xb1400002 119#define FPGA_OUT 0xb1400002
@@ -133,18 +133,10 @@
133#define SE7343_FPGA_IRQ_UARTB 11 133#define SE7343_FPGA_IRQ_UARTB 11
134 134
135#define SE7343_FPGA_IRQ_NR 12 135#define SE7343_FPGA_IRQ_NR 12
136#define SE7343_FPGA_IRQ_BASE 120
137
138#define MRSHPC_IRQ3 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC3)
139#define MRSHPC_IRQ2 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC2)
140#define MRSHPC_IRQ1 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC1)
141#define MRSHPC_IRQ0 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC0)
142#define SMC_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_SMC)
143#define USB_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_USB)
144#define UARTA_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_UARTA)
145#define UARTB_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_UARTB)
146 136
147/* arch/sh/boards/se/7343/irq.c */ 137/* arch/sh/boards/se/7343/irq.c */
138extern unsigned int se7343_fpga_irq[];
139
148void init_7343se_IRQ(void); 140void init_7343se_IRQ(void);
149 141
150#endif /* __ASM_SH_HITACHI_SE7343_H */ 142#endif /* __ASM_SH_HITACHI_SE7343_H */