aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-common
diff options
context:
space:
mode:
authorMichael Hennerich <michael.hennerich@analog.com>2010-02-19 10:09:10 -0500
committerMike Frysinger <vapier@gentoo.org>2010-03-09 00:30:52 -0500
commitaec59c911307639c77076bdc9d9b546a4a767a73 (patch)
tree84dea13756d7a2093322dc25f6e2efda2c10f169 /arch/blackfin/mach-common
parentb2740801457b2fbbe14812c0fda24bd689025886 (diff)
Blackfin: add support for the on-chip MAC status interrupts
This patch provides infrastructure for MAC Wake-On-Lan and PHYINT use in phylib. New Interrupts added: IRQ_MAC_PHYINT /* PHY_INT Interrupt */ IRQ_MAC_MMCINT /* MMC Counter Interrupt */ IRQ_MAC_RXFSINT /* RX Frame-Status Interrupt */ IRQ_MAC_TXFSINT /* TX Frame-Status Interrupt */ IRQ_MAC_WAKEDET /* Wake-Up Interrupt */ IRQ_MAC_RXDMAERR /* RX DMA Direction Error Interrupt */ IRQ_MAC_TXDMAERR /* TX DMA Direction Error Interrupt */ IRQ_MAC_STMDONE /* Station Mgt. Transfer Done Interrupt */ On BF537/6 the implementation is not straight forward since there are now two chained chained_handlers. A cleaner approach would have been to add latter IRQs to the demux of IRQ_GENERIC_ERROR. Signed-off-by: Michael Hennerich <michael.hennerich@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin/mach-common')
-rw-r--r--arch/blackfin/mach-common/ints-priority.c140
1 files changed, 136 insertions, 4 deletions
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index ebf886091187..11c05f3e178b 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -325,7 +325,6 @@ static int error_int_mask;
325static void bfin_generic_error_mask_irq(unsigned int irq) 325static void bfin_generic_error_mask_irq(unsigned int irq)
326{ 326{
327 error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR)); 327 error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR));
328
329 if (!error_int_mask) 328 if (!error_int_mask)
330 bfin_internal_mask_irq(IRQ_GENERIC_ERROR); 329 bfin_internal_mask_irq(IRQ_GENERIC_ERROR);
331} 330}
@@ -416,6 +415,127 @@ static void bfin_demux_error_irq(unsigned int int_err_irq,
416} 415}
417#endif /* BF537_GENERIC_ERROR_INT_DEMUX */ 416#endif /* BF537_GENERIC_ERROR_INT_DEMUX */
418 417
418#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
419static int mac_stat_int_mask;
420
421static void bfin_mac_status_ack_irq(unsigned int irq)
422{
423 switch (irq) {
424 case IRQ_MAC_MMCINT:
425 bfin_write_EMAC_MMC_TIRQS(
426 bfin_read_EMAC_MMC_TIRQE() &
427 bfin_read_EMAC_MMC_TIRQS());
428 bfin_write_EMAC_MMC_RIRQS(
429 bfin_read_EMAC_MMC_RIRQE() &
430 bfin_read_EMAC_MMC_RIRQS());
431 break;
432 case IRQ_MAC_RXFSINT:
433 bfin_write_EMAC_RX_STKY(
434 bfin_read_EMAC_RX_IRQE() &
435 bfin_read_EMAC_RX_STKY());
436 break;
437 case IRQ_MAC_TXFSINT:
438 bfin_write_EMAC_TX_STKY(
439 bfin_read_EMAC_TX_IRQE() &
440 bfin_read_EMAC_TX_STKY());
441 break;
442 case IRQ_MAC_WAKEDET:
443 bfin_write_EMAC_WKUP_CTL(
444 bfin_read_EMAC_WKUP_CTL() | MPKS | RWKS);
445 break;
446 default:
447 /* These bits are W1C */
448 bfin_write_EMAC_SYSTAT(1L << (irq - IRQ_MAC_PHYINT));
449 break;
450 }
451}
452
453static void bfin_mac_status_mask_irq(unsigned int irq)
454{
455 mac_stat_int_mask &= ~(1L << (irq - IRQ_MAC_PHYINT));
456#ifdef BF537_GENERIC_ERROR_INT_DEMUX
457 switch (irq) {
458 case IRQ_MAC_PHYINT:
459 bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() & ~PHYIE);
460 break;
461 default:
462 break;
463 }
464#else
465 if (!mac_stat_int_mask)
466 bfin_internal_mask_irq(IRQ_MAC_ERROR);
467#endif
468 bfin_mac_status_ack_irq(irq);
469}
470
471static void bfin_mac_status_unmask_irq(unsigned int irq)
472{
473#ifdef BF537_GENERIC_ERROR_INT_DEMUX
474 switch (irq) {
475 case IRQ_MAC_PHYINT:
476 bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() | PHYIE);
477 break;
478 default:
479 break;
480 }
481#else
482 if (!mac_stat_int_mask)
483 bfin_internal_unmask_irq(IRQ_MAC_ERROR);
484#endif
485 mac_stat_int_mask |= 1L << (irq - IRQ_MAC_PHYINT);
486}
487
488#ifdef CONFIG_PM
489int bfin_mac_status_set_wake(unsigned int irq, unsigned int state)
490{
491#ifdef BF537_GENERIC_ERROR_INT_DEMUX
492 return bfin_internal_set_wake(IRQ_GENERIC_ERROR, state);
493#else
494 return bfin_internal_set_wake(IRQ_MAC_ERROR, state);
495#endif
496}
497#endif
498
499static struct irq_chip bfin_mac_status_irqchip = {
500 .name = "MACST",
501 .ack = bfin_ack_noop,
502 .mask_ack = bfin_mac_status_mask_irq,
503 .mask = bfin_mac_status_mask_irq,
504 .unmask = bfin_mac_status_unmask_irq,
505#ifdef CONFIG_PM
506 .set_wake = bfin_mac_status_set_wake,
507#endif
508};
509
510static void bfin_demux_mac_status_irq(unsigned int int_err_irq,
511 struct irq_desc *inta_desc)
512{
513 int i, irq = 0;
514 u32 status = bfin_read_EMAC_SYSTAT();
515
516 for (i = 0; i < (IRQ_MAC_STMDONE - IRQ_MAC_PHYINT); i++)
517 if (status & (1L << i)) {
518 irq = IRQ_MAC_PHYINT + i;
519 break;
520 }
521
522 if (irq) {
523 if (mac_stat_int_mask & (1L << (irq - IRQ_MAC_PHYINT))) {
524 bfin_handle_irq(irq);
525 } else {
526 bfin_mac_status_ack_irq(irq);
527 pr_debug("IRQ %d:"
528 " MASKED MAC ERROR INTERRUPT ASSERTED\n",
529 irq);
530 }
531 } else
532 printk(KERN_ERR
533 "%s : %s : LINE %d :\nIRQ ?: MAC ERROR"
534 " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n",
535 __func__, __FILE__, __LINE__);
536}
537#endif
538
419static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle) 539static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle)
420{ 540{
421#ifdef CONFIG_IPIPE 541#ifdef CONFIG_IPIPE
@@ -1070,7 +1190,11 @@ int __init init_arch_irq(void)
1070 set_irq_chained_handler(irq, bfin_demux_error_irq); 1190 set_irq_chained_handler(irq, bfin_demux_error_irq);
1071 break; 1191 break;
1072#endif 1192#endif
1073 1193#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
1194 case IRQ_MAC_ERROR:
1195 set_irq_chained_handler(irq, bfin_demux_mac_status_irq);
1196 break;
1197#endif
1074#ifdef CONFIG_SMP 1198#ifdef CONFIG_SMP
1075 case IRQ_SUPPLE_0: 1199 case IRQ_SUPPLE_0:
1076 case IRQ_SUPPLE_1: 1200 case IRQ_SUPPLE_1:
@@ -1111,14 +1235,22 @@ int __init init_arch_irq(void)
1111 for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) 1235 for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++)
1112 set_irq_chip_and_handler(irq, &bfin_generic_error_irqchip, 1236 set_irq_chip_and_handler(irq, &bfin_generic_error_irqchip,
1113 handle_level_irq); 1237 handle_level_irq);
1238#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
1239 set_irq_chained_handler(IRQ_MAC_ERROR, bfin_demux_mac_status_irq);
1240#endif
1114#endif 1241#endif
1115 1242
1243#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
1244 for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++)
1245 set_irq_chip_and_handler(irq, &bfin_mac_status_irqchip,
1246 handle_level_irq);
1247#endif
1116 /* if configured as edge, then will be changed to do_edge_IRQ */ 1248 /* if configured as edge, then will be changed to do_edge_IRQ */
1117 for (irq = GPIO_IRQ_BASE; irq < NR_MACH_IRQS; irq++) 1249 for (irq = GPIO_IRQ_BASE;
1250 irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++)
1118 set_irq_chip_and_handler(irq, &bfin_gpio_irqchip, 1251 set_irq_chip_and_handler(irq, &bfin_gpio_irqchip,
1119 handle_level_irq); 1252 handle_level_irq);
1120 1253
1121
1122 bfin_write_IMASK(0); 1254 bfin_write_IMASK(0);
1123 CSYNC(); 1255 CSYNC();
1124 ilat = bfin_read_ILAT(); 1256 ilat = bfin_read_ILAT();