irq.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * arch/sh/boards/se/7343/irq.c
  3. *
  4. */
  5. #include <linux/config.h>
  6. #include <linux/init.h>
  7. #include <linux/interrupt.h>
  8. #include <linux/irq.h>
  9. #include <asm/irq.h>
  10. #include <asm/io.h>
  11. #include <asm/mach/se7343.h>
  12. static void
  13. disable_intreq_irq(unsigned int irq)
  14. {
  15. int bit = irq - OFFCHIP_IRQ_BASE;
  16. u16 val;
  17. val = ctrl_inw(PA_CPLD_IMSK);
  18. val |= 1 << bit;
  19. ctrl_outw(val, PA_CPLD_IMSK);
  20. }
  21. static void
  22. enable_intreq_irq(unsigned int irq)
  23. {
  24. int bit = irq - OFFCHIP_IRQ_BASE;
  25. u16 val;
  26. val = ctrl_inw(PA_CPLD_IMSK);
  27. val &= ~(1 << bit);
  28. ctrl_outw(val, PA_CPLD_IMSK);
  29. }
  30. static void
  31. mask_and_ack_intreq_irq(unsigned int irq)
  32. {
  33. disable_intreq_irq(irq);
  34. }
  35. static unsigned int
  36. startup_intreq_irq(unsigned int irq)
  37. {
  38. enable_intreq_irq(irq);
  39. return 0;
  40. }
  41. static void
  42. shutdown_intreq_irq(unsigned int irq)
  43. {
  44. disable_intreq_irq(irq);
  45. }
  46. static void
  47. end_intreq_irq(unsigned int irq)
  48. {
  49. if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
  50. enable_intreq_irq(irq);
  51. }
  52. static struct hw_interrupt_type intreq_irq_type = {
  53. .typename = "FPGA-IRQ",
  54. .startup = startup_intreq_irq,
  55. .shutdown = shutdown_intreq_irq,
  56. .enable = enable_intreq_irq,
  57. .disable = disable_intreq_irq,
  58. .ack = mask_and_ack_intreq_irq,
  59. .end = end_intreq_irq
  60. };
  61. static void
  62. make_intreq_irq(unsigned int irq)
  63. {
  64. disable_irq_nosync(irq);
  65. irq_desc[irq].handler = &intreq_irq_type;
  66. disable_intreq_irq(irq);
  67. }
  68. int
  69. shmse_irq_demux(int irq)
  70. {
  71. int bit;
  72. volatile u16 val;
  73. if (irq == IRQ5_IRQ) {
  74. /* Read status Register */
  75. val = ctrl_inw(PA_CPLD_ST);
  76. bit = ffs(val);
  77. if (bit != 0)
  78. return OFFCHIP_IRQ_BASE + bit - 1;
  79. }
  80. return irq;
  81. }
  82. /* IRQ5 is multiplexed between the following sources:
  83. * 1. PC Card socket
  84. * 2. Extension slot
  85. * 3. USB Controller
  86. * 4. Serial Controller
  87. *
  88. * We configure IRQ5 as a cascade IRQ.
  89. */
  90. static struct irqaction irq5 = { no_action, 0, CPU_MASK_NONE, "IRQ5-cascade",
  91. NULL, NULL};
  92. /*
  93. * Initialize IRQ setting
  94. */
  95. void __init
  96. init_7343se_IRQ(void)
  97. {
  98. /* Setup Multiplexed interrupts */
  99. ctrl_outw(8, PA_CPLD_MODESET); /* Set all CPLD interrupts to active
  100. * low.
  101. */
  102. /* Mask all CPLD controller interrupts */
  103. ctrl_outw(0x0fff, PA_CPLD_IMSK);
  104. /* PC Card interrupts */
  105. make_intreq_irq(PC_IRQ0);
  106. make_intreq_irq(PC_IRQ1);
  107. make_intreq_irq(PC_IRQ2);
  108. make_intreq_irq(PC_IRQ3);
  109. /* Extension Slot Interrupts */
  110. make_intreq_irq(EXT_IRQ0);
  111. make_intreq_irq(EXT_IRQ1);
  112. make_intreq_irq(EXT_IRQ2);
  113. make_intreq_irq(EXT_IRQ3);
  114. /* USB Controller interrupts */
  115. make_intreq_irq(USB_IRQ0);
  116. make_intreq_irq(USB_IRQ1);
  117. /* Serial Controller interrupts */
  118. make_intreq_irq(UART_IRQ0);
  119. make_intreq_irq(UART_IRQ1);
  120. /* Setup all external interrupts to be active low */
  121. ctrl_outw(0xaaaa, INTC_ICR1);
  122. make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR+2, IRQ5_IPR_POS, IRQ5_PRIORITY);
  123. setup_irq(IRQ5_IRQ, &irq5);
  124. /* Set port control to use IRQ5 */
  125. *(u16 *)0xA4050108 &= ~0xc;
  126. make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
  127. make_ipr_irq(VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8);
  128. ctrl_outb(0x0f, INTC_IMCR5); /* enable SCIF IRQ */
  129. make_ipr_irq(DMTE0_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
  130. make_ipr_irq(DMTE1_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
  131. make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
  132. make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
  133. make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
  134. make_ipr_irq(DMTE5_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
  135. /* I2C block */
  136. make_ipr_irq(IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY);
  137. make_ipr_irq(IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS,
  138. IIC0_PRIORITY);
  139. make_ipr_irq(IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS,
  140. IIC0_PRIORITY);
  141. make_ipr_irq(IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY);
  142. make_ipr_irq(IIC1_ALI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY);
  143. make_ipr_irq(IIC1_TACKI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS,
  144. IIC1_PRIORITY);
  145. make_ipr_irq(IIC1_WAITI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS,
  146. IIC1_PRIORITY);
  147. make_ipr_irq(IIC1_DTEI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY);
  148. /* SIOF */
  149. make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
  150. /* SIU */
  151. make_ipr_irq(SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY);
  152. /* VIO interrupt */
  153. make_ipr_irq(CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
  154. make_ipr_irq(BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
  155. make_ipr_irq(VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
  156. /*MFI interrupt*/
  157. make_ipr_irq(MFI_IRQ, MFI_IPR_ADDR, MFI_IPR_POS, MFI_PRIORITY);
  158. /* LCD controller */
  159. make_ipr_irq(LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY);
  160. ctrl_outw(0x2000, PA_MRSHPC + 0x0c); /* mrshpc irq enable */
  161. }