aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
diff options
context:
space:
mode:
authorMagnus Damm <damm@igel.co.jp>2007-07-19 23:10:29 -0400
committerPaul Mundt <lethal@linux-sh.org>2007-07-19 23:18:21 -0400
commit39c7aa9ea9b6175f4313f69ef9f8e0a3a9bba5bb (patch)
tree4effb54c779136032f35acddc620077abcb4cd9c /arch/sh/kernel/cpu/sh4a/setup-sh7780.c
parent680c45981ae2b4029878806d76aa17bb62d3c674 (diff)
sh: intc - add support for 7780
This patch converts the cpu specific 7780 setup code to use the new intc controller. Many new vectors are added and also support for external interrupt sense configuration. So with this patch it is now possible to configure external interrupt pins as edge or level triggered using set_irq_type(). No external interrupts are registered by default. Use plat_irq_setup_pins() to select between IRQ or IRL mode. This patch also fixes the Alarm IRQ for the RTC. Signed-off-by: Magnus Damm <damm@igel.co.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/cpu/sh4a/setup-sh7780.c')
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7780.c219
1 files changed, 190 insertions, 29 deletions
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
index 86cd6281fa4d..a4127ec15203 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
@@ -30,7 +30,7 @@ static struct resource rtc_resources[] = {
30 }, 30 },
31 [3] = { 31 [3] = {
32 /* Alarm IRQ */ 32 /* Alarm IRQ */
33 .start = 23, 33 .start = 20,
34 .flags = IORESOURCE_IRQ, 34 .flags = IORESOURCE_IRQ,
35 }, 35 },
36}; 36};
@@ -78,44 +78,205 @@ static int __init sh7780_devices_setup(void)
78} 78}
79__initcall(sh7780_devices_setup); 79__initcall(sh7780_devices_setup);
80 80
81static struct intc2_data intc2_irq_table[] = { 81enum {
82 { 28, 0, 24, 0, 0, 2 }, /* TMU0 */ 82 UNUSED = 0,
83 83
84 { 21, 1, 0, 0, 2, 2 }, 84 /* interrupt sources */
85 { 22, 1, 1, 0, 2, 2 },
86 { 23, 1, 2, 0, 2, 2 },
87 85
88 { 40, 8, 24, 0, 3, 3 }, /* SCIF0 ERI */ 86 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
89 { 41, 8, 24, 0, 3, 3 }, /* SCIF0 RXI */ 87 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
90 { 42, 8, 24, 0, 3, 3 }, /* SCIF0 BRI */ 88 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
91 { 43, 8, 24, 0, 3, 3 }, /* SCIF0 TXI */ 89 IRL_HHLL, IRL_HHLH, IRL_HHHL,
92 90
93 { 76, 8, 16, 0, 4, 3 }, /* SCIF1 ERI */ 91 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
94 { 77, 8, 16, 0, 4, 3 }, /* SCIF1 RXI */ 92 RTC_ATI, RTC_PRI, RTC_CUI,
95 { 78, 8, 16, 0, 4, 3 }, /* SCIF1 BRI */ 93 WDT,
96 { 79, 8, 16, 0, 4, 3 }, /* SCIF1 TXI */ 94 TMU0, TMU1, TMU2, TMU2_TICPI,
95 HUDI,
96 DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3, DMAC0_DMAE,
97 SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
98 DMAC0_DMINT4, DMAC0_DMINT5, DMAC1_DMINT6, DMAC1_DMINT7,
99 CMT, HAC,
100 PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD,
101 PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0,
102 SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
103 SIOF, HSPI,
104 MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY,
105 DMAC1_DMINT8, DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11,
106 TMU3, TMU4, TMU5,
107 SSI,
108 FLCTL_FLSTE, FLCTL_FLEND, FLCTL_FLTRQ0, FLCTL_FLTRQ1,
109 GPIOI0, GPIOI1, GPIOI2, GPIOI3,
97 110
98 { 64, 0x10, 8, 0, 14, 2 }, /* PCIC0 */ 111 /* interrupt groups */
99 { 65, 0x10, 0, 0, 15, 2 }, /* PCIC1 */ 112
100 { 66, 0x14, 24, 0, 16, 2 }, /* PCIC2 */ 113 RTC, TMU012, DMAC0, SCIF0, DMAC45, DMAC1,
101 { 67, 0x14, 16, 0, 17, 2 }, /* PCIC3 */ 114 PCIC5, SCIF1, MMCIF, TMU345, FLCTL, GPIO,
102 { 68, 0x14, 8, 0, 18, 2 }, /* PCIC4 */
103}; 115};
104 116
105static struct intc2_desc intc2_irq_desc __read_mostly = { 117static struct intc_vect vectors[] = {
106 .prio_base = 0xffd40000, 118 INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
107 .msk_base = 0xffd40038, 119 INTC_VECT(RTC_CUI, 0x4c0),
108 .mskclr_base = 0xffd4003c, 120 INTC_VECT(WDT, 0x560),
121 INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0),
122 INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0),
123 INTC_VECT(HUDI, 0x600),
124 INTC_VECT(DMAC0_DMINT0, 0x640), INTC_VECT(DMAC0_DMINT1, 0x660),
125 INTC_VECT(DMAC0_DMINT2, 0x680), INTC_VECT(DMAC0_DMINT3, 0x6a0),
126 INTC_VECT(DMAC0_DMAE, 0x6c0),
127 INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
128 INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
129 INTC_VECT(DMAC0_DMINT4, 0x780), INTC_VECT(DMAC0_DMINT5, 0x7a0),
130 INTC_VECT(DMAC1_DMINT6, 0x7c0), INTC_VECT(DMAC1_DMINT7, 0x7e0),
131 INTC_VECT(CMT, 0x900), INTC_VECT(HAC, 0x980),
132 INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20),
133 INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60),
134 INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIERR, 0xaa0),
135 INTC_VECT(PCIPWD3, 0xac0), INTC_VECT(PCIPWD2, 0xae0),
136 INTC_VECT(PCIPWD1, 0xb00), INTC_VECT(PCIPWD0, 0xb20),
137 INTC_VECT(SCIF1_ERI, 0xb80), INTC_VECT(SCIF1_RXI, 0xba0),
138 INTC_VECT(SCIF1_BRI, 0xbc0), INTC_VECT(SCIF1_TXI, 0xbe0),
139 INTC_VECT(SIOF, 0xc00), INTC_VECT(HSPI, 0xc80),
140 INTC_VECT(MMCIF_FSTAT, 0xd00), INTC_VECT(MMCIF_TRAN, 0xd20),
141 INTC_VECT(MMCIF_ERR, 0xd40), INTC_VECT(MMCIF_FRDY, 0xd60),
142 INTC_VECT(DMAC1_DMINT8, 0xd80), INTC_VECT(DMAC1_DMINT9, 0xda0),
143 INTC_VECT(DMAC1_DMINT10, 0xdc0), INTC_VECT(DMAC1_DMINT11, 0xde0),
144 INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
145 INTC_VECT(TMU5, 0xe40),
146 INTC_VECT(SSI, 0xe80),
147 INTC_VECT(FLCTL_FLSTE, 0xf00), INTC_VECT(FLCTL_FLEND, 0xf20),
148 INTC_VECT(FLCTL_FLTRQ0, 0xf40), INTC_VECT(FLCTL_FLTRQ1, 0xf60),
149 INTC_VECT(GPIOI0, 0xf80), INTC_VECT(GPIOI1, 0xfa0),
150 INTC_VECT(GPIOI2, 0xfc0), INTC_VECT(GPIOI3, 0xfe0),
151};
109 152
110 .intc2_data = intc2_irq_table, 153static struct intc_group groups[] = {
111 .nr_irqs = ARRAY_SIZE(intc2_irq_table), 154 INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
155 INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
156 INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
157 DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
158 INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
159 INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8,
160 DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11),
161 INTC_GROUP(PCIC5, PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0),
162 INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
163 INTC_GROUP(MMCIF, MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY),
164 INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
165 INTC_GROUP(FLCTL, FLCTL_FLSTE, FLCTL_FLEND,
166 FLCTL_FLTRQ0, FLCTL_FLTRQ1),
167 INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3),
168};
112 169
113 .chip = { 170static struct intc_prio priorities[] = {
114 .name = "INTC2-sh7780", 171 INTC_PRIO(SCIF0, 3),
115 }, 172 INTC_PRIO(SCIF1, 3),
173};
174
175static struct intc_mask_reg mask_registers[] = {
176 { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */
177 { 0, 0, 0, 0, 0, 0, GPIO, FLCTL,
178 SSI, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB,
179 PCIINTA, PCISERR, HAC, CMT, 0, 0, DMAC1, DMAC0,
180 HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } },
181};
182
183static struct intc_prio_reg prio_registers[] = {
184 { 0xffd40000, 32, 8, /* INT2PRI0 */ { TMU0, TMU1, TMU2, TMU2_TICPI } },
185 { 0xffd40004, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } },
186 { 0xffd40008, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } },
187 { 0xffd4000c, 32, 8, /* INT2PRI3 */ { HUDI, DMAC0, DMAC1 } },
188 { 0xffd40010, 32, 8, /* INT2PRI4 */ { CMT, HAC, PCISERR, PCIINTA, } },
189 { 0xffd40014, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC,
190 PCIINTD, PCIC5 } },
191 { 0xffd40018, 32, 8, /* INT2PRI6 */ { SIOF, HSPI, MMCIF, SSI } },
192 { 0xffd4001c, 32, 8, /* INT2PRI7 */ { FLCTL, GPIO } },
193};
194
195static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups, priorities,
196 mask_registers, prio_registers, NULL);
197
198/* Support for external interrupt pins in IRQ mode */
199
200static struct intc_vect irq_vectors[] = {
201 INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
202 INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
203 INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380),
204 INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200),
205};
206
207static struct intc_mask_reg irq_mask_registers[] = {
208 { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */
209 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
210};
211
212static struct intc_prio_reg irq_prio_registers[] = {
213 { 0xffd00010, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3,
214 IRQ4, IRQ5, IRQ6, IRQ7 } },
116}; 215};
117 216
217static struct intc_sense_reg irq_sense_registers[] = {
218 { 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3,
219 IRQ4, IRQ5, IRQ6, IRQ7 } },
220};
221
222static DECLARE_INTC_DESC(intc_irq_desc, "sh7780-irq", irq_vectors,
223 NULL, NULL, irq_mask_registers, irq_prio_registers,
224 irq_sense_registers);
225
226/* External interrupt pins in IRL mode */
227
228static struct intc_vect irl_vectors[] = {
229 INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
230 INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
231 INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
232 INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
233 INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
234 INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
235 INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
236 INTC_VECT(IRL_HHHL, 0x3c0),
237};
238
239static struct intc_mask_reg irl3210_mask_registers[] = {
240 { 0xffd00080, 0xffd00084, 32, /* INTMSK2 / INTMSKCLR2 */
241 { IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
242 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
243 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
244 IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
245};
246
247static struct intc_mask_reg irl7654_mask_registers[] = {
248 { 0xffd00080, 0xffd00084, 32, /* INTMSK2 / INTMSKCLR2 */
249 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
250 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
251 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
252 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
253 IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
254};
255
256static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7780-irl7654", irl_vectors,
257 NULL, NULL, irl7654_mask_registers, NULL, NULL);
258
259static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors,
260 NULL, NULL, irl3210_mask_registers, NULL, NULL);
261
118void __init plat_irq_setup(void) 262void __init plat_irq_setup(void)
119{ 263{
120 register_intc2_controller(&intc2_irq_desc); 264 register_intc_controller(&intc_desc);
265}
266
267void __init plat_irq_setup_pins(int mode)
268{
269 switch (mode) {
270 case IRQ_MODE_IRQ:
271 register_intc_controller(&intc_irq_desc);
272 break;
273 case IRQ_MODE_IRL7654:
274 register_intc_controller(&intc_irl7654_desc);
275 break;
276 case IRQ_MODE_IRL3210:
277 register_intc_controller(&intc_irl3210_desc);
278 break;
279 default:
280 BUG();
281 }
121} 282}