aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/common/locomo.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/common/locomo.c')
-rw-r--r--arch/arm/common/locomo.c268
1 files changed, 6 insertions, 262 deletions
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index 96cd0730167d..d8a1261f029c 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -133,36 +133,6 @@ static struct locomo_dev_info locomo_devices[] = {
133 }, 133 },
134}; 134};
135 135
136
137/** LoCoMo interrupt handling stuff.
138 * NOTE: LoCoMo has a 1 to many mapping on all of its IRQs.
139 * that is, there is only one real hardware interrupt
140 * we determine which interrupt it is by reading some IO memory.
141 * We have two levels of expansion, first in the handler for the
142 * hardware interrupt we generate an interrupt
143 * IRQ_LOCOMO_*_BASE and those handlers generate more interrupts
144 *
145 * hardware irq reads LOCOMO_ICR & 0x0f00
146 * IRQ_LOCOMO_KEY
147 * IRQ_LOCOMO_GPIO_BASE
148 * IRQ_LOCOMO_LT_BASE
149 * IRQ_LOCOMO_SPI_BASE
150 * IRQ_LOCOMO_GPIO_BASE reads LOCOMO_GIR & LOCOMO_GPD & 0xffff
151 * IRQ_LOCOMO_GPIO[0-15]
152 * IRQ_LOCOMO_LT_BASE reads LOCOMO_LTINT & 0x0001
153 * IRQ_LOCOMO_LT
154 * IRQ_LOCOMO_SPI_BASE reads LOCOMO_SPIIR & 0x000F
155 * IRQ_LOCOMO_SPI_RFR
156 * IRQ_LOCOMO_SPI_RFW
157 * IRQ_LOCOMO_SPI_OVRN
158 * IRQ_LOCOMO_SPI_TEND
159 */
160
161#define LOCOMO_IRQ_START (IRQ_LOCOMO_KEY)
162#define LOCOMO_IRQ_GPIO_START (IRQ_LOCOMO_GPIO0)
163#define LOCOMO_IRQ_LT_START (IRQ_LOCOMO_LT)
164#define LOCOMO_IRQ_SPI_START (IRQ_LOCOMO_SPI_RFR)
165
166static void locomo_handler(unsigned int irq, struct irq_desc *desc) 136static void locomo_handler(unsigned int irq, struct irq_desc *desc)
167{ 137{
168 int req, i; 138 int req, i;
@@ -176,7 +146,7 @@ static void locomo_handler(unsigned int irq, struct irq_desc *desc)
176 146
177 if (req) { 147 if (req) {
178 /* generate the next interrupt(s) */ 148 /* generate the next interrupt(s) */
179 irq = LOCOMO_IRQ_START; 149 irq = IRQ_LOCOMO_KEY;
180 for (i = 0; i <= 3; i++, irq++) { 150 for (i = 0; i <= 3; i++, irq++) {
181 if (req & (0x0100 << i)) { 151 if (req & (0x0100 << i)) {
182 generic_handle_irq(irq); 152 generic_handle_irq(irq);
@@ -195,7 +165,7 @@ static void locomo_mask_irq(unsigned int irq)
195 void __iomem *mapbase = get_irq_chip_data(irq); 165 void __iomem *mapbase = get_irq_chip_data(irq);
196 unsigned int r; 166 unsigned int r;
197 r = locomo_readl(mapbase + LOCOMO_ICR); 167 r = locomo_readl(mapbase + LOCOMO_ICR);
198 r &= ~(0x0010 << (irq - LOCOMO_IRQ_START)); 168 r &= ~(0x0010 << (irq - IRQ_LOCOMO_KEY));
199 locomo_writel(r, mapbase + LOCOMO_ICR); 169 locomo_writel(r, mapbase + LOCOMO_ICR);
200} 170}
201 171
@@ -204,7 +174,7 @@ static void locomo_unmask_irq(unsigned int irq)
204 void __iomem *mapbase = get_irq_chip_data(irq); 174 void __iomem *mapbase = get_irq_chip_data(irq);
205 unsigned int r; 175 unsigned int r;
206 r = locomo_readl(mapbase + LOCOMO_ICR); 176 r = locomo_readl(mapbase + LOCOMO_ICR);
207 r |= (0x0010 << (irq - LOCOMO_IRQ_START)); 177 r |= (0x0010 << (irq - IRQ_LOCOMO_KEY));
208 locomo_writel(r, mapbase + LOCOMO_ICR); 178 locomo_writel(r, mapbase + LOCOMO_ICR);
209} 179}
210 180
@@ -215,200 +185,6 @@ static struct irq_chip locomo_chip = {
215 .unmask = locomo_unmask_irq, 185 .unmask = locomo_unmask_irq,
216}; 186};
217 187
218static void locomo_gpio_handler(unsigned int irq, struct irq_desc *desc)
219{
220 int req, i;
221 void __iomem *mapbase = get_irq_chip_data(irq);
222
223 req = locomo_readl(mapbase + LOCOMO_GIR) &
224 locomo_readl(mapbase + LOCOMO_GPD) &
225 0xffff;
226
227 if (req) {
228 irq = LOCOMO_IRQ_GPIO_START;
229 for (i = 0; i <= 15; i++, irq++) {
230 if (req & (0x0001 << i)) {
231 generic_handle_irq(irq);
232 }
233 }
234 }
235}
236
237static void locomo_gpio_ack_irq(unsigned int irq)
238{
239 void __iomem *mapbase = get_irq_chip_data(irq);
240 unsigned int r;
241 r = locomo_readl(mapbase + LOCOMO_GWE);
242 r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
243 locomo_writel(r, mapbase + LOCOMO_GWE);
244
245 r = locomo_readl(mapbase + LOCOMO_GIS);
246 r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
247 locomo_writel(r, mapbase + LOCOMO_GIS);
248
249 r = locomo_readl(mapbase + LOCOMO_GWE);
250 r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
251 locomo_writel(r, mapbase + LOCOMO_GWE);
252}
253
254static void locomo_gpio_mask_irq(unsigned int irq)
255{
256 void __iomem *mapbase = get_irq_chip_data(irq);
257 unsigned int r;
258 r = locomo_readl(mapbase + LOCOMO_GIE);
259 r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
260 locomo_writel(r, mapbase + LOCOMO_GIE);
261}
262
263static void locomo_gpio_unmask_irq(unsigned int irq)
264{
265 void __iomem *mapbase = get_irq_chip_data(irq);
266 unsigned int r;
267 r = locomo_readl(mapbase + LOCOMO_GIE);
268 r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
269 locomo_writel(r, mapbase + LOCOMO_GIE);
270}
271
272static int GPIO_IRQ_rising_edge;
273static int GPIO_IRQ_falling_edge;
274
275static int locomo_gpio_type(unsigned int irq, unsigned int type)
276{
277 unsigned int mask;
278 void __iomem *mapbase = get_irq_chip_data(irq);
279
280 mask = 1 << (irq - LOCOMO_IRQ_GPIO_START);
281
282 if (type == IRQ_TYPE_PROBE) {
283 if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask)
284 return 0;
285 type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
286 }
287
288 if (type & IRQ_TYPE_EDGE_RISING)
289 GPIO_IRQ_rising_edge |= mask;
290 else
291 GPIO_IRQ_rising_edge &= ~mask;
292 if (type & IRQ_TYPE_EDGE_FALLING)
293 GPIO_IRQ_falling_edge |= mask;
294 else
295 GPIO_IRQ_falling_edge &= ~mask;
296 locomo_writel(GPIO_IRQ_rising_edge, mapbase + LOCOMO_GRIE);
297 locomo_writel(GPIO_IRQ_falling_edge, mapbase + LOCOMO_GFIE);
298
299 return 0;
300}
301
302static struct irq_chip locomo_gpio_chip = {
303 .name = "LOCOMO-gpio",
304 .ack = locomo_gpio_ack_irq,
305 .mask = locomo_gpio_mask_irq,
306 .unmask = locomo_gpio_unmask_irq,
307 .set_type = locomo_gpio_type,
308};
309
310static void locomo_lt_handler(unsigned int irq, struct irq_desc *desc)
311{
312 void __iomem *mapbase = get_irq_chip_data(irq);
313
314 if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) {
315 generic_handle_irq(LOCOMO_IRQ_LT_START);
316 }
317}
318
319static void locomo_lt_ack_irq(unsigned int irq)
320{
321 void __iomem *mapbase = get_irq_chip_data(irq);
322 unsigned int r;
323 r = locomo_readl(mapbase + LOCOMO_LTINT);
324 r &= ~(0x0100 << (irq - LOCOMO_IRQ_LT_START));
325 locomo_writel(r, mapbase + LOCOMO_LTINT);
326}
327
328static void locomo_lt_mask_irq(unsigned int irq)
329{
330 void __iomem *mapbase = get_irq_chip_data(irq);
331 unsigned int r;
332 r = locomo_readl(mapbase + LOCOMO_LTINT);
333 r &= ~(0x0010 << (irq - LOCOMO_IRQ_LT_START));
334 locomo_writel(r, mapbase + LOCOMO_LTINT);
335}
336
337static void locomo_lt_unmask_irq(unsigned int irq)
338{
339 void __iomem *mapbase = get_irq_chip_data(irq);
340 unsigned int r;
341 r = locomo_readl(mapbase + LOCOMO_LTINT);
342 r |= (0x0010 << (irq - LOCOMO_IRQ_LT_START));
343 locomo_writel(r, mapbase + LOCOMO_LTINT);
344}
345
346static struct irq_chip locomo_lt_chip = {
347 .name = "LOCOMO-lt",
348 .ack = locomo_lt_ack_irq,
349 .mask = locomo_lt_mask_irq,
350 .unmask = locomo_lt_unmask_irq,
351};
352
353static void locomo_spi_handler(unsigned int irq, struct irq_desc *desc)
354{
355 int req, i;
356 void __iomem *mapbase = get_irq_chip_data(irq);
357
358 req = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIR) & 0x000F;
359 if (req) {
360 irq = LOCOMO_IRQ_SPI_START;
361
362 for (i = 0; i <= 3; i++, irq++) {
363 if (req & (0x0001 << i)) {
364 generic_handle_irq(irq);
365 }
366 }
367 }
368}
369
370static void locomo_spi_ack_irq(unsigned int irq)
371{
372 void __iomem *mapbase = get_irq_chip_data(irq);
373 unsigned int r;
374 r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
375 r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START));
376 locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
377
378 r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIS);
379 r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START));
380 locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIS);
381
382 r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
383 r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START));
384 locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
385}
386
387static void locomo_spi_mask_irq(unsigned int irq)
388{
389 void __iomem *mapbase = get_irq_chip_data(irq);
390 unsigned int r;
391 r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
392 r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START));
393 locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
394}
395
396static void locomo_spi_unmask_irq(unsigned int irq)
397{
398 void __iomem *mapbase = get_irq_chip_data(irq);
399 unsigned int r;
400 r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
401 r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START));
402 locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
403}
404
405static struct irq_chip locomo_spi_chip = {
406 .name = "LOCOMO-spi",
407 .ack = locomo_spi_ack_irq,
408 .mask = locomo_spi_mask_irq,
409 .unmask = locomo_spi_unmask_irq,
410};
411
412static void locomo_setup_irq(struct locomo *lchip) 188static void locomo_setup_irq(struct locomo *lchip)
413{ 189{
414 int irq; 190 int irq;
@@ -421,41 +197,9 @@ static void locomo_setup_irq(struct locomo *lchip)
421 set_irq_chip_data(lchip->irq, irqbase); 197 set_irq_chip_data(lchip->irq, irqbase);
422 set_irq_chained_handler(lchip->irq, locomo_handler); 198 set_irq_chained_handler(lchip->irq, locomo_handler);
423 199
424 /* Install handlers for IRQ_LOCOMO_*_BASE */ 200 /* install handlers for IRQ_LOCOMO_* */
425 set_irq_chip(IRQ_LOCOMO_KEY, &locomo_chip); 201 for (irq = IRQ_LOCOMO_KEY; irq < IRQ_LOCOMO_KEY + 4; irq++) {
426 set_irq_chip_data(IRQ_LOCOMO_KEY, irqbase); 202 set_irq_chip(irq, &locomo_chip);
427 set_irq_handler(IRQ_LOCOMO_KEY, handle_edge_irq);
428 set_irq_flags(IRQ_LOCOMO_KEY, IRQF_VALID | IRQF_PROBE);
429
430 set_irq_chip(IRQ_LOCOMO_GPIO_BASE, &locomo_chip);
431 set_irq_chip_data(IRQ_LOCOMO_GPIO_BASE, irqbase);
432 set_irq_chained_handler(IRQ_LOCOMO_GPIO_BASE, locomo_gpio_handler);
433
434 set_irq_chip(IRQ_LOCOMO_LT_BASE, &locomo_chip);
435 set_irq_chip_data(IRQ_LOCOMO_LT_BASE, irqbase);
436 set_irq_chained_handler(IRQ_LOCOMO_LT_BASE, locomo_lt_handler);
437
438 set_irq_chip(IRQ_LOCOMO_SPI_BASE, &locomo_chip);
439 set_irq_chip_data(IRQ_LOCOMO_SPI_BASE, irqbase);
440 set_irq_chained_handler(IRQ_LOCOMO_SPI_BASE, locomo_spi_handler);
441
442 /* install handlers for IRQ_LOCOMO_GPIO_BASE generated interrupts */
443 for (irq = LOCOMO_IRQ_GPIO_START; irq < LOCOMO_IRQ_GPIO_START + 16; irq++) {
444 set_irq_chip(irq, &locomo_gpio_chip);
445 set_irq_chip_data(irq, irqbase);
446 set_irq_handler(irq, handle_edge_irq);
447 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
448 }
449
450 /* install handlers for IRQ_LOCOMO_LT_BASE generated interrupts */
451 set_irq_chip(LOCOMO_IRQ_LT_START, &locomo_lt_chip);
452 set_irq_chip_data(LOCOMO_IRQ_LT_START, irqbase);
453 set_irq_handler(LOCOMO_IRQ_LT_START, handle_edge_irq);
454 set_irq_flags(LOCOMO_IRQ_LT_START, IRQF_VALID | IRQF_PROBE);
455
456 /* install handlers for IRQ_LOCOMO_SPI_BASE generated interrupts */
457 for (irq = LOCOMO_IRQ_SPI_START; irq < LOCOMO_IRQ_SPI_START + 4; irq++) {
458 set_irq_chip(irq, &locomo_spi_chip);
459 set_irq_chip_data(irq, irqbase); 203 set_irq_chip_data(irq, irqbase);
460 set_irq_handler(irq, handle_edge_irq); 204 set_irq_handler(irq, handle_edge_irq);
461 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 205 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);