diff options
Diffstat (limited to 'arch/blackfin/mach-common/ints-priority.c')
-rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 208 |
1 files changed, 184 insertions, 24 deletions
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 1873b2c1fede..7ad8878bfa18 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <asm/dpmc.h> | 28 | #include <asm/dpmc.h> |
29 | #include <asm/bfin5xx_spi.h> | 29 | #include <asm/bfin5xx_spi.h> |
30 | #include <asm/bfin_sport.h> | 30 | #include <asm/bfin_sport.h> |
31 | #include <asm/bfin_can.h> | ||
31 | 32 | ||
32 | #define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) | 33 | #define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) |
33 | 34 | ||
@@ -172,7 +173,12 @@ static void bfin_internal_mask_irq(unsigned int irq) | |||
172 | local_irq_restore_hw(flags); | 173 | local_irq_restore_hw(flags); |
173 | } | 174 | } |
174 | 175 | ||
176 | #ifdef CONFIG_SMP | ||
177 | static void bfin_internal_unmask_irq_affinity(unsigned int irq, | ||
178 | const struct cpumask *affinity) | ||
179 | #else | ||
175 | static void bfin_internal_unmask_irq(unsigned int irq) | 180 | static void bfin_internal_unmask_irq(unsigned int irq) |
181 | #endif | ||
176 | { | 182 | { |
177 | unsigned long flags; | 183 | unsigned long flags; |
178 | 184 | ||
@@ -185,16 +191,38 @@ static void bfin_internal_unmask_irq(unsigned int irq) | |||
185 | local_irq_save_hw(flags); | 191 | local_irq_save_hw(flags); |
186 | mask_bank = SIC_SYSIRQ(irq) / 32; | 192 | mask_bank = SIC_SYSIRQ(irq) / 32; |
187 | mask_bit = SIC_SYSIRQ(irq) % 32; | 193 | mask_bit = SIC_SYSIRQ(irq) % 32; |
188 | bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) | | ||
189 | (1 << mask_bit)); | ||
190 | #ifdef CONFIG_SMP | 194 | #ifdef CONFIG_SMP |
191 | bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) | | 195 | if (cpumask_test_cpu(0, affinity)) |
192 | (1 << mask_bit)); | 196 | #endif |
197 | bfin_write_SIC_IMASK(mask_bank, | ||
198 | bfin_read_SIC_IMASK(mask_bank) | | ||
199 | (1 << mask_bit)); | ||
200 | #ifdef CONFIG_SMP | ||
201 | if (cpumask_test_cpu(1, affinity)) | ||
202 | bfin_write_SICB_IMASK(mask_bank, | ||
203 | bfin_read_SICB_IMASK(mask_bank) | | ||
204 | (1 << mask_bit)); | ||
193 | #endif | 205 | #endif |
194 | #endif | 206 | #endif |
195 | local_irq_restore_hw(flags); | 207 | local_irq_restore_hw(flags); |
196 | } | 208 | } |
197 | 209 | ||
210 | #ifdef CONFIG_SMP | ||
211 | static void bfin_internal_unmask_irq(unsigned int irq) | ||
212 | { | ||
213 | struct irq_desc *desc = irq_to_desc(irq); | ||
214 | bfin_internal_unmask_irq_affinity(irq, desc->affinity); | ||
215 | } | ||
216 | |||
217 | static int bfin_internal_set_affinity(unsigned int irq, const struct cpumask *mask) | ||
218 | { | ||
219 | bfin_internal_mask_irq(irq); | ||
220 | bfin_internal_unmask_irq_affinity(irq, mask); | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | #endif | ||
225 | |||
198 | #ifdef CONFIG_PM | 226 | #ifdef CONFIG_PM |
199 | int bfin_internal_set_wake(unsigned int irq, unsigned int state) | 227 | int bfin_internal_set_wake(unsigned int irq, unsigned int state) |
200 | { | 228 | { |
@@ -224,11 +252,6 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state) | |||
224 | wakeup |= USBWE; | 252 | wakeup |= USBWE; |
225 | break; | 253 | break; |
226 | #endif | 254 | #endif |
227 | #ifdef IRQ_KEY | ||
228 | case IRQ_KEY: | ||
229 | wakeup |= KPADWE; | ||
230 | break; | ||
231 | #endif | ||
232 | #ifdef CONFIG_BF54x | 255 | #ifdef CONFIG_BF54x |
233 | case IRQ_CNT: | 256 | case IRQ_CNT: |
234 | wakeup |= ROTWE; | 257 | wakeup |= ROTWE; |
@@ -270,6 +293,9 @@ static struct irq_chip bfin_internal_irqchip = { | |||
270 | .mask_ack = bfin_internal_mask_irq, | 293 | .mask_ack = bfin_internal_mask_irq, |
271 | .disable = bfin_internal_mask_irq, | 294 | .disable = bfin_internal_mask_irq, |
272 | .enable = bfin_internal_unmask_irq, | 295 | .enable = bfin_internal_unmask_irq, |
296 | #ifdef CONFIG_SMP | ||
297 | .set_affinity = bfin_internal_set_affinity, | ||
298 | #endif | ||
273 | #ifdef CONFIG_PM | 299 | #ifdef CONFIG_PM |
274 | .set_wake = bfin_internal_set_wake, | 300 | .set_wake = bfin_internal_set_wake, |
275 | #endif | 301 | #endif |
@@ -294,7 +320,6 @@ static int error_int_mask; | |||
294 | static void bfin_generic_error_mask_irq(unsigned int irq) | 320 | static void bfin_generic_error_mask_irq(unsigned int irq) |
295 | { | 321 | { |
296 | error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR)); | 322 | error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR)); |
297 | |||
298 | if (!error_int_mask) | 323 | if (!error_int_mask) |
299 | bfin_internal_mask_irq(IRQ_GENERIC_ERROR); | 324 | bfin_internal_mask_irq(IRQ_GENERIC_ERROR); |
300 | } | 325 | } |
@@ -385,6 +410,127 @@ static void bfin_demux_error_irq(unsigned int int_err_irq, | |||
385 | } | 410 | } |
386 | #endif /* BF537_GENERIC_ERROR_INT_DEMUX */ | 411 | #endif /* BF537_GENERIC_ERROR_INT_DEMUX */ |
387 | 412 | ||
413 | #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) | ||
414 | static int mac_stat_int_mask; | ||
415 | |||
416 | static void bfin_mac_status_ack_irq(unsigned int irq) | ||
417 | { | ||
418 | switch (irq) { | ||
419 | case IRQ_MAC_MMCINT: | ||
420 | bfin_write_EMAC_MMC_TIRQS( | ||
421 | bfin_read_EMAC_MMC_TIRQE() & | ||
422 | bfin_read_EMAC_MMC_TIRQS()); | ||
423 | bfin_write_EMAC_MMC_RIRQS( | ||
424 | bfin_read_EMAC_MMC_RIRQE() & | ||
425 | bfin_read_EMAC_MMC_RIRQS()); | ||
426 | break; | ||
427 | case IRQ_MAC_RXFSINT: | ||
428 | bfin_write_EMAC_RX_STKY( | ||
429 | bfin_read_EMAC_RX_IRQE() & | ||
430 | bfin_read_EMAC_RX_STKY()); | ||
431 | break; | ||
432 | case IRQ_MAC_TXFSINT: | ||
433 | bfin_write_EMAC_TX_STKY( | ||
434 | bfin_read_EMAC_TX_IRQE() & | ||
435 | bfin_read_EMAC_TX_STKY()); | ||
436 | break; | ||
437 | case IRQ_MAC_WAKEDET: | ||
438 | bfin_write_EMAC_WKUP_CTL( | ||
439 | bfin_read_EMAC_WKUP_CTL() | MPKS | RWKS); | ||
440 | break; | ||
441 | default: | ||
442 | /* These bits are W1C */ | ||
443 | bfin_write_EMAC_SYSTAT(1L << (irq - IRQ_MAC_PHYINT)); | ||
444 | break; | ||
445 | } | ||
446 | } | ||
447 | |||
448 | static void bfin_mac_status_mask_irq(unsigned int irq) | ||
449 | { | ||
450 | mac_stat_int_mask &= ~(1L << (irq - IRQ_MAC_PHYINT)); | ||
451 | #ifdef BF537_GENERIC_ERROR_INT_DEMUX | ||
452 | switch (irq) { | ||
453 | case IRQ_MAC_PHYINT: | ||
454 | bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() & ~PHYIE); | ||
455 | break; | ||
456 | default: | ||
457 | break; | ||
458 | } | ||
459 | #else | ||
460 | if (!mac_stat_int_mask) | ||
461 | bfin_internal_mask_irq(IRQ_MAC_ERROR); | ||
462 | #endif | ||
463 | bfin_mac_status_ack_irq(irq); | ||
464 | } | ||
465 | |||
466 | static void bfin_mac_status_unmask_irq(unsigned int irq) | ||
467 | { | ||
468 | #ifdef BF537_GENERIC_ERROR_INT_DEMUX | ||
469 | switch (irq) { | ||
470 | case IRQ_MAC_PHYINT: | ||
471 | bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() | PHYIE); | ||
472 | break; | ||
473 | default: | ||
474 | break; | ||
475 | } | ||
476 | #else | ||
477 | if (!mac_stat_int_mask) | ||
478 | bfin_internal_unmask_irq(IRQ_MAC_ERROR); | ||
479 | #endif | ||
480 | mac_stat_int_mask |= 1L << (irq - IRQ_MAC_PHYINT); | ||
481 | } | ||
482 | |||
483 | #ifdef CONFIG_PM | ||
484 | int bfin_mac_status_set_wake(unsigned int irq, unsigned int state) | ||
485 | { | ||
486 | #ifdef BF537_GENERIC_ERROR_INT_DEMUX | ||
487 | return bfin_internal_set_wake(IRQ_GENERIC_ERROR, state); | ||
488 | #else | ||
489 | return bfin_internal_set_wake(IRQ_MAC_ERROR, state); | ||
490 | #endif | ||
491 | } | ||
492 | #endif | ||
493 | |||
494 | static struct irq_chip bfin_mac_status_irqchip = { | ||
495 | .name = "MACST", | ||
496 | .ack = bfin_ack_noop, | ||
497 | .mask_ack = bfin_mac_status_mask_irq, | ||
498 | .mask = bfin_mac_status_mask_irq, | ||
499 | .unmask = bfin_mac_status_unmask_irq, | ||
500 | #ifdef CONFIG_PM | ||
501 | .set_wake = bfin_mac_status_set_wake, | ||
502 | #endif | ||
503 | }; | ||
504 | |||
505 | static void bfin_demux_mac_status_irq(unsigned int int_err_irq, | ||
506 | struct irq_desc *inta_desc) | ||
507 | { | ||
508 | int i, irq = 0; | ||
509 | u32 status = bfin_read_EMAC_SYSTAT(); | ||
510 | |||
511 | for (i = 0; i < (IRQ_MAC_STMDONE - IRQ_MAC_PHYINT); i++) | ||
512 | if (status & (1L << i)) { | ||
513 | irq = IRQ_MAC_PHYINT + i; | ||
514 | break; | ||
515 | } | ||
516 | |||
517 | if (irq) { | ||
518 | if (mac_stat_int_mask & (1L << (irq - IRQ_MAC_PHYINT))) { | ||
519 | bfin_handle_irq(irq); | ||
520 | } else { | ||
521 | bfin_mac_status_ack_irq(irq); | ||
522 | pr_debug("IRQ %d:" | ||
523 | " MASKED MAC ERROR INTERRUPT ASSERTED\n", | ||
524 | irq); | ||
525 | } | ||
526 | } else | ||
527 | printk(KERN_ERR | ||
528 | "%s : %s : LINE %d :\nIRQ ?: MAC ERROR" | ||
529 | " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n", | ||
530 | __func__, __FILE__, __LINE__); | ||
531 | } | ||
532 | #endif | ||
533 | |||
388 | static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle) | 534 | static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle) |
389 | { | 535 | { |
390 | #ifdef CONFIG_IPIPE | 536 | #ifdef CONFIG_IPIPE |
@@ -1031,7 +1177,6 @@ int __init init_arch_irq(void) | |||
1031 | #elif defined(CONFIG_BF538) || defined(CONFIG_BF539) | 1177 | #elif defined(CONFIG_BF538) || defined(CONFIG_BF539) |
1032 | case IRQ_PORTF_INTA: | 1178 | case IRQ_PORTF_INTA: |
1033 | #endif | 1179 | #endif |
1034 | |||
1035 | set_irq_chained_handler(irq, | 1180 | set_irq_chained_handler(irq, |
1036 | bfin_demux_gpio_irq); | 1181 | bfin_demux_gpio_irq); |
1037 | break; | 1182 | break; |
@@ -1040,29 +1185,36 @@ int __init init_arch_irq(void) | |||
1040 | set_irq_chained_handler(irq, bfin_demux_error_irq); | 1185 | set_irq_chained_handler(irq, bfin_demux_error_irq); |
1041 | break; | 1186 | break; |
1042 | #endif | 1187 | #endif |
1043 | 1188 | #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) | |
1044 | #ifdef CONFIG_SMP | 1189 | case IRQ_MAC_ERROR: |
1045 | #ifdef CONFIG_TICKSOURCE_GPTMR0 | 1190 | set_irq_chained_handler(irq, bfin_demux_mac_status_irq); |
1046 | case IRQ_TIMER0: | 1191 | break; |
1047 | #endif | ||
1048 | #ifdef CONFIG_TICKSOURCE_CORETMR | ||
1049 | case IRQ_CORETMR: | ||
1050 | #endif | 1192 | #endif |
1193 | #ifdef CONFIG_SMP | ||
1051 | case IRQ_SUPPLE_0: | 1194 | case IRQ_SUPPLE_0: |
1052 | case IRQ_SUPPLE_1: | 1195 | case IRQ_SUPPLE_1: |
1053 | set_irq_handler(irq, handle_percpu_irq); | 1196 | set_irq_handler(irq, handle_percpu_irq); |
1054 | break; | 1197 | break; |
1055 | #endif | 1198 | #endif |
1056 | 1199 | ||
1057 | #ifdef CONFIG_IPIPE | 1200 | #ifdef CONFIG_TICKSOURCE_CORETMR |
1058 | #ifndef CONFIG_TICKSOURCE_CORETMR | 1201 | case IRQ_CORETMR: |
1059 | case IRQ_TIMER0: | 1202 | # ifdef CONFIG_SMP |
1203 | set_irq_handler(irq, handle_percpu_irq); | ||
1204 | break; | ||
1205 | # else | ||
1060 | set_irq_handler(irq, handle_simple_irq); | 1206 | set_irq_handler(irq, handle_simple_irq); |
1061 | break; | 1207 | break; |
1208 | # endif | ||
1062 | #endif | 1209 | #endif |
1063 | case IRQ_CORETMR: | 1210 | |
1211 | #ifdef CONFIG_TICKSOURCE_GPTMR0 | ||
1212 | case IRQ_TIMER0: | ||
1064 | set_irq_handler(irq, handle_simple_irq); | 1213 | set_irq_handler(irq, handle_simple_irq); |
1065 | break; | 1214 | break; |
1215 | #endif | ||
1216 | |||
1217 | #ifdef CONFIG_IPIPE | ||
1066 | default: | 1218 | default: |
1067 | set_irq_handler(irq, handle_level_irq); | 1219 | set_irq_handler(irq, handle_level_irq); |
1068 | break; | 1220 | break; |
@@ -1078,14 +1230,22 @@ int __init init_arch_irq(void) | |||
1078 | for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) | 1230 | for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) |
1079 | set_irq_chip_and_handler(irq, &bfin_generic_error_irqchip, | 1231 | set_irq_chip_and_handler(irq, &bfin_generic_error_irqchip, |
1080 | handle_level_irq); | 1232 | handle_level_irq); |
1233 | #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) | ||
1234 | set_irq_chained_handler(IRQ_MAC_ERROR, bfin_demux_mac_status_irq); | ||
1235 | #endif | ||
1081 | #endif | 1236 | #endif |
1082 | 1237 | ||
1238 | #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) | ||
1239 | for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++) | ||
1240 | set_irq_chip_and_handler(irq, &bfin_mac_status_irqchip, | ||
1241 | handle_level_irq); | ||
1242 | #endif | ||
1083 | /* if configured as edge, then will be changed to do_edge_IRQ */ | 1243 | /* if configured as edge, then will be changed to do_edge_IRQ */ |
1084 | for (irq = GPIO_IRQ_BASE; irq < NR_IRQS; irq++) | 1244 | for (irq = GPIO_IRQ_BASE; |
1245 | irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) | ||
1085 | set_irq_chip_and_handler(irq, &bfin_gpio_irqchip, | 1246 | set_irq_chip_and_handler(irq, &bfin_gpio_irqchip, |
1086 | handle_level_irq); | 1247 | handle_level_irq); |
1087 | 1248 | ||
1088 | |||
1089 | bfin_write_IMASK(0); | 1249 | bfin_write_IMASK(0); |
1090 | CSYNC(); | 1250 | CSYNC(); |
1091 | ilat = bfin_read_ILAT(); | 1251 | ilat = bfin_read_ILAT(); |