irq.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. /*
  2. * Copyright 2001, 2007-2008 MontaVista Software Inc.
  3. * Author: MontaVista Software, Inc. <source@mvista.com>
  4. *
  5. * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation; either version 2 of the License, or (at your
  10. * option) any later version.
  11. *
  12. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  13. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  14. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
  15. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  16. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  17. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  18. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  19. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  20. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  21. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  22. *
  23. * You should have received a copy of the GNU General Public License along
  24. * with this program; if not, write to the Free Software Foundation, Inc.,
  25. * 675 Mass Ave, Cambridge, MA 02139, USA.
  26. */
  27. #include <linux/bitops.h>
  28. #include <linux/init.h>
  29. #include <linux/interrupt.h>
  30. #include <linux/irq.h>
  31. #include <linux/slab.h>
  32. #include <linux/sysdev.h>
  33. #include <asm/irq_cpu.h>
  34. #include <asm/mipsregs.h>
  35. #include <asm/mach-au1x00/au1000.h>
  36. #ifdef CONFIG_MIPS_PB1000
  37. #include <asm/mach-pb1x00/pb1000.h>
  38. #endif
  39. static int au1x_ic_settype(unsigned int irq, unsigned int flow_type);
  40. /* NOTE on interrupt priorities: The original writers of this code said:
  41. *
  42. * Because of the tight timing of SETUP token to reply transactions,
  43. * the USB devices-side packet complete interrupt (USB_DEV_REQ_INT)
  44. * needs the highest priority.
  45. */
  46. /* per-processor fixed function irqs */
  47. struct au1xxx_irqmap {
  48. int im_irq;
  49. int im_type;
  50. int im_request; /* set 1 to get higher priority */
  51. };
  52. struct au1xxx_irqmap au1000_irqmap[] __initdata = {
  53. { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  54. { AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  55. { AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  56. { AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  57. { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  58. { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  59. { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
  60. { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
  61. { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
  62. { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
  63. { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
  64. { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
  65. { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
  66. { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
  67. { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
  68. { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
  69. { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
  70. { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
  71. { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
  72. { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
  73. { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
  74. { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
  75. { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  76. { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  77. { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
  78. { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
  79. { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
  80. { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
  81. { AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  82. { AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  83. { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
  84. { -1, },
  85. };
  86. struct au1xxx_irqmap au1500_irqmap[] __initdata = {
  87. { AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  88. { AU1500_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
  89. { AU1500_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
  90. { AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  91. { AU1500_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
  92. { AU1500_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
  93. { AU1500_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
  94. { AU1500_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
  95. { AU1500_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
  96. { AU1500_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
  97. { AU1500_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
  98. { AU1500_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
  99. { AU1500_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
  100. { AU1500_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
  101. { AU1500_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
  102. { AU1500_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
  103. { AU1500_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
  104. { AU1500_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
  105. { AU1500_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
  106. { AU1500_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
  107. { AU1500_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
  108. { AU1500_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
  109. { AU1500_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
  110. { AU1500_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
  111. { AU1500_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
  112. { AU1500_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
  113. { AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  114. { AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  115. { AU1500_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
  116. { -1, },
  117. };
  118. struct au1xxx_irqmap au1100_irqmap[] __initdata = {
  119. { AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  120. { AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  121. { AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  122. { AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  123. { AU1100_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  124. { AU1100_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  125. { AU1100_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
  126. { AU1100_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
  127. { AU1100_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
  128. { AU1100_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
  129. { AU1100_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
  130. { AU1100_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
  131. { AU1100_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
  132. { AU1100_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
  133. { AU1100_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
  134. { AU1100_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
  135. { AU1100_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
  136. { AU1100_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
  137. { AU1100_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
  138. { AU1100_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
  139. { AU1100_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
  140. { AU1100_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
  141. { AU1100_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  142. { AU1100_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  143. { AU1100_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
  144. { AU1100_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
  145. { AU1100_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
  146. { AU1100_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
  147. { AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  148. { AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  149. { AU1100_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
  150. { -1, },
  151. };
  152. struct au1xxx_irqmap au1550_irqmap[] __initdata = {
  153. { AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  154. { AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
  155. { AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
  156. { AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  157. { AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  158. { AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
  159. { AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
  160. { AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
  161. { AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  162. { AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  163. { AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  164. { AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  165. { AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  166. { AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  167. { AU1550_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
  168. { AU1550_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
  169. { AU1550_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
  170. { AU1550_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
  171. { AU1550_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
  172. { AU1550_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
  173. { AU1550_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
  174. { AU1550_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
  175. { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
  176. { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
  177. { AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
  178. { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
  179. { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  180. { AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  181. { -1, },
  182. };
  183. struct au1xxx_irqmap au1200_irqmap[] __initdata = {
  184. { AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  185. { AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 0 },
  186. { AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  187. { AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  188. { AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  189. { AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  190. { AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  191. { AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  192. { AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  193. { AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  194. { AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  195. { AU1200_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
  196. { AU1200_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
  197. { AU1200_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
  198. { AU1200_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
  199. { AU1200_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
  200. { AU1200_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
  201. { AU1200_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
  202. { AU1200_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
  203. { AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
  204. { AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  205. { AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  206. { AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
  207. { -1, },
  208. };
  209. static void au1x_ic0_unmask(unsigned int irq_nr)
  210. {
  211. unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
  212. au_writel(1 << bit, IC0_MASKSET);
  213. au_writel(1 << bit, IC0_WAKESET);
  214. au_sync();
  215. }
  216. static void au1x_ic1_unmask(unsigned int irq_nr)
  217. {
  218. unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
  219. au_writel(1 << bit, IC1_MASKSET);
  220. au_writel(1 << bit, IC1_WAKESET);
  221. /* very hacky. does the pb1000 cpld auto-disable this int?
  222. * nowhere in the current kernel sources is it disabled. --mlau
  223. */
  224. #if defined(CONFIG_MIPS_PB1000)
  225. if (irq_nr == AU1000_GPIO15_INT)
  226. au_writel(0x4000, PB1000_MDR); /* enable int */
  227. #endif
  228. au_sync();
  229. }
  230. static void au1x_ic0_mask(unsigned int irq_nr)
  231. {
  232. unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
  233. au_writel(1 << bit, IC0_MASKCLR);
  234. au_writel(1 << bit, IC0_WAKECLR);
  235. au_sync();
  236. }
  237. static void au1x_ic1_mask(unsigned int irq_nr)
  238. {
  239. unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
  240. au_writel(1 << bit, IC1_MASKCLR);
  241. au_writel(1 << bit, IC1_WAKECLR);
  242. au_sync();
  243. }
  244. static void au1x_ic0_ack(unsigned int irq_nr)
  245. {
  246. unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
  247. /*
  248. * This may assume that we don't get interrupts from
  249. * both edges at once, or if we do, that we don't care.
  250. */
  251. au_writel(1 << bit, IC0_FALLINGCLR);
  252. au_writel(1 << bit, IC0_RISINGCLR);
  253. au_sync();
  254. }
  255. static void au1x_ic1_ack(unsigned int irq_nr)
  256. {
  257. unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
  258. /*
  259. * This may assume that we don't get interrupts from
  260. * both edges at once, or if we do, that we don't care.
  261. */
  262. au_writel(1 << bit, IC1_FALLINGCLR);
  263. au_writel(1 << bit, IC1_RISINGCLR);
  264. au_sync();
  265. }
  266. static void au1x_ic0_maskack(unsigned int irq_nr)
  267. {
  268. unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
  269. au_writel(1 << bit, IC0_WAKECLR);
  270. au_writel(1 << bit, IC0_MASKCLR);
  271. au_writel(1 << bit, IC0_RISINGCLR);
  272. au_writel(1 << bit, IC0_FALLINGCLR);
  273. au_sync();
  274. }
  275. static void au1x_ic1_maskack(unsigned int irq_nr)
  276. {
  277. unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
  278. au_writel(1 << bit, IC1_WAKECLR);
  279. au_writel(1 << bit, IC1_MASKCLR);
  280. au_writel(1 << bit, IC1_RISINGCLR);
  281. au_writel(1 << bit, IC1_FALLINGCLR);
  282. au_sync();
  283. }
  284. static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
  285. {
  286. int bit = irq - AU1000_INTC1_INT_BASE;
  287. unsigned long wakemsk, flags;
  288. /* only GPIO 0-7 can act as wakeup source. Fortunately these
  289. * are wired up identically on all supported variants.
  290. */
  291. if ((bit < 0) || (bit > 7))
  292. return -EINVAL;
  293. local_irq_save(flags);
  294. wakemsk = au_readl(SYS_WAKEMSK);
  295. if (on)
  296. wakemsk |= 1 << bit;
  297. else
  298. wakemsk &= ~(1 << bit);
  299. au_writel(wakemsk, SYS_WAKEMSK);
  300. au_sync();
  301. local_irq_restore(flags);
  302. return 0;
  303. }
  304. /*
  305. * irq_chips for both ICs; this way the mask handlers can be
  306. * as short as possible.
  307. */
  308. static struct irq_chip au1x_ic0_chip = {
  309. .name = "Alchemy-IC0",
  310. .ack = au1x_ic0_ack,
  311. .mask = au1x_ic0_mask,
  312. .mask_ack = au1x_ic0_maskack,
  313. .unmask = au1x_ic0_unmask,
  314. .set_type = au1x_ic_settype,
  315. };
  316. static struct irq_chip au1x_ic1_chip = {
  317. .name = "Alchemy-IC1",
  318. .ack = au1x_ic1_ack,
  319. .mask = au1x_ic1_mask,
  320. .mask_ack = au1x_ic1_maskack,
  321. .unmask = au1x_ic1_unmask,
  322. .set_type = au1x_ic_settype,
  323. .set_wake = au1x_ic1_setwake,
  324. };
  325. static int au1x_ic_settype(unsigned int irq, unsigned int flow_type)
  326. {
  327. struct irq_chip *chip;
  328. unsigned long icr[6];
  329. unsigned int bit, ic;
  330. int ret;
  331. if (irq >= AU1000_INTC1_INT_BASE) {
  332. bit = irq - AU1000_INTC1_INT_BASE;
  333. chip = &au1x_ic1_chip;
  334. ic = 1;
  335. } else {
  336. bit = irq - AU1000_INTC0_INT_BASE;
  337. chip = &au1x_ic0_chip;
  338. ic = 0;
  339. }
  340. if (bit > 31)
  341. return -EINVAL;
  342. icr[0] = ic ? IC1_CFG0SET : IC0_CFG0SET;
  343. icr[1] = ic ? IC1_CFG1SET : IC0_CFG1SET;
  344. icr[2] = ic ? IC1_CFG2SET : IC0_CFG2SET;
  345. icr[3] = ic ? IC1_CFG0CLR : IC0_CFG0CLR;
  346. icr[4] = ic ? IC1_CFG1CLR : IC0_CFG1CLR;
  347. icr[5] = ic ? IC1_CFG2CLR : IC0_CFG2CLR;
  348. ret = 0;
  349. switch (flow_type) { /* cfgregs 2:1:0 */
  350. case IRQ_TYPE_EDGE_RISING: /* 0:0:1 */
  351. au_writel(1 << bit, icr[5]);
  352. au_writel(1 << bit, icr[4]);
  353. au_writel(1 << bit, icr[0]);
  354. set_irq_chip_and_handler_name(irq, chip,
  355. handle_edge_irq, "riseedge");
  356. break;
  357. case IRQ_TYPE_EDGE_FALLING: /* 0:1:0 */
  358. au_writel(1 << bit, icr[5]);
  359. au_writel(1 << bit, icr[1]);
  360. au_writel(1 << bit, icr[3]);
  361. set_irq_chip_and_handler_name(irq, chip,
  362. handle_edge_irq, "falledge");
  363. break;
  364. case IRQ_TYPE_EDGE_BOTH: /* 0:1:1 */
  365. au_writel(1 << bit, icr[5]);
  366. au_writel(1 << bit, icr[1]);
  367. au_writel(1 << bit, icr[0]);
  368. set_irq_chip_and_handler_name(irq, chip,
  369. handle_edge_irq, "bothedge");
  370. break;
  371. case IRQ_TYPE_LEVEL_HIGH: /* 1:0:1 */
  372. au_writel(1 << bit, icr[2]);
  373. au_writel(1 << bit, icr[4]);
  374. au_writel(1 << bit, icr[0]);
  375. set_irq_chip_and_handler_name(irq, chip,
  376. handle_level_irq, "hilevel");
  377. break;
  378. case IRQ_TYPE_LEVEL_LOW: /* 1:1:0 */
  379. au_writel(1 << bit, icr[2]);
  380. au_writel(1 << bit, icr[1]);
  381. au_writel(1 << bit, icr[3]);
  382. set_irq_chip_and_handler_name(irq, chip,
  383. handle_level_irq, "lowlevel");
  384. break;
  385. case IRQ_TYPE_NONE: /* 0:0:0 */
  386. au_writel(1 << bit, icr[5]);
  387. au_writel(1 << bit, icr[4]);
  388. au_writel(1 << bit, icr[3]);
  389. /* set at least chip so we can call set_irq_type() on it */
  390. set_irq_chip(irq, chip);
  391. break;
  392. default:
  393. ret = -EINVAL;
  394. }
  395. au_sync();
  396. return ret;
  397. }
  398. asmlinkage void plat_irq_dispatch(void)
  399. {
  400. unsigned int pending = read_c0_status() & read_c0_cause();
  401. unsigned long s, off;
  402. if (pending & CAUSEF_IP7) {
  403. off = MIPS_CPU_IRQ_BASE + 7;
  404. goto handle;
  405. } else if (pending & CAUSEF_IP2) {
  406. s = IC0_REQ0INT;
  407. off = AU1000_INTC0_INT_BASE;
  408. } else if (pending & CAUSEF_IP3) {
  409. s = IC0_REQ1INT;
  410. off = AU1000_INTC0_INT_BASE;
  411. } else if (pending & CAUSEF_IP4) {
  412. s = IC1_REQ0INT;
  413. off = AU1000_INTC1_INT_BASE;
  414. } else if (pending & CAUSEF_IP5) {
  415. s = IC1_REQ1INT;
  416. off = AU1000_INTC1_INT_BASE;
  417. } else
  418. goto spurious;
  419. s = au_readl(s);
  420. if (unlikely(!s)) {
  421. spurious:
  422. spurious_interrupt();
  423. return;
  424. }
  425. off += __ffs(s);
  426. handle:
  427. do_IRQ(off);
  428. }
  429. static void __init au1000_init_irq(struct au1xxx_irqmap *map)
  430. {
  431. unsigned int bit, irq_nr;
  432. int i;
  433. /*
  434. * Initialize interrupt controllers to a safe state.
  435. */
  436. au_writel(0xffffffff, IC0_CFG0CLR);
  437. au_writel(0xffffffff, IC0_CFG1CLR);
  438. au_writel(0xffffffff, IC0_CFG2CLR);
  439. au_writel(0xffffffff, IC0_MASKCLR);
  440. au_writel(0xffffffff, IC0_ASSIGNCLR);
  441. au_writel(0xffffffff, IC0_WAKECLR);
  442. au_writel(0xffffffff, IC0_SRCSET);
  443. au_writel(0xffffffff, IC0_FALLINGCLR);
  444. au_writel(0xffffffff, IC0_RISINGCLR);
  445. au_writel(0x00000000, IC0_TESTBIT);
  446. au_writel(0xffffffff, IC1_CFG0CLR);
  447. au_writel(0xffffffff, IC1_CFG1CLR);
  448. au_writel(0xffffffff, IC1_CFG2CLR);
  449. au_writel(0xffffffff, IC1_MASKCLR);
  450. au_writel(0xffffffff, IC1_ASSIGNCLR);
  451. au_writel(0xffffffff, IC1_WAKECLR);
  452. au_writel(0xffffffff, IC1_SRCSET);
  453. au_writel(0xffffffff, IC1_FALLINGCLR);
  454. au_writel(0xffffffff, IC1_RISINGCLR);
  455. au_writel(0x00000000, IC1_TESTBIT);
  456. mips_cpu_irq_init();
  457. /* register all 64 possible IC0+IC1 irq sources as type "none".
  458. * Use set_irq_type() to set edge/level behaviour at runtime.
  459. */
  460. for (i = AU1000_INTC0_INT_BASE;
  461. (i < AU1000_INTC0_INT_BASE + 32); i++)
  462. au1x_ic_settype(i, IRQ_TYPE_NONE);
  463. for (i = AU1000_INTC1_INT_BASE;
  464. (i < AU1000_INTC1_INT_BASE + 32); i++)
  465. au1x_ic_settype(i, IRQ_TYPE_NONE);
  466. /*
  467. * Initialize IC0, which is fixed per processor.
  468. */
  469. while (map->im_irq != -1) {
  470. irq_nr = map->im_irq;
  471. if (irq_nr >= AU1000_INTC1_INT_BASE) {
  472. bit = irq_nr - AU1000_INTC1_INT_BASE;
  473. if (map->im_request)
  474. au_writel(1 << bit, IC1_ASSIGNSET);
  475. } else {
  476. bit = irq_nr - AU1000_INTC0_INT_BASE;
  477. if (map->im_request)
  478. au_writel(1 << bit, IC0_ASSIGNSET);
  479. }
  480. au1x_ic_settype(irq_nr, map->im_type);
  481. ++map;
  482. }
  483. set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3);
  484. }
  485. void __init arch_init_irq(void)
  486. {
  487. switch (alchemy_get_cputype()) {
  488. case ALCHEMY_CPU_AU1000:
  489. au1000_init_irq(au1000_irqmap);
  490. break;
  491. case ALCHEMY_CPU_AU1500:
  492. au1000_init_irq(au1500_irqmap);
  493. break;
  494. case ALCHEMY_CPU_AU1100:
  495. au1000_init_irq(au1100_irqmap);
  496. break;
  497. case ALCHEMY_CPU_AU1550:
  498. au1000_init_irq(au1550_irqmap);
  499. break;
  500. case ALCHEMY_CPU_AU1200:
  501. au1000_init_irq(au1200_irqmap);
  502. break;
  503. }
  504. }
  505. struct alchemy_ic_sysdev {
  506. struct sys_device sysdev;
  507. void __iomem *base;
  508. unsigned long pmdata[7];
  509. };
  510. static int alchemy_ic_suspend(struct sys_device *dev, pm_message_t state)
  511. {
  512. struct alchemy_ic_sysdev *icdev =
  513. container_of(dev, struct alchemy_ic_sysdev, sysdev);
  514. icdev->pmdata[0] = __raw_readl(icdev->base + IC_CFG0RD);
  515. icdev->pmdata[1] = __raw_readl(icdev->base + IC_CFG1RD);
  516. icdev->pmdata[2] = __raw_readl(icdev->base + IC_CFG2RD);
  517. icdev->pmdata[3] = __raw_readl(icdev->base + IC_SRCRD);
  518. icdev->pmdata[4] = __raw_readl(icdev->base + IC_ASSIGNRD);
  519. icdev->pmdata[5] = __raw_readl(icdev->base + IC_WAKERD);
  520. icdev->pmdata[6] = __raw_readl(icdev->base + IC_MASKRD);
  521. return 0;
  522. }
  523. static int alchemy_ic_resume(struct sys_device *dev)
  524. {
  525. struct alchemy_ic_sysdev *icdev =
  526. container_of(dev, struct alchemy_ic_sysdev, sysdev);
  527. __raw_writel(0xffffffff, icdev->base + IC_MASKCLR);
  528. __raw_writel(0xffffffff, icdev->base + IC_CFG0CLR);
  529. __raw_writel(0xffffffff, icdev->base + IC_CFG1CLR);
  530. __raw_writel(0xffffffff, icdev->base + IC_CFG2CLR);
  531. __raw_writel(0xffffffff, icdev->base + IC_SRCCLR);
  532. __raw_writel(0xffffffff, icdev->base + IC_ASSIGNCLR);
  533. __raw_writel(0xffffffff, icdev->base + IC_WAKECLR);
  534. __raw_writel(0xffffffff, icdev->base + IC_RISINGCLR);
  535. __raw_writel(0xffffffff, icdev->base + IC_FALLINGCLR);
  536. __raw_writel(0x00000000, icdev->base + IC_TESTBIT);
  537. wmb();
  538. __raw_writel(icdev->pmdata[0], icdev->base + IC_CFG0SET);
  539. __raw_writel(icdev->pmdata[1], icdev->base + IC_CFG1SET);
  540. __raw_writel(icdev->pmdata[2], icdev->base + IC_CFG2SET);
  541. __raw_writel(icdev->pmdata[3], icdev->base + IC_SRCSET);
  542. __raw_writel(icdev->pmdata[4], icdev->base + IC_ASSIGNSET);
  543. __raw_writel(icdev->pmdata[5], icdev->base + IC_WAKESET);
  544. wmb();
  545. __raw_writel(icdev->pmdata[6], icdev->base + IC_MASKSET);
  546. wmb();
  547. return 0;
  548. }
  549. static struct sysdev_class alchemy_ic_sysdev_class = {
  550. .name = "ic",
  551. .suspend = alchemy_ic_suspend,
  552. .resume = alchemy_ic_resume,
  553. };
  554. static int __init alchemy_ic_sysdev_init(void)
  555. {
  556. struct alchemy_ic_sysdev *icdev;
  557. unsigned long icbase[2] = { IC0_PHYS_ADDR, IC1_PHYS_ADDR };
  558. int err, i;
  559. err = sysdev_class_register(&alchemy_ic_sysdev_class);
  560. if (err)
  561. return err;
  562. for (i = 0; i < 2; i++) {
  563. icdev = kzalloc(sizeof(struct alchemy_ic_sysdev), GFP_KERNEL);
  564. if (!icdev)
  565. return -ENOMEM;
  566. icdev->base = ioremap(icbase[i], 0x1000);
  567. icdev->sysdev.id = i;
  568. icdev->sysdev.cls = &alchemy_ic_sysdev_class;
  569. err = sysdev_register(&icdev->sysdev);
  570. if (err) {
  571. kfree(icdev);
  572. return err;
  573. }
  574. }
  575. return 0;
  576. }
  577. device_initcall(alchemy_ic_sysdev_init);