diff options
Diffstat (limited to 'arch/blackfin/mach-common/ints-priority.c')
-rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 541 |
1 files changed, 368 insertions, 173 deletions
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 34e8a726ffda..1bba6030dce9 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c | |||
@@ -1,9 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * File: arch/blackfin/mach-common/ints-priority.c | 2 | * File: arch/blackfin/mach-common/ints-priority.c |
3 | * Based on: | ||
4 | * Author: | ||
5 | * | 3 | * |
6 | * Created: ? | ||
7 | * Description: Set up the interrupt priorities | 4 | * Description: Set up the interrupt priorities |
8 | * | 5 | * |
9 | * Modified: | 6 | * Modified: |
@@ -37,6 +34,9 @@ | |||
37 | #include <linux/kernel_stat.h> | 34 | #include <linux/kernel_stat.h> |
38 | #include <linux/seq_file.h> | 35 | #include <linux/seq_file.h> |
39 | #include <linux/irq.h> | 36 | #include <linux/irq.h> |
37 | #ifdef CONFIG_IPIPE | ||
38 | #include <linux/ipipe.h> | ||
39 | #endif | ||
40 | #ifdef CONFIG_KGDB | 40 | #ifdef CONFIG_KGDB |
41 | #include <linux/kgdb.h> | 41 | #include <linux/kgdb.h> |
42 | #endif | 42 | #endif |
@@ -45,6 +45,8 @@ | |||
45 | #include <asm/gpio.h> | 45 | #include <asm/gpio.h> |
46 | #include <asm/irq_handler.h> | 46 | #include <asm/irq_handler.h> |
47 | 47 | ||
48 | #define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) | ||
49 | |||
48 | #ifdef BF537_FAMILY | 50 | #ifdef BF537_FAMILY |
49 | # define BF537_GENERIC_ERROR_INT_DEMUX | 51 | # define BF537_GENERIC_ERROR_INT_DEMUX |
50 | #else | 52 | #else |
@@ -58,13 +60,16 @@ | |||
58 | * - | 60 | * - |
59 | */ | 61 | */ |
60 | 62 | ||
63 | #ifndef CONFIG_SMP | ||
61 | /* Initialize this to an actual value to force it into the .data | 64 | /* Initialize this to an actual value to force it into the .data |
62 | * section so that we know it is properly initialized at entry into | 65 | * section so that we know it is properly initialized at entry into |
63 | * the kernel but before bss is initialized to zero (which is where | 66 | * the kernel but before bss is initialized to zero (which is where |
64 | * it would live otherwise). The 0x1f magic represents the IRQs we | 67 | * it would live otherwise). The 0x1f magic represents the IRQs we |
65 | * cannot actually mask out in hardware. | 68 | * cannot actually mask out in hardware. |
66 | */ | 69 | */ |
67 | unsigned long irq_flags = 0x1f; | 70 | unsigned long bfin_irq_flags = 0x1f; |
71 | EXPORT_SYMBOL(bfin_irq_flags); | ||
72 | #endif | ||
68 | 73 | ||
69 | /* The number of spurious interrupts */ | 74 | /* The number of spurious interrupts */ |
70 | atomic_t num_spurious; | 75 | atomic_t num_spurious; |
@@ -103,12 +108,14 @@ static void __init search_IAR(void) | |||
103 | for (irqn = 0; irqn < NR_PERI_INTS; irqn++) { | 108 | for (irqn = 0; irqn < NR_PERI_INTS; irqn++) { |
104 | int iar_shift = (irqn & 7) * 4; | 109 | int iar_shift = (irqn & 7) * 4; |
105 | if (ivg == (0xf & | 110 | if (ivg == (0xf & |
106 | #ifndef CONFIG_BF52x | 111 | #if defined(CONFIG_BF52x) || defined(CONFIG_BF538) \ |
112 | || defined(CONFIG_BF539) || defined(CONFIG_BF51x) | ||
107 | bfin_read32((unsigned long *)SIC_IAR0 + | 113 | bfin_read32((unsigned long *)SIC_IAR0 + |
108 | (irqn >> 3)) >> iar_shift)) { | 114 | ((irqn % 32) >> 3) + ((irqn / 32) * |
115 | ((SIC_IAR4 - SIC_IAR0) / 4))) >> iar_shift)) { | ||
109 | #else | 116 | #else |
110 | bfin_read32((unsigned long *)SIC_IAR0 + | 117 | bfin_read32((unsigned long *)SIC_IAR0 + |
111 | ((irqn%32) >> 3) + ((irqn / 32) * 16)) >> iar_shift)) { | 118 | (irqn >> 3)) >> iar_shift)) { |
112 | #endif | 119 | #endif |
113 | ivg_table[irq_pos].irqno = IVG7 + irqn; | 120 | ivg_table[irq_pos].irqno = IVG7 + irqn; |
114 | ivg_table[irq_pos].isrflag = 1 << (irqn % 32); | 121 | ivg_table[irq_pos].isrflag = 1 << (irqn % 32); |
@@ -130,25 +137,25 @@ static void bfin_ack_noop(unsigned int irq) | |||
130 | 137 | ||
131 | static void bfin_core_mask_irq(unsigned int irq) | 138 | static void bfin_core_mask_irq(unsigned int irq) |
132 | { | 139 | { |
133 | irq_flags &= ~(1 << irq); | 140 | bfin_irq_flags &= ~(1 << irq); |
134 | if (!irqs_disabled()) | 141 | if (!irqs_disabled_hw()) |
135 | local_irq_enable(); | 142 | local_irq_enable_hw(); |
136 | } | 143 | } |
137 | 144 | ||
138 | static void bfin_core_unmask_irq(unsigned int irq) | 145 | static void bfin_core_unmask_irq(unsigned int irq) |
139 | { | 146 | { |
140 | irq_flags |= 1 << irq; | 147 | bfin_irq_flags |= 1 << irq; |
141 | /* | 148 | /* |
142 | * If interrupts are enabled, IMASK must contain the same value | 149 | * If interrupts are enabled, IMASK must contain the same value |
143 | * as irq_flags. Make sure that invariant holds. If interrupts | 150 | * as bfin_irq_flags. Make sure that invariant holds. If interrupts |
144 | * are currently disabled we need not do anything; one of the | 151 | * are currently disabled we need not do anything; one of the |
145 | * callers will take care of setting IMASK to the proper value | 152 | * callers will take care of setting IMASK to the proper value |
146 | * when reenabling interrupts. | 153 | * when reenabling interrupts. |
147 | * local_irq_enable just does "STI irq_flags", so it's exactly | 154 | * local_irq_enable just does "STI bfin_irq_flags", so it's exactly |
148 | * what we need. | 155 | * what we need. |
149 | */ | 156 | */ |
150 | if (!irqs_disabled()) | 157 | if (!irqs_disabled_hw()) |
151 | local_irq_enable(); | 158 | local_irq_enable_hw(); |
152 | return; | 159 | return; |
153 | } | 160 | } |
154 | 161 | ||
@@ -163,8 +170,11 @@ static void bfin_internal_mask_irq(unsigned int irq) | |||
163 | mask_bit = SIC_SYSIRQ(irq) % 32; | 170 | mask_bit = SIC_SYSIRQ(irq) % 32; |
164 | bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) & | 171 | bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) & |
165 | ~(1 << mask_bit)); | 172 | ~(1 << mask_bit)); |
173 | #ifdef CONFIG_SMP | ||
174 | bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) & | ||
175 | ~(1 << mask_bit)); | ||
176 | #endif | ||
166 | #endif | 177 | #endif |
167 | SSYNC(); | ||
168 | } | 178 | } |
169 | 179 | ||
170 | static void bfin_internal_unmask_irq(unsigned int irq) | 180 | static void bfin_internal_unmask_irq(unsigned int irq) |
@@ -178,14 +188,17 @@ static void bfin_internal_unmask_irq(unsigned int irq) | |||
178 | mask_bit = SIC_SYSIRQ(irq) % 32; | 188 | mask_bit = SIC_SYSIRQ(irq) % 32; |
179 | bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) | | 189 | bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) | |
180 | (1 << mask_bit)); | 190 | (1 << mask_bit)); |
191 | #ifdef CONFIG_SMP | ||
192 | bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) | | ||
193 | (1 << mask_bit)); | ||
194 | #endif | ||
181 | #endif | 195 | #endif |
182 | SSYNC(); | ||
183 | } | 196 | } |
184 | 197 | ||
185 | #ifdef CONFIG_PM | 198 | #ifdef CONFIG_PM |
186 | int bfin_internal_set_wake(unsigned int irq, unsigned int state) | 199 | int bfin_internal_set_wake(unsigned int irq, unsigned int state) |
187 | { | 200 | { |
188 | unsigned bank, bit, wakeup = 0; | 201 | u32 bank, bit, wakeup = 0; |
189 | unsigned long flags; | 202 | unsigned long flags; |
190 | bank = SIC_SYSIRQ(irq) / 32; | 203 | bank = SIC_SYSIRQ(irq) / 32; |
191 | bit = SIC_SYSIRQ(irq) % 32; | 204 | bit = SIC_SYSIRQ(irq) % 32; |
@@ -225,7 +238,7 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state) | |||
225 | break; | 238 | break; |
226 | } | 239 | } |
227 | 240 | ||
228 | local_irq_save(flags); | 241 | local_irq_save_hw(flags); |
229 | 242 | ||
230 | if (state) { | 243 | if (state) { |
231 | bfin_sic_iwr[bank] |= (1 << bit); | 244 | bfin_sic_iwr[bank] |= (1 << bit); |
@@ -236,7 +249,7 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state) | |||
236 | vr_wakeup &= ~wakeup; | 249 | vr_wakeup &= ~wakeup; |
237 | } | 250 | } |
238 | 251 | ||
239 | local_irq_restore(flags); | 252 | local_irq_restore_hw(flags); |
240 | 253 | ||
241 | return 0; | 254 | return 0; |
242 | } | 255 | } |
@@ -262,6 +275,19 @@ static struct irq_chip bfin_internal_irqchip = { | |||
262 | #endif | 275 | #endif |
263 | }; | 276 | }; |
264 | 277 | ||
278 | static void bfin_handle_irq(unsigned irq) | ||
279 | { | ||
280 | #ifdef CONFIG_IPIPE | ||
281 | struct pt_regs regs; /* Contents not used. */ | ||
282 | ipipe_trace_irq_entry(irq); | ||
283 | __ipipe_handle_irq(irq, ®s); | ||
284 | ipipe_trace_irq_exit(irq); | ||
285 | #else /* !CONFIG_IPIPE */ | ||
286 | struct irq_desc *desc = irq_desc + irq; | ||
287 | desc->handle_irq(irq, desc); | ||
288 | #endif /* !CONFIG_IPIPE */ | ||
289 | } | ||
290 | |||
265 | #ifdef BF537_GENERIC_ERROR_INT_DEMUX | 291 | #ifdef BF537_GENERIC_ERROR_INT_DEMUX |
266 | static int error_int_mask; | 292 | static int error_int_mask; |
267 | 293 | ||
@@ -292,8 +318,6 @@ static void bfin_demux_error_irq(unsigned int int_err_irq, | |||
292 | { | 318 | { |
293 | int irq = 0; | 319 | int irq = 0; |
294 | 320 | ||
295 | SSYNC(); | ||
296 | |||
297 | #if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) | 321 | #if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) |
298 | if (bfin_read_EMAC_SYSTAT() & EMAC_ERR_MASK) | 322 | if (bfin_read_EMAC_SYSTAT() & EMAC_ERR_MASK) |
299 | irq = IRQ_MAC_ERROR; | 323 | irq = IRQ_MAC_ERROR; |
@@ -317,10 +341,9 @@ static void bfin_demux_error_irq(unsigned int int_err_irq, | |||
317 | irq = IRQ_UART1_ERROR; | 341 | irq = IRQ_UART1_ERROR; |
318 | 342 | ||
319 | if (irq) { | 343 | if (irq) { |
320 | if (error_int_mask & (1L << (irq - IRQ_PPI_ERROR))) { | 344 | if (error_int_mask & (1L << (irq - IRQ_PPI_ERROR))) |
321 | struct irq_desc *desc = irq_desc + irq; | 345 | bfin_handle_irq(irq); |
322 | desc->handle_irq(irq, desc); | 346 | else { |
323 | } else { | ||
324 | 347 | ||
325 | switch (irq) { | 348 | switch (irq) { |
326 | case IRQ_PPI_ERROR: | 349 | case IRQ_PPI_ERROR: |
@@ -366,62 +389,57 @@ static void bfin_demux_error_irq(unsigned int int_err_irq, | |||
366 | 389 | ||
367 | static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle) | 390 | static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle) |
368 | { | 391 | { |
392 | #ifdef CONFIG_IPIPE | ||
393 | _set_irq_handler(irq, handle_edge_irq); | ||
394 | #else | ||
369 | struct irq_desc *desc = irq_desc + irq; | 395 | struct irq_desc *desc = irq_desc + irq; |
370 | /* May not call generic set_irq_handler() due to spinlock | 396 | /* May not call generic set_irq_handler() due to spinlock |
371 | recursion. */ | 397 | recursion. */ |
372 | desc->handle_irq = handle; | 398 | desc->handle_irq = handle; |
399 | #endif | ||
373 | } | 400 | } |
374 | 401 | ||
375 | #if !defined(CONFIG_BF54x) | 402 | static DECLARE_BITMAP(gpio_enabled, MAX_BLACKFIN_GPIOS); |
376 | |||
377 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; | ||
378 | static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; | ||
379 | |||
380 | extern void bfin_gpio_irq_prepare(unsigned gpio); | 403 | extern void bfin_gpio_irq_prepare(unsigned gpio); |
381 | 404 | ||
405 | #if !defined(CONFIG_BF54x) | ||
406 | |||
382 | static void bfin_gpio_ack_irq(unsigned int irq) | 407 | static void bfin_gpio_ack_irq(unsigned int irq) |
383 | { | 408 | { |
384 | u16 gpionr = irq - IRQ_PF0; | 409 | /* AFAIK ack_irq in case mask_ack is provided |
385 | 410 | * get's only called for edge sense irqs | |
386 | if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) { | 411 | */ |
387 | set_gpio_data(gpionr, 0); | 412 | set_gpio_data(irq_to_gpio(irq), 0); |
388 | SSYNC(); | ||
389 | } | ||
390 | } | 413 | } |
391 | 414 | ||
392 | static void bfin_gpio_mask_ack_irq(unsigned int irq) | 415 | static void bfin_gpio_mask_ack_irq(unsigned int irq) |
393 | { | 416 | { |
394 | u16 gpionr = irq - IRQ_PF0; | 417 | struct irq_desc *desc = irq_desc + irq; |
418 | u32 gpionr = irq_to_gpio(irq); | ||
395 | 419 | ||
396 | if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) { | 420 | if (desc->handle_irq == handle_edge_irq) |
397 | set_gpio_data(gpionr, 0); | 421 | set_gpio_data(gpionr, 0); |
398 | SSYNC(); | ||
399 | } | ||
400 | 422 | ||
401 | set_gpio_maska(gpionr, 0); | 423 | set_gpio_maska(gpionr, 0); |
402 | SSYNC(); | ||
403 | } | 424 | } |
404 | 425 | ||
405 | static void bfin_gpio_mask_irq(unsigned int irq) | 426 | static void bfin_gpio_mask_irq(unsigned int irq) |
406 | { | 427 | { |
407 | set_gpio_maska(irq - IRQ_PF0, 0); | 428 | set_gpio_maska(irq_to_gpio(irq), 0); |
408 | SSYNC(); | ||
409 | } | 429 | } |
410 | 430 | ||
411 | static void bfin_gpio_unmask_irq(unsigned int irq) | 431 | static void bfin_gpio_unmask_irq(unsigned int irq) |
412 | { | 432 | { |
413 | set_gpio_maska(irq - IRQ_PF0, 1); | 433 | set_gpio_maska(irq_to_gpio(irq), 1); |
414 | SSYNC(); | ||
415 | } | 434 | } |
416 | 435 | ||
417 | static unsigned int bfin_gpio_irq_startup(unsigned int irq) | 436 | static unsigned int bfin_gpio_irq_startup(unsigned int irq) |
418 | { | 437 | { |
419 | u16 gpionr = irq - IRQ_PF0; | 438 | u32 gpionr = irq_to_gpio(irq); |
420 | 439 | ||
421 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) | 440 | if (__test_and_set_bit(gpionr, gpio_enabled)) |
422 | bfin_gpio_irq_prepare(gpionr); | 441 | bfin_gpio_irq_prepare(gpionr); |
423 | 442 | ||
424 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); | ||
425 | bfin_gpio_unmask_irq(irq); | 443 | bfin_gpio_unmask_irq(irq); |
426 | 444 | ||
427 | return 0; | 445 | return 0; |
@@ -429,29 +447,39 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq) | |||
429 | 447 | ||
430 | static void bfin_gpio_irq_shutdown(unsigned int irq) | 448 | static void bfin_gpio_irq_shutdown(unsigned int irq) |
431 | { | 449 | { |
450 | u32 gpionr = irq_to_gpio(irq); | ||
451 | |||
432 | bfin_gpio_mask_irq(irq); | 452 | bfin_gpio_mask_irq(irq); |
433 | gpio_enabled[gpio_bank(irq - IRQ_PF0)] &= ~gpio_bit(irq - IRQ_PF0); | 453 | __clear_bit(gpionr, gpio_enabled); |
454 | bfin_gpio_irq_free(gpionr); | ||
434 | } | 455 | } |
435 | 456 | ||
436 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | 457 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) |
437 | { | 458 | { |
438 | u16 gpionr = irq - IRQ_PF0; | 459 | int ret; |
460 | char buf[16]; | ||
461 | u32 gpionr = irq_to_gpio(irq); | ||
439 | 462 | ||
440 | if (type == IRQ_TYPE_PROBE) { | 463 | if (type == IRQ_TYPE_PROBE) { |
441 | /* only probe unenabled GPIO interrupt lines */ | 464 | /* only probe unenabled GPIO interrupt lines */ |
442 | if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr)) | 465 | if (__test_bit(gpionr, gpio_enabled)) |
443 | return 0; | 466 | return 0; |
444 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; | 467 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; |
445 | } | 468 | } |
446 | 469 | ||
447 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | | 470 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | |
448 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { | 471 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { |
449 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) | 472 | |
473 | snprintf(buf, 16, "gpio-irq%d", irq); | ||
474 | ret = bfin_gpio_irq_request(gpionr, buf); | ||
475 | if (ret) | ||
476 | return ret; | ||
477 | |||
478 | if (__test_and_set_bit(gpionr, gpio_enabled)) | ||
450 | bfin_gpio_irq_prepare(gpionr); | 479 | bfin_gpio_irq_prepare(gpionr); |
451 | 480 | ||
452 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); | ||
453 | } else { | 481 | } else { |
454 | gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); | 482 | __clear_bit(gpionr, gpio_enabled); |
455 | return 0; | 483 | return 0; |
456 | } | 484 | } |
457 | 485 | ||
@@ -472,17 +500,13 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
472 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { | 500 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { |
473 | set_gpio_edge(gpionr, 1); | 501 | set_gpio_edge(gpionr, 1); |
474 | set_gpio_inen(gpionr, 1); | 502 | set_gpio_inen(gpionr, 1); |
475 | gpio_edge_triggered[gpio_bank(gpionr)] |= gpio_bit(gpionr); | ||
476 | set_gpio_data(gpionr, 0); | 503 | set_gpio_data(gpionr, 0); |
477 | 504 | ||
478 | } else { | 505 | } else { |
479 | set_gpio_edge(gpionr, 0); | 506 | set_gpio_edge(gpionr, 0); |
480 | gpio_edge_triggered[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); | ||
481 | set_gpio_inen(gpionr, 1); | 507 | set_gpio_inen(gpionr, 1); |
482 | } | 508 | } |
483 | 509 | ||
484 | SSYNC(); | ||
485 | |||
486 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) | 510 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) |
487 | bfin_set_irq_handler(irq, handle_edge_irq); | 511 | bfin_set_irq_handler(irq, handle_edge_irq); |
488 | else | 512 | else |
@@ -505,22 +529,6 @@ int bfin_gpio_set_wake(unsigned int irq, unsigned int state) | |||
505 | } | 529 | } |
506 | #endif | 530 | #endif |
507 | 531 | ||
508 | static struct irq_chip bfin_gpio_irqchip = { | ||
509 | .name = "GPIO", | ||
510 | .ack = bfin_gpio_ack_irq, | ||
511 | .mask = bfin_gpio_mask_irq, | ||
512 | .mask_ack = bfin_gpio_mask_ack_irq, | ||
513 | .unmask = bfin_gpio_unmask_irq, | ||
514 | .disable = bfin_gpio_mask_irq, | ||
515 | .enable = bfin_gpio_unmask_irq, | ||
516 | .set_type = bfin_gpio_irq_type, | ||
517 | .startup = bfin_gpio_irq_startup, | ||
518 | .shutdown = bfin_gpio_irq_shutdown, | ||
519 | #ifdef CONFIG_PM | ||
520 | .set_wake = bfin_gpio_set_wake, | ||
521 | #endif | ||
522 | }; | ||
523 | |||
524 | static void bfin_demux_gpio_irq(unsigned int inta_irq, | 532 | static void bfin_demux_gpio_irq(unsigned int inta_irq, |
525 | struct irq_desc *desc) | 533 | struct irq_desc *desc) |
526 | { | 534 | { |
@@ -537,7 +545,11 @@ static void bfin_demux_gpio_irq(unsigned int inta_irq, | |||
537 | irq = IRQ_PH0; | 545 | irq = IRQ_PH0; |
538 | break; | 546 | break; |
539 | # endif | 547 | # endif |
540 | #elif defined(CONFIG_BF52x) | 548 | #elif defined(CONFIG_BF538) || defined(CONFIG_BF539) |
549 | case IRQ_PORTF_INTA: | ||
550 | irq = IRQ_PF0; | ||
551 | break; | ||
552 | #elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x) | ||
541 | case IRQ_PORTF_INTA: | 553 | case IRQ_PORTF_INTA: |
542 | irq = IRQ_PF0; | 554 | irq = IRQ_PF0; |
543 | break; | 555 | break; |
@@ -567,30 +579,22 @@ static void bfin_demux_gpio_irq(unsigned int inta_irq, | |||
567 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { | 579 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { |
568 | irq += i; | 580 | irq += i; |
569 | 581 | ||
570 | mask = get_gpiop_data(i) & | 582 | mask = get_gpiop_data(i) & get_gpiop_maska(i); |
571 | (gpio_enabled[gpio_bank(i)] & | ||
572 | get_gpiop_maska(i)); | ||
573 | 583 | ||
574 | while (mask) { | 584 | while (mask) { |
575 | if (mask & 1) { | 585 | if (mask & 1) |
576 | desc = irq_desc + irq; | 586 | bfin_handle_irq(irq); |
577 | desc->handle_irq(irq, desc); | ||
578 | } | ||
579 | irq++; | 587 | irq++; |
580 | mask >>= 1; | 588 | mask >>= 1; |
581 | } | 589 | } |
582 | } | 590 | } |
583 | } else { | 591 | } else { |
584 | gpio = irq_to_gpio(irq); | 592 | gpio = irq_to_gpio(irq); |
585 | mask = get_gpiop_data(gpio) & | 593 | mask = get_gpiop_data(gpio) & get_gpiop_maska(gpio); |
586 | (gpio_enabled[gpio_bank(gpio)] & | ||
587 | get_gpiop_maska(gpio)); | ||
588 | 594 | ||
589 | do { | 595 | do { |
590 | if (mask & 1) { | 596 | if (mask & 1) |
591 | desc = irq_desc + irq; | 597 | bfin_handle_irq(irq); |
592 | desc->handle_irq(irq, desc); | ||
593 | } | ||
594 | irq++; | 598 | irq++; |
595 | mask >>= 1; | 599 | mask >>= 1; |
596 | } while (mask); | 600 | } while (mask); |
@@ -612,10 +616,6 @@ static void bfin_demux_gpio_irq(unsigned int inta_irq, | |||
612 | static unsigned char irq2pint_lut[NR_PINTS]; | 616 | static unsigned char irq2pint_lut[NR_PINTS]; |
613 | static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS]; | 617 | static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS]; |
614 | 618 | ||
615 | static unsigned int gpio_both_edge_triggered[NR_PINT_SYS_IRQS]; | ||
616 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; | ||
617 | |||
618 | |||
619 | struct pin_int_t { | 619 | struct pin_int_t { |
620 | unsigned int mask_set; | 620 | unsigned int mask_set; |
621 | unsigned int mask_clear; | 621 | unsigned int mask_clear; |
@@ -636,12 +636,9 @@ static struct pin_int_t *pint[NR_PINT_SYS_IRQS] = { | |||
636 | (struct pin_int_t *)PINT3_MASK_SET, | 636 | (struct pin_int_t *)PINT3_MASK_SET, |
637 | }; | 637 | }; |
638 | 638 | ||
639 | extern void bfin_gpio_irq_prepare(unsigned gpio); | 639 | inline unsigned int get_irq_base(u32 bank, u8 bmap) |
640 | |||
641 | inline unsigned short get_irq_base(u8 bank, u8 bmap) | ||
642 | { | 640 | { |
643 | 641 | unsigned int irq_base; | |
644 | u16 irq_base; | ||
645 | 642 | ||
646 | if (bank < 2) { /*PA-PB */ | 643 | if (bank < 2) { /*PA-PB */ |
647 | irq_base = IRQ_PA0 + bmap * 16; | 644 | irq_base = IRQ_PA0 + bmap * 16; |
@@ -650,7 +647,6 @@ inline unsigned short get_irq_base(u8 bank, u8 bmap) | |||
650 | } | 647 | } |
651 | 648 | ||
652 | return irq_base; | 649 | return irq_base; |
653 | |||
654 | } | 650 | } |
655 | 651 | ||
656 | /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ | 652 | /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ |
@@ -677,20 +673,18 @@ void init_pint_lut(void) | |||
677 | 673 | ||
678 | pint2irq_lut[bit_pos] = irq_base - SYS_IRQS; | 674 | pint2irq_lut[bit_pos] = irq_base - SYS_IRQS; |
679 | irq2pint_lut[irq_base - SYS_IRQS] = bit_pos; | 675 | irq2pint_lut[irq_base - SYS_IRQS] = bit_pos; |
680 | |||
681 | } | 676 | } |
682 | |||
683 | } | 677 | } |
684 | |||
685 | } | 678 | } |
686 | 679 | ||
687 | static void bfin_gpio_ack_irq(unsigned int irq) | 680 | static void bfin_gpio_ack_irq(unsigned int irq) |
688 | { | 681 | { |
689 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 682 | struct irq_desc *desc = irq_desc + irq; |
683 | u32 pint_val = irq2pint_lut[irq - SYS_IRQS]; | ||
690 | u32 pintbit = PINT_BIT(pint_val); | 684 | u32 pintbit = PINT_BIT(pint_val); |
691 | u8 bank = PINT_2_BANK(pint_val); | 685 | u32 bank = PINT_2_BANK(pint_val); |
692 | 686 | ||
693 | if (unlikely(gpio_both_edge_triggered[bank] & pintbit)) { | 687 | if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { |
694 | if (pint[bank]->invert_set & pintbit) | 688 | if (pint[bank]->invert_set & pintbit) |
695 | pint[bank]->invert_clear = pintbit; | 689 | pint[bank]->invert_clear = pintbit; |
696 | else | 690 | else |
@@ -698,16 +692,16 @@ static void bfin_gpio_ack_irq(unsigned int irq) | |||
698 | } | 692 | } |
699 | pint[bank]->request = pintbit; | 693 | pint[bank]->request = pintbit; |
700 | 694 | ||
701 | SSYNC(); | ||
702 | } | 695 | } |
703 | 696 | ||
704 | static void bfin_gpio_mask_ack_irq(unsigned int irq) | 697 | static void bfin_gpio_mask_ack_irq(unsigned int irq) |
705 | { | 698 | { |
706 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 699 | struct irq_desc *desc = irq_desc + irq; |
700 | u32 pint_val = irq2pint_lut[irq - SYS_IRQS]; | ||
707 | u32 pintbit = PINT_BIT(pint_val); | 701 | u32 pintbit = PINT_BIT(pint_val); |
708 | u8 bank = PINT_2_BANK(pint_val); | 702 | u32 bank = PINT_2_BANK(pint_val); |
709 | 703 | ||
710 | if (unlikely(gpio_both_edge_triggered[bank] & pintbit)) { | 704 | if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { |
711 | if (pint[bank]->invert_set & pintbit) | 705 | if (pint[bank]->invert_set & pintbit) |
712 | pint[bank]->invert_clear = pintbit; | 706 | pint[bank]->invert_clear = pintbit; |
713 | else | 707 | else |
@@ -716,32 +710,29 @@ static void bfin_gpio_mask_ack_irq(unsigned int irq) | |||
716 | 710 | ||
717 | pint[bank]->request = pintbit; | 711 | pint[bank]->request = pintbit; |
718 | pint[bank]->mask_clear = pintbit; | 712 | pint[bank]->mask_clear = pintbit; |
719 | SSYNC(); | ||
720 | } | 713 | } |
721 | 714 | ||
722 | static void bfin_gpio_mask_irq(unsigned int irq) | 715 | static void bfin_gpio_mask_irq(unsigned int irq) |
723 | { | 716 | { |
724 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 717 | u32 pint_val = irq2pint_lut[irq - SYS_IRQS]; |
725 | 718 | ||
726 | pint[PINT_2_BANK(pint_val)]->mask_clear = PINT_BIT(pint_val); | 719 | pint[PINT_2_BANK(pint_val)]->mask_clear = PINT_BIT(pint_val); |
727 | SSYNC(); | ||
728 | } | 720 | } |
729 | 721 | ||
730 | static void bfin_gpio_unmask_irq(unsigned int irq) | 722 | static void bfin_gpio_unmask_irq(unsigned int irq) |
731 | { | 723 | { |
732 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 724 | u32 pint_val = irq2pint_lut[irq - SYS_IRQS]; |
733 | u32 pintbit = PINT_BIT(pint_val); | 725 | u32 pintbit = PINT_BIT(pint_val); |
734 | u8 bank = PINT_2_BANK(pint_val); | 726 | u32 bank = PINT_2_BANK(pint_val); |
735 | 727 | ||
736 | pint[bank]->request = pintbit; | 728 | pint[bank]->request = pintbit; |
737 | pint[bank]->mask_set = pintbit; | 729 | pint[bank]->mask_set = pintbit; |
738 | SSYNC(); | ||
739 | } | 730 | } |
740 | 731 | ||
741 | static unsigned int bfin_gpio_irq_startup(unsigned int irq) | 732 | static unsigned int bfin_gpio_irq_startup(unsigned int irq) |
742 | { | 733 | { |
743 | u16 gpionr = irq_to_gpio(irq); | 734 | u32 gpionr = irq_to_gpio(irq); |
744 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 735 | u32 pint_val = irq2pint_lut[irq - SYS_IRQS]; |
745 | 736 | ||
746 | if (pint_val == IRQ_NOT_AVAIL) { | 737 | if (pint_val == IRQ_NOT_AVAIL) { |
747 | printk(KERN_ERR | 738 | printk(KERN_ERR |
@@ -750,10 +741,9 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq) | |||
750 | return -ENODEV; | 741 | return -ENODEV; |
751 | } | 742 | } |
752 | 743 | ||
753 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) | 744 | if (__test_and_set_bit(gpionr, gpio_enabled)) |
754 | bfin_gpio_irq_prepare(gpionr); | 745 | bfin_gpio_irq_prepare(gpionr); |
755 | 746 | ||
756 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); | ||
757 | bfin_gpio_unmask_irq(irq); | 747 | bfin_gpio_unmask_irq(irq); |
758 | 748 | ||
759 | return 0; | 749 | return 0; |
@@ -761,38 +751,45 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq) | |||
761 | 751 | ||
762 | static void bfin_gpio_irq_shutdown(unsigned int irq) | 752 | static void bfin_gpio_irq_shutdown(unsigned int irq) |
763 | { | 753 | { |
764 | u16 gpionr = irq_to_gpio(irq); | 754 | u32 gpionr = irq_to_gpio(irq); |
765 | 755 | ||
766 | bfin_gpio_mask_irq(irq); | 756 | bfin_gpio_mask_irq(irq); |
767 | gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); | 757 | __clear_bit(gpionr, gpio_enabled); |
758 | bfin_gpio_irq_free(gpionr); | ||
768 | } | 759 | } |
769 | 760 | ||
770 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | 761 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) |
771 | { | 762 | { |
772 | 763 | int ret; | |
773 | u16 gpionr = irq_to_gpio(irq); | 764 | char buf[16]; |
774 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 765 | u32 gpionr = irq_to_gpio(irq); |
766 | u32 pint_val = irq2pint_lut[irq - SYS_IRQS]; | ||
775 | u32 pintbit = PINT_BIT(pint_val); | 767 | u32 pintbit = PINT_BIT(pint_val); |
776 | u8 bank = PINT_2_BANK(pint_val); | 768 | u32 bank = PINT_2_BANK(pint_val); |
777 | 769 | ||
778 | if (pint_val == IRQ_NOT_AVAIL) | 770 | if (pint_val == IRQ_NOT_AVAIL) |
779 | return -ENODEV; | 771 | return -ENODEV; |
780 | 772 | ||
781 | if (type == IRQ_TYPE_PROBE) { | 773 | if (type == IRQ_TYPE_PROBE) { |
782 | /* only probe unenabled GPIO interrupt lines */ | 774 | /* only probe unenabled GPIO interrupt lines */ |
783 | if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr)) | 775 | if (__test_bit(gpionr, gpio_enabled)) |
784 | return 0; | 776 | return 0; |
785 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; | 777 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; |
786 | } | 778 | } |
787 | 779 | ||
788 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | | 780 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | |
789 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { | 781 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { |
790 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) | 782 | |
783 | snprintf(buf, 16, "gpio-irq%d", irq); | ||
784 | ret = bfin_gpio_irq_request(gpionr, buf); | ||
785 | if (ret) | ||
786 | return ret; | ||
787 | |||
788 | if (__test_and_set_bit(gpionr, gpio_enabled)) | ||
791 | bfin_gpio_irq_prepare(gpionr); | 789 | bfin_gpio_irq_prepare(gpionr); |
792 | 790 | ||
793 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); | ||
794 | } else { | 791 | } else { |
795 | gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); | 792 | __clear_bit(gpionr, gpio_enabled); |
796 | return 0; | 793 | return 0; |
797 | } | 794 | } |
798 | 795 | ||
@@ -803,15 +800,10 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
803 | 800 | ||
804 | if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) | 801 | if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) |
805 | == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { | 802 | == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { |
806 | |||
807 | gpio_both_edge_triggered[bank] |= pintbit; | ||
808 | |||
809 | if (gpio_get_value(gpionr)) | 803 | if (gpio_get_value(gpionr)) |
810 | pint[bank]->invert_set = pintbit; | 804 | pint[bank]->invert_set = pintbit; |
811 | else | 805 | else |
812 | pint[bank]->invert_clear = pintbit; | 806 | pint[bank]->invert_clear = pintbit; |
813 | } else { | ||
814 | gpio_both_edge_triggered[bank] &= ~pintbit; | ||
815 | } | 807 | } |
816 | 808 | ||
817 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { | 809 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { |
@@ -822,8 +814,6 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
822 | bfin_set_irq_handler(irq, handle_level_irq); | 814 | bfin_set_irq_handler(irq, handle_level_irq); |
823 | } | 815 | } |
824 | 816 | ||
825 | SSYNC(); | ||
826 | |||
827 | return 0; | 817 | return 0; |
828 | } | 818 | } |
829 | 819 | ||
@@ -834,7 +824,7 @@ u32 pint_wakeup_masks[NR_PINT_SYS_IRQS]; | |||
834 | int bfin_gpio_set_wake(unsigned int irq, unsigned int state) | 824 | int bfin_gpio_set_wake(unsigned int irq, unsigned int state) |
835 | { | 825 | { |
836 | u32 pint_irq; | 826 | u32 pint_irq; |
837 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 827 | u32 pint_val = irq2pint_lut[irq - SYS_IRQS]; |
838 | u32 bank = PINT_2_BANK(pint_val); | 828 | u32 bank = PINT_2_BANK(pint_val); |
839 | u32 pintbit = PINT_BIT(pint_val); | 829 | u32 pintbit = PINT_BIT(pint_val); |
840 | 830 | ||
@@ -895,26 +885,10 @@ void bfin_pm_restore(void) | |||
895 | } | 885 | } |
896 | #endif | 886 | #endif |
897 | 887 | ||
898 | static struct irq_chip bfin_gpio_irqchip = { | ||
899 | .name = "GPIO", | ||
900 | .ack = bfin_gpio_ack_irq, | ||
901 | .mask = bfin_gpio_mask_irq, | ||
902 | .mask_ack = bfin_gpio_mask_ack_irq, | ||
903 | .unmask = bfin_gpio_unmask_irq, | ||
904 | .disable = bfin_gpio_mask_irq, | ||
905 | .enable = bfin_gpio_unmask_irq, | ||
906 | .set_type = bfin_gpio_irq_type, | ||
907 | .startup = bfin_gpio_irq_startup, | ||
908 | .shutdown = bfin_gpio_irq_shutdown, | ||
909 | #ifdef CONFIG_PM | ||
910 | .set_wake = bfin_gpio_set_wake, | ||
911 | #endif | ||
912 | }; | ||
913 | |||
914 | static void bfin_demux_gpio_irq(unsigned int inta_irq, | 888 | static void bfin_demux_gpio_irq(unsigned int inta_irq, |
915 | struct irq_desc *desc) | 889 | struct irq_desc *desc) |
916 | { | 890 | { |
917 | u8 bank, pint_val; | 891 | u32 bank, pint_val; |
918 | u32 request, irq; | 892 | u32 request, irq; |
919 | 893 | ||
920 | switch (inta_irq) { | 894 | switch (inta_irq) { |
@@ -941,8 +915,7 @@ static void bfin_demux_gpio_irq(unsigned int inta_irq, | |||
941 | while (request) { | 915 | while (request) { |
942 | if (request & 1) { | 916 | if (request & 1) { |
943 | irq = pint2irq_lut[pint_val] + SYS_IRQS; | 917 | irq = pint2irq_lut[pint_val] + SYS_IRQS; |
944 | desc = irq_desc + irq; | 918 | bfin_handle_irq(irq); |
945 | desc->handle_irq(irq, desc); | ||
946 | } | 919 | } |
947 | pint_val++; | 920 | pint_val++; |
948 | request >>= 1; | 921 | request >>= 1; |
@@ -951,10 +924,24 @@ static void bfin_demux_gpio_irq(unsigned int inta_irq, | |||
951 | } | 924 | } |
952 | #endif | 925 | #endif |
953 | 926 | ||
954 | void __init init_exception_vectors(void) | 927 | static struct irq_chip bfin_gpio_irqchip = { |
955 | { | 928 | .name = "GPIO", |
956 | SSYNC(); | 929 | .ack = bfin_gpio_ack_irq, |
930 | .mask = bfin_gpio_mask_irq, | ||
931 | .mask_ack = bfin_gpio_mask_ack_irq, | ||
932 | .unmask = bfin_gpio_unmask_irq, | ||
933 | .disable = bfin_gpio_mask_irq, | ||
934 | .enable = bfin_gpio_unmask_irq, | ||
935 | .set_type = bfin_gpio_irq_type, | ||
936 | .startup = bfin_gpio_irq_startup, | ||
937 | .shutdown = bfin_gpio_irq_shutdown, | ||
938 | #ifdef CONFIG_PM | ||
939 | .set_wake = bfin_gpio_set_wake, | ||
940 | #endif | ||
941 | }; | ||
957 | 942 | ||
943 | void __cpuinit init_exception_vectors(void) | ||
944 | { | ||
958 | /* cannot program in software: | 945 | /* cannot program in software: |
959 | * evt0 - emulation (jtag) | 946 | * evt0 - emulation (jtag) |
960 | * evt1 - reset | 947 | * evt1 - reset |
@@ -979,17 +966,23 @@ void __init init_exception_vectors(void) | |||
979 | * This function should be called during kernel startup to initialize | 966 | * This function should be called during kernel startup to initialize |
980 | * the BFin IRQ handling routines. | 967 | * the BFin IRQ handling routines. |
981 | */ | 968 | */ |
969 | |||
982 | int __init init_arch_irq(void) | 970 | int __init init_arch_irq(void) |
983 | { | 971 | { |
984 | int irq; | 972 | int irq; |
985 | unsigned long ilat = 0; | 973 | unsigned long ilat = 0; |
986 | /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ | 974 | /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ |
987 | #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) | 975 | #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) \ |
976 | || defined(BF538_FAMILY) || defined(CONFIG_BF51x) | ||
988 | bfin_write_SIC_IMASK0(SIC_UNMASK_ALL); | 977 | bfin_write_SIC_IMASK0(SIC_UNMASK_ALL); |
989 | bfin_write_SIC_IMASK1(SIC_UNMASK_ALL); | 978 | bfin_write_SIC_IMASK1(SIC_UNMASK_ALL); |
990 | # ifdef CONFIG_BF54x | 979 | # ifdef CONFIG_BF54x |
991 | bfin_write_SIC_IMASK2(SIC_UNMASK_ALL); | 980 | bfin_write_SIC_IMASK2(SIC_UNMASK_ALL); |
992 | # endif | 981 | # endif |
982 | # ifdef CONFIG_SMP | ||
983 | bfin_write_SICB_IMASK0(SIC_UNMASK_ALL); | ||
984 | bfin_write_SICB_IMASK1(SIC_UNMASK_ALL); | ||
985 | # endif | ||
993 | #else | 986 | #else |
994 | bfin_write_SIC_IMASK(SIC_UNMASK_ALL); | 987 | bfin_write_SIC_IMASK(SIC_UNMASK_ALL); |
995 | #endif | 988 | #endif |
@@ -1029,7 +1022,7 @@ int __init init_arch_irq(void) | |||
1029 | case IRQ_PINT1: | 1022 | case IRQ_PINT1: |
1030 | case IRQ_PINT2: | 1023 | case IRQ_PINT2: |
1031 | case IRQ_PINT3: | 1024 | case IRQ_PINT3: |
1032 | #elif defined(CONFIG_BF52x) | 1025 | #elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x) |
1033 | case IRQ_PORTF_INTA: | 1026 | case IRQ_PORTF_INTA: |
1034 | case IRQ_PORTG_INTA: | 1027 | case IRQ_PORTG_INTA: |
1035 | case IRQ_PORTH_INTA: | 1028 | case IRQ_PORTH_INTA: |
@@ -1037,18 +1030,41 @@ int __init init_arch_irq(void) | |||
1037 | case IRQ_PROG0_INTA: | 1030 | case IRQ_PROG0_INTA: |
1038 | case IRQ_PROG1_INTA: | 1031 | case IRQ_PROG1_INTA: |
1039 | case IRQ_PROG2_INTA: | 1032 | case IRQ_PROG2_INTA: |
1033 | #elif defined(CONFIG_BF538) || defined(CONFIG_BF539) | ||
1034 | case IRQ_PORTF_INTA: | ||
1040 | #endif | 1035 | #endif |
1036 | |||
1041 | set_irq_chained_handler(irq, | 1037 | set_irq_chained_handler(irq, |
1042 | bfin_demux_gpio_irq); | 1038 | bfin_demux_gpio_irq); |
1043 | break; | 1039 | break; |
1044 | #ifdef BF537_GENERIC_ERROR_INT_DEMUX | 1040 | #ifdef BF537_GENERIC_ERROR_INT_DEMUX |
1045 | case IRQ_GENERIC_ERROR: | 1041 | case IRQ_GENERIC_ERROR: |
1046 | set_irq_handler(irq, bfin_demux_error_irq); | 1042 | set_irq_chained_handler(irq, bfin_demux_error_irq); |
1047 | 1043 | break; | |
1044 | #endif | ||
1045 | #if defined(CONFIG_TICK_SOURCE_SYSTMR0) || defined(CONFIG_IPIPE) | ||
1046 | case IRQ_TIMER0: | ||
1047 | set_irq_handler(irq, handle_percpu_irq); | ||
1048 | break; | ||
1049 | #endif | ||
1050 | #ifdef CONFIG_SMP | ||
1051 | case IRQ_SUPPLE_0: | ||
1052 | case IRQ_SUPPLE_1: | ||
1053 | set_irq_handler(irq, handle_percpu_irq); | ||
1048 | break; | 1054 | break; |
1049 | #endif | 1055 | #endif |
1050 | default: | 1056 | default: |
1057 | #ifdef CONFIG_IPIPE | ||
1058 | /* | ||
1059 | * We want internal interrupt sources to be masked, because | ||
1060 | * ISRs may trigger interrupts recursively (e.g. DMA), but | ||
1061 | * interrupts are _not_ masked at CPU level. So let's handle | ||
1062 | * them as level interrupts. | ||
1063 | */ | ||
1064 | set_irq_handler(irq, handle_level_irq); | ||
1065 | #else /* !CONFIG_IPIPE */ | ||
1051 | set_irq_handler(irq, handle_simple_irq); | 1066 | set_irq_handler(irq, handle_simple_irq); |
1067 | #endif /* !CONFIG_IPIPE */ | ||
1052 | break; | 1068 | break; |
1053 | } | 1069 | } |
1054 | } | 1070 | } |
@@ -1073,7 +1089,7 @@ int __init init_arch_irq(void) | |||
1073 | CSYNC(); | 1089 | CSYNC(); |
1074 | 1090 | ||
1075 | printk(KERN_INFO "Configuring Blackfin Priority Driven Interrupts\n"); | 1091 | printk(KERN_INFO "Configuring Blackfin Priority Driven Interrupts\n"); |
1076 | /* IMASK=xxx is equivalent to STI xx or irq_flags=xx, | 1092 | /* IMASK=xxx is equivalent to STI xx or bfin_irq_flags=xx, |
1077 | * local_irq_enable() | 1093 | * local_irq_enable() |
1078 | */ | 1094 | */ |
1079 | program_IAR(); | 1095 | program_IAR(); |
@@ -1081,19 +1097,23 @@ int __init init_arch_irq(void) | |||
1081 | search_IAR(); | 1097 | search_IAR(); |
1082 | 1098 | ||
1083 | /* Enable interrupts IVG7-15 */ | 1099 | /* Enable interrupts IVG7-15 */ |
1084 | irq_flags = irq_flags | IMASK_IVG15 | | 1100 | bfin_irq_flags |= IMASK_IVG15 | |
1085 | IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | | 1101 | IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | |
1086 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; | 1102 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; |
1087 | 1103 | ||
1088 | #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) | 1104 | #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) \ |
1105 | || defined(BF538_FAMILY) || defined(CONFIG_BF51x) | ||
1089 | bfin_write_SIC_IWR0(IWR_DISABLE_ALL); | 1106 | bfin_write_SIC_IWR0(IWR_DISABLE_ALL); |
1090 | #if defined(CONFIG_BF52x) | 1107 | #if defined(CONFIG_BF52x) || defined(CONFIG_BF51x) |
1091 | /* BF52x system reset does not properly reset SIC_IWR1 which | 1108 | /* BF52x/BF51x system reset does not properly reset SIC_IWR1 which |
1092 | * will screw up the bootrom as it relies on MDMA0/1 waking it | 1109 | * will screw up the bootrom as it relies on MDMA0/1 waking it |
1093 | * up from IDLE instructions. See this report for more info: | 1110 | * up from IDLE instructions. See this report for more info: |
1094 | * http://blackfin.uclinux.org/gf/tracker/4323 | 1111 | * http://blackfin.uclinux.org/gf/tracker/4323 |
1095 | */ | 1112 | */ |
1096 | bfin_write_SIC_IWR1(IWR_ENABLE(10) | IWR_ENABLE(11)); | 1113 | if (ANOMALY_05000435) |
1114 | bfin_write_SIC_IWR1(IWR_ENABLE(10) | IWR_ENABLE(11)); | ||
1115 | else | ||
1116 | bfin_write_SIC_IWR1(IWR_DISABLE_ALL); | ||
1097 | #else | 1117 | #else |
1098 | bfin_write_SIC_IWR1(IWR_DISABLE_ALL); | 1118 | bfin_write_SIC_IWR1(IWR_DISABLE_ALL); |
1099 | #endif | 1119 | #endif |
@@ -1104,6 +1124,14 @@ int __init init_arch_irq(void) | |||
1104 | bfin_write_SIC_IWR(IWR_DISABLE_ALL); | 1124 | bfin_write_SIC_IWR(IWR_DISABLE_ALL); |
1105 | #endif | 1125 | #endif |
1106 | 1126 | ||
1127 | #ifdef CONFIG_IPIPE | ||
1128 | for (irq = 0; irq < NR_IRQS; irq++) { | ||
1129 | struct irq_desc *desc = irq_desc + irq; | ||
1130 | desc->ic_prio = __ipipe_get_irq_priority(irq); | ||
1131 | desc->thr_prio = __ipipe_get_irqthread_priority(irq); | ||
1132 | } | ||
1133 | #endif /* CONFIG_IPIPE */ | ||
1134 | |||
1107 | return 0; | 1135 | return 0; |
1108 | } | 1136 | } |
1109 | 1137 | ||
@@ -1117,11 +1145,20 @@ void do_irq(int vec, struct pt_regs *fp) | |||
1117 | } else { | 1145 | } else { |
1118 | struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; | 1146 | struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; |
1119 | struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; | 1147 | struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; |
1120 | #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) | 1148 | #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) \ |
1149 | || defined(BF538_FAMILY) || defined(CONFIG_BF51x) | ||
1121 | unsigned long sic_status[3]; | 1150 | unsigned long sic_status[3]; |
1122 | 1151 | ||
1123 | sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0(); | 1152 | if (smp_processor_id()) { |
1124 | sic_status[1] = bfin_read_SIC_ISR1() & bfin_read_SIC_IMASK1(); | 1153 | #ifdef CONFIG_SMP |
1154 | /* This will be optimized out in UP mode. */ | ||
1155 | sic_status[0] = bfin_read_SICB_ISR0() & bfin_read_SICB_IMASK0(); | ||
1156 | sic_status[1] = bfin_read_SICB_ISR1() & bfin_read_SICB_IMASK1(); | ||
1157 | #endif | ||
1158 | } else { | ||
1159 | sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0(); | ||
1160 | sic_status[1] = bfin_read_SIC_ISR1() & bfin_read_SIC_IMASK1(); | ||
1161 | } | ||
1125 | #ifdef CONFIG_BF54x | 1162 | #ifdef CONFIG_BF54x |
1126 | sic_status[2] = bfin_read_SIC_ISR2() & bfin_read_SIC_IMASK2(); | 1163 | sic_status[2] = bfin_read_SIC_ISR2() & bfin_read_SIC_IMASK2(); |
1127 | #endif | 1164 | #endif |
@@ -1150,3 +1187,161 @@ void do_irq(int vec, struct pt_regs *fp) | |||
1150 | } | 1187 | } |
1151 | asm_do_IRQ(vec, fp); | 1188 | asm_do_IRQ(vec, fp); |
1152 | } | 1189 | } |
1190 | |||
1191 | #ifdef CONFIG_IPIPE | ||
1192 | |||
1193 | int __ipipe_get_irq_priority(unsigned irq) | ||
1194 | { | ||
1195 | int ient, prio; | ||
1196 | |||
1197 | if (irq <= IRQ_CORETMR) | ||
1198 | return irq; | ||
1199 | |||
1200 | for (ient = 0; ient < NR_PERI_INTS; ient++) { | ||
1201 | struct ivgx *ivg = ivg_table + ient; | ||
1202 | if (ivg->irqno == irq) { | ||
1203 | for (prio = 0; prio <= IVG13-IVG7; prio++) { | ||
1204 | if (ivg7_13[prio].ifirst <= ivg && | ||
1205 | ivg7_13[prio].istop > ivg) | ||
1206 | return IVG7 + prio; | ||
1207 | } | ||
1208 | } | ||
1209 | } | ||
1210 | |||
1211 | return IVG15; | ||
1212 | } | ||
1213 | |||
1214 | int __ipipe_get_irqthread_priority(unsigned irq) | ||
1215 | { | ||
1216 | int ient, prio; | ||
1217 | int demux_irq; | ||
1218 | |||
1219 | /* The returned priority value is rescaled to [0..IVG13+1] | ||
1220 | * with 0 being the lowest effective priority level. */ | ||
1221 | |||
1222 | if (irq <= IRQ_CORETMR) | ||
1223 | return IVG13 - irq + 1; | ||
1224 | |||
1225 | /* GPIO IRQs are given the priority of the demux | ||
1226 | * interrupt. */ | ||
1227 | if (IS_GPIOIRQ(irq)) { | ||
1228 | #if defined(CONFIG_BF54x) | ||
1229 | u32 bank = PINT_2_BANK(irq2pint_lut[irq - SYS_IRQS]); | ||
1230 | demux_irq = (bank == 0 ? IRQ_PINT0 : | ||
1231 | bank == 1 ? IRQ_PINT1 : | ||
1232 | bank == 2 ? IRQ_PINT2 : | ||
1233 | IRQ_PINT3); | ||
1234 | #elif defined(CONFIG_BF561) | ||
1235 | demux_irq = (irq >= IRQ_PF32 ? IRQ_PROG2_INTA : | ||
1236 | irq >= IRQ_PF16 ? IRQ_PROG1_INTA : | ||
1237 | IRQ_PROG0_INTA); | ||
1238 | #elif defined(CONFIG_BF52x) | ||
1239 | demux_irq = (irq >= IRQ_PH0 ? IRQ_PORTH_INTA : | ||
1240 | irq >= IRQ_PG0 ? IRQ_PORTG_INTA : | ||
1241 | IRQ_PORTF_INTA); | ||
1242 | #else | ||
1243 | demux_irq = irq; | ||
1244 | #endif | ||
1245 | return IVG13 - PRIO_GPIODEMUX(demux_irq) + 1; | ||
1246 | } | ||
1247 | |||
1248 | /* The GPIO demux interrupt is given a lower priority | ||
1249 | * than the GPIO IRQs, so that its threaded handler | ||
1250 | * unmasks the interrupt line after the decoded IRQs | ||
1251 | * have been processed. */ | ||
1252 | prio = PRIO_GPIODEMUX(irq); | ||
1253 | /* demux irq? */ | ||
1254 | if (prio != -1) | ||
1255 | return IVG13 - prio; | ||
1256 | |||
1257 | for (ient = 0; ient < NR_PERI_INTS; ient++) { | ||
1258 | struct ivgx *ivg = ivg_table + ient; | ||
1259 | if (ivg->irqno == irq) { | ||
1260 | for (prio = 0; prio <= IVG13-IVG7; prio++) { | ||
1261 | if (ivg7_13[prio].ifirst <= ivg && | ||
1262 | ivg7_13[prio].istop > ivg) | ||
1263 | return IVG7 - prio; | ||
1264 | } | ||
1265 | } | ||
1266 | } | ||
1267 | |||
1268 | return 0; | ||
1269 | } | ||
1270 | |||
1271 | /* Hw interrupts are disabled on entry (check SAVE_CONTEXT). */ | ||
1272 | #ifdef CONFIG_DO_IRQ_L1 | ||
1273 | __attribute__((l1_text)) | ||
1274 | #endif | ||
1275 | asmlinkage int __ipipe_grab_irq(int vec, struct pt_regs *regs) | ||
1276 | { | ||
1277 | struct ivgx *ivg_stop = ivg7_13[vec-IVG7].istop; | ||
1278 | struct ivgx *ivg = ivg7_13[vec-IVG7].ifirst; | ||
1279 | int irq; | ||
1280 | |||
1281 | if (likely(vec == EVT_IVTMR_P)) { | ||
1282 | irq = IRQ_CORETMR; | ||
1283 | goto handle_irq; | ||
1284 | } | ||
1285 | |||
1286 | SSYNC(); | ||
1287 | |||
1288 | #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) | ||
1289 | { | ||
1290 | unsigned long sic_status[3]; | ||
1291 | |||
1292 | sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0(); | ||
1293 | sic_status[1] = bfin_read_SIC_ISR1() & bfin_read_SIC_IMASK1(); | ||
1294 | #ifdef CONFIG_BF54x | ||
1295 | sic_status[2] = bfin_read_SIC_ISR2() & bfin_read_SIC_IMASK2(); | ||
1296 | #endif | ||
1297 | for (;; ivg++) { | ||
1298 | if (ivg >= ivg_stop) { | ||
1299 | atomic_inc(&num_spurious); | ||
1300 | return 0; | ||
1301 | } | ||
1302 | if (sic_status[(ivg->irqno - IVG7) / 32] & ivg->isrflag) | ||
1303 | break; | ||
1304 | } | ||
1305 | } | ||
1306 | #else | ||
1307 | { | ||
1308 | unsigned long sic_status; | ||
1309 | |||
1310 | sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); | ||
1311 | |||
1312 | for (;; ivg++) { | ||
1313 | if (ivg >= ivg_stop) { | ||
1314 | atomic_inc(&num_spurious); | ||
1315 | return 0; | ||
1316 | } else if (sic_status & ivg->isrflag) | ||
1317 | break; | ||
1318 | } | ||
1319 | } | ||
1320 | #endif | ||
1321 | |||
1322 | irq = ivg->irqno; | ||
1323 | |||
1324 | if (irq == IRQ_SYSTMR) { | ||
1325 | bfin_write_TIMER_STATUS(1); /* Latch TIMIL0 */ | ||
1326 | /* This is basically what we need from the register frame. */ | ||
1327 | __raw_get_cpu_var(__ipipe_tick_regs).ipend = regs->ipend; | ||
1328 | __raw_get_cpu_var(__ipipe_tick_regs).pc = regs->pc; | ||
1329 | if (!ipipe_root_domain_p) | ||
1330 | __raw_get_cpu_var(__ipipe_tick_regs).ipend |= 0x10; | ||
1331 | else | ||
1332 | __raw_get_cpu_var(__ipipe_tick_regs).ipend &= ~0x10; | ||
1333 | } | ||
1334 | |||
1335 | handle_irq: | ||
1336 | |||
1337 | ipipe_trace_irq_entry(irq); | ||
1338 | __ipipe_handle_irq(irq, regs); | ||
1339 | ipipe_trace_irq_exit(irq); | ||
1340 | |||
1341 | if (ipipe_root_domain_p) | ||
1342 | return !test_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)); | ||
1343 | |||
1344 | return 0; | ||
1345 | } | ||
1346 | |||
1347 | #endif /* CONFIG_IPIPE */ | ||