irq.c 4.6 KB

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