diff options
Diffstat (limited to 'arch/arm/common/locomo.c')
-rw-r--r-- | arch/arm/common/locomo.c | 268 |
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 | |||
166 | static void locomo_handler(unsigned int irq, struct irq_desc *desc) | 136 | static 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 | ||
218 | static 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 | |||
237 | static 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 | |||
254 | static 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 | |||
263 | static 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 | |||
272 | static int GPIO_IRQ_rising_edge; | ||
273 | static int GPIO_IRQ_falling_edge; | ||
274 | |||
275 | static 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 | |||
302 | static 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 | |||
310 | static 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 | |||
319 | static 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 | |||
328 | static 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 | |||
337 | static 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 | |||
346 | static 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 | |||
353 | static 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 | |||
370 | static 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 | |||
387 | static 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 | |||
396 | static 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 | |||
405 | static 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 | |||
412 | static void locomo_setup_irq(struct locomo *lchip) | 188 | static 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); |