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(); |
