irq.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*
  2. * linux/arch/mips/tx4938/toshiba_rbtx4938/irq.c
  3. *
  4. * Toshiba RBTX4938 specific interrupt handlers
  5. * Copyright (C) 2000-2001 Toshiba Corporation
  6. *
  7. * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
  8. * terms of the GNU General Public License version 2. This program is
  9. * licensed "as is" without any warranty of any kind, whether express
  10. * or implied.
  11. *
  12. * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
  13. */
  14. /*
  15. IRQ Device
  16. 16 TX4938-CP0/00 Software 0
  17. 17 TX4938-CP0/01 Software 1
  18. 18 TX4938-CP0/02 Cascade TX4938-CP0
  19. 19 TX4938-CP0/03 Multiplexed -- do not use
  20. 20 TX4938-CP0/04 Multiplexed -- do not use
  21. 21 TX4938-CP0/05 Multiplexed -- do not use
  22. 22 TX4938-CP0/06 Multiplexed -- do not use
  23. 23 TX4938-CP0/07 CPU TIMER
  24. 24 TX4938-PIC/00
  25. 25 TX4938-PIC/01
  26. 26 TX4938-PIC/02 Cascade RBTX4938-IOC
  27. 27 TX4938-PIC/03 RBTX4938 RTL-8019AS Ethernet
  28. 28 TX4938-PIC/04
  29. 29 TX4938-PIC/05 TX4938 ETH1
  30. 30 TX4938-PIC/06 TX4938 ETH0
  31. 31 TX4938-PIC/07
  32. 32 TX4938-PIC/08 TX4938 SIO 0
  33. 33 TX4938-PIC/09 TX4938 SIO 1
  34. 34 TX4938-PIC/10 TX4938 DMA0
  35. 35 TX4938-PIC/11 TX4938 DMA1
  36. 36 TX4938-PIC/12 TX4938 DMA2
  37. 37 TX4938-PIC/13 TX4938 DMA3
  38. 38 TX4938-PIC/14
  39. 39 TX4938-PIC/15
  40. 40 TX4938-PIC/16 TX4938 PCIC
  41. 41 TX4938-PIC/17 TX4938 TMR0
  42. 42 TX4938-PIC/18 TX4938 TMR1
  43. 43 TX4938-PIC/19 TX4938 TMR2
  44. 44 TX4938-PIC/20
  45. 45 TX4938-PIC/21
  46. 46 TX4938-PIC/22 TX4938 PCIERR
  47. 47 TX4938-PIC/23
  48. 48 TX4938-PIC/24
  49. 49 TX4938-PIC/25
  50. 50 TX4938-PIC/26
  51. 51 TX4938-PIC/27
  52. 52 TX4938-PIC/28
  53. 53 TX4938-PIC/29
  54. 54 TX4938-PIC/30
  55. 55 TX4938-PIC/31 TX4938 SPI
  56. 56 RBTX4938-IOC/00 PCI-D
  57. 57 RBTX4938-IOC/01 PCI-C
  58. 58 RBTX4938-IOC/02 PCI-B
  59. 59 RBTX4938-IOC/03 PCI-A
  60. 60 RBTX4938-IOC/04 RTC
  61. 61 RBTX4938-IOC/05 ATA
  62. 62 RBTX4938-IOC/06 MODEM
  63. 63 RBTX4938-IOC/07 SWINT
  64. */
  65. #include <linux/init.h>
  66. #include <linux/kernel.h>
  67. #include <linux/types.h>
  68. #include <linux/mm.h>
  69. #include <linux/swap.h>
  70. #include <linux/ioport.h>
  71. #include <linux/sched.h>
  72. #include <linux/interrupt.h>
  73. #include <linux/pci.h>
  74. #include <linux/timex.h>
  75. #include <asm/bootinfo.h>
  76. #include <asm/page.h>
  77. #include <asm/io.h>
  78. #include <asm/irq.h>
  79. #include <asm/processor.h>
  80. #include <asm/ptrace.h>
  81. #include <asm/reboot.h>
  82. #include <asm/time.h>
  83. #include <linux/bootmem.h>
  84. #include <asm/tx4938/rbtx4938.h>
  85. static unsigned int toshiba_rbtx4938_irq_ioc_startup(unsigned int irq);
  86. static void toshiba_rbtx4938_irq_ioc_shutdown(unsigned int irq);
  87. static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq);
  88. static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq);
  89. static void toshiba_rbtx4938_irq_ioc_mask_and_ack(unsigned int irq);
  90. static void toshiba_rbtx4938_irq_ioc_end(unsigned int irq);
  91. DEFINE_SPINLOCK(toshiba_rbtx4938_ioc_lock);
  92. #define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC"
  93. static struct irq_chip toshiba_rbtx4938_irq_ioc_type = {
  94. .typename = TOSHIBA_RBTX4938_IOC_NAME,
  95. .startup = toshiba_rbtx4938_irq_ioc_startup,
  96. .shutdown = toshiba_rbtx4938_irq_ioc_shutdown,
  97. .enable = toshiba_rbtx4938_irq_ioc_enable,
  98. .disable = toshiba_rbtx4938_irq_ioc_disable,
  99. .ack = toshiba_rbtx4938_irq_ioc_mask_and_ack,
  100. .end = toshiba_rbtx4938_irq_ioc_end,
  101. .set_affinity = NULL
  102. };
  103. #define TOSHIBA_RBTX4938_IOC_INTR_ENAB 0xb7f02000
  104. #define TOSHIBA_RBTX4938_IOC_INTR_STAT 0xb7f0200a
  105. int
  106. toshiba_rbtx4938_irq_nested(int sw_irq)
  107. {
  108. u8 level3;
  109. level3 = reg_rd08(TOSHIBA_RBTX4938_IOC_INTR_STAT) & 0xff;
  110. if (level3) {
  111. /* must use fls so onboard ATA has priority */
  112. sw_irq = TOSHIBA_RBTX4938_IRQ_IOC_BEG + fls(level3) - 1;
  113. }
  114. wbflush();
  115. return sw_irq;
  116. }
  117. static struct irqaction toshiba_rbtx4938_irq_ioc_action = {
  118. .handler = no_action,
  119. .flags = 0,
  120. .mask = CPU_MASK_NONE,
  121. .name = TOSHIBA_RBTX4938_IOC_NAME,
  122. };
  123. /**********************************************************************************/
  124. /* Functions for ioc */
  125. /**********************************************************************************/
  126. static void __init
  127. toshiba_rbtx4938_irq_ioc_init(void)
  128. {
  129. int i;
  130. for (i = TOSHIBA_RBTX4938_IRQ_IOC_BEG;
  131. i <= TOSHIBA_RBTX4938_IRQ_IOC_END; i++) {
  132. irq_desc[i].status = IRQ_DISABLED;
  133. irq_desc[i].action = 0;
  134. irq_desc[i].depth = 3;
  135. irq_desc[i].chip = &toshiba_rbtx4938_irq_ioc_type;
  136. }
  137. setup_irq(RBTX4938_IRQ_IOCINT,
  138. &toshiba_rbtx4938_irq_ioc_action);
  139. }
  140. static unsigned int
  141. toshiba_rbtx4938_irq_ioc_startup(unsigned int irq)
  142. {
  143. toshiba_rbtx4938_irq_ioc_enable(irq);
  144. return 0;
  145. }
  146. static void
  147. toshiba_rbtx4938_irq_ioc_shutdown(unsigned int irq)
  148. {
  149. toshiba_rbtx4938_irq_ioc_disable(irq);
  150. }
  151. static void
  152. toshiba_rbtx4938_irq_ioc_enable(unsigned int irq)
  153. {
  154. unsigned long flags;
  155. volatile unsigned char v;
  156. spin_lock_irqsave(&toshiba_rbtx4938_ioc_lock, flags);
  157. v = TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
  158. v |= (1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG));
  159. TX4938_WR08(TOSHIBA_RBTX4938_IOC_INTR_ENAB, v);
  160. mmiowb();
  161. TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
  162. spin_unlock_irqrestore(&toshiba_rbtx4938_ioc_lock, flags);
  163. }
  164. static void
  165. toshiba_rbtx4938_irq_ioc_disable(unsigned int irq)
  166. {
  167. unsigned long flags;
  168. volatile unsigned char v;
  169. spin_lock_irqsave(&toshiba_rbtx4938_ioc_lock, flags);
  170. v = TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
  171. v &= ~(1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG));
  172. TX4938_WR08(TOSHIBA_RBTX4938_IOC_INTR_ENAB, v);
  173. mmiowb();
  174. TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
  175. spin_unlock_irqrestore(&toshiba_rbtx4938_ioc_lock, flags);
  176. }
  177. static void
  178. toshiba_rbtx4938_irq_ioc_mask_and_ack(unsigned int irq)
  179. {
  180. toshiba_rbtx4938_irq_ioc_disable(irq);
  181. }
  182. static void
  183. toshiba_rbtx4938_irq_ioc_end(unsigned int irq)
  184. {
  185. if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
  186. toshiba_rbtx4938_irq_ioc_enable(irq);
  187. }
  188. }
  189. extern void __init txx9_spi_irqinit(int irc_irq);
  190. void __init arch_init_irq(void)
  191. {
  192. extern void tx4938_irq_init(void);
  193. /* Now, interrupt control disabled, */
  194. /* all IRC interrupts are masked, */
  195. /* all IRC interrupt mode are Low Active. */
  196. /* mask all IOC interrupts */
  197. *rbtx4938_imask_ptr = 0;
  198. /* clear SoftInt interrupts */
  199. *rbtx4938_softint_ptr = 0;
  200. tx4938_irq_init();
  201. toshiba_rbtx4938_irq_ioc_init();
  202. /* Onboard 10M Ether: High Active */
  203. TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM0), 0x00000040);
  204. if (tx4938_ccfgptr->pcfg & TX4938_PCFG_SPI_SEL) {
  205. txx9_spi_irqinit(RBTX4938_IRQ_IRC_SPI);
  206. }
  207. wbflush();
  208. }