irq.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:15k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * BRIEF MODULE DESCRIPTION
  3.  * Au1000 interrupt routines.
  4.  *
  5.  * Copyright 2001 MontaVista Software Inc.
  6.  * Author: MontaVista Software, Inc.
  7.  * ppopov@mvista.com or source@mvista.com
  8.  *
  9.  *  This program is free software; you can redistribute  it and/or modify it
  10.  *  under  the terms of  the GNU General  Public License as published by the
  11.  *  Free Software Foundation;  either version 2 of the License, or (at your
  12.  *  option) any later version.
  13.  *
  14.  *  THIS  SOFTWARE  IS PROVIDED   ``AS IS'' AND   ANY EXPRESS OR IMPLIED
  15.  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
  16.  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
  17.  *  NO EVENT  SHALL   THE AUTHOR  BE  LIABLE FOR ANY   DIRECT, INDIRECT,
  18.  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19.  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS OR SERVICES; LOSS OF
  20.  *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  21.  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
  22.  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23.  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24.  *
  25.  *  You should have received a copy of the  GNU General Public License along
  26.  *  with this program; if not, write  to the Free Software Foundation, Inc.,
  27.  *  675 Mass Ave, Cambridge, MA 02139, USA.
  28.  */
  29. #include <linux/errno.h>
  30. #include <linux/init.h>
  31. #include <linux/kernel_stat.h>
  32. #include <linux/module.h>
  33. #include <linux/signal.h>
  34. #include <linux/sched.h>
  35. #include <linux/types.h>
  36. #include <linux/interrupt.h>
  37. #include <linux/ioport.h>
  38. #include <linux/timex.h>
  39. #include <linux/slab.h>
  40. #include <linux/random.h>
  41. #include <linux/delay.h>
  42. #include <asm/bitops.h>
  43. #include <asm/bootinfo.h>
  44. #include <asm/io.h>
  45. #include <asm/mipsregs.h>
  46. #include <asm/system.h>
  47. #include <asm/au1000.h>
  48. #if defined(CONFIG_MIPS_PB1000)
  49. #include <asm/pb1000.h>
  50. #elif defined(CONFIG_MIPS_PB1500)
  51. #include <asm/pb1500.h>
  52. #elif defined(CONFIG_MIPS_PB1100)
  53. #include <asm/pb1100.h>
  54. #else
  55. #error unsupported alchemy board
  56. #endif
  57. #undef DEBUG_IRQ
  58. #ifdef DEBUG_IRQ
  59. /* note: prints function name for you */
  60. #define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
  61. #else
  62. #define DPRINTK(fmt, args...)
  63. #endif
  64. #define EXT_INTC0_REQ0 2 /* IP 2 */
  65. #define EXT_INTC0_REQ1 3 /* IP 3 */
  66. #define EXT_INTC1_REQ0 4 /* IP 4 */
  67. #define EXT_INTC1_REQ1 5 /* IP 5 */
  68. #define MIPS_TIMER_IP  7 /* IP 7 */
  69. #ifdef CONFIG_REMOTE_DEBUG
  70. extern void breakpoint(void);
  71. #endif
  72. extern asmlinkage void au1000_IRQ(void);
  73. extern void set_debug_traps(void);
  74. extern irq_cpustat_t irq_stat [NR_CPUS];
  75. unsigned int local_bh_count[NR_CPUS];
  76. unsigned int local_irq_count[NR_CPUS];
  77. static void setup_local_irq(unsigned int irq, int type, int int_req);
  78. static unsigned int startup_irq(unsigned int irq);
  79. static void end_irq(unsigned int irq_nr);
  80. static inline void mask_and_ack_level_irq(unsigned int irq_nr);
  81. static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr);
  82. static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr);
  83. inline void local_enable_irq(unsigned int irq_nr);
  84. inline void local_disable_irq(unsigned int irq_nr);
  85. extern unsigned int do_IRQ(int irq, struct pt_regs *regs);
  86. extern void __init init_generic_irq(void);
  87. #ifdef CONFIG_PM
  88. extern void counter0_irq(int irq, void *dev_id, struct pt_regs *regs);
  89. #endif
  90. static void setup_local_irq(unsigned int irq_nr, int type, int int_req)
  91. {
  92. if (irq_nr > AU1000_MAX_INTR) return;
  93. /* Config2[n], Config1[n], Config0[n] */
  94. if (irq_nr > AU1000_LAST_INTC0_INT) {
  95. switch (type) {
  96. case INTC_INT_RISE_EDGE: /* 0:0:1 */
  97. au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
  98. au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
  99. au_writel(1<<(irq_nr-32), IC1_CFG0SET);
  100. break;
  101. case INTC_INT_FALL_EDGE: /* 0:1:0 */
  102. au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
  103. au_writel(1<<(irq_nr-32), IC1_CFG1SET);
  104. au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
  105. break;
  106. case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
  107. au_writel(1<<(irq_nr-32), IC1_CFG2SET);
  108. au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
  109. au_writel(1<<(irq_nr-32), IC1_CFG0SET);
  110. break;
  111. case INTC_INT_LOW_LEVEL: /* 1:1:0 */
  112. au_writel(1<<(irq_nr-32), IC1_CFG2SET);
  113. au_writel(1<<(irq_nr-32), IC1_CFG1SET);
  114. au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
  115. break;
  116. case INTC_INT_DISABLED: /* 0:0:0 */
  117. au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
  118. au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
  119. au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
  120. break;
  121. default: /* disable the interrupt */
  122. printk("unexpected int type %d (irq %d)n", type, irq_nr);
  123. au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
  124. au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
  125. au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
  126. return;
  127. }
  128. if (int_req) /* assign to interrupt request 1 */
  129. au_writel(1<<(irq_nr-32), IC1_ASSIGNCLR);
  130. else      /* assign to interrupt request 0 */
  131. au_writel(1<<(irq_nr-32), IC1_ASSIGNSET);
  132. au_writel(1<<(irq_nr-32), IC1_SRCSET);
  133. au_writel(1<<(irq_nr-32), IC1_MASKCLR);
  134. au_writel(1<<(irq_nr-32), IC1_WAKECLR);
  135. }
  136. else {
  137. switch (type) {
  138. case INTC_INT_RISE_EDGE: /* 0:0:1 */
  139. au_writel(1<<irq_nr, IC0_CFG2CLR);
  140. au_writel(1<<irq_nr, IC0_CFG1CLR);
  141. au_writel(1<<irq_nr, IC0_CFG0SET);
  142. break;
  143. case INTC_INT_FALL_EDGE: /* 0:1:0 */
  144. au_writel(1<<irq_nr, IC0_CFG2CLR);
  145. au_writel(1<<irq_nr, IC0_CFG1SET);
  146. au_writel(1<<irq_nr, IC0_CFG0CLR);
  147. break;
  148. case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
  149. au_writel(1<<irq_nr, IC0_CFG2SET);
  150. au_writel(1<<irq_nr, IC0_CFG1CLR);
  151. au_writel(1<<irq_nr, IC0_CFG0SET);
  152. break;
  153. case INTC_INT_LOW_LEVEL: /* 1:1:0 */
  154. au_writel(1<<irq_nr, IC0_CFG2SET);
  155. au_writel(1<<irq_nr, IC0_CFG1SET);
  156. au_writel(1<<irq_nr, IC0_CFG0CLR);
  157. break;
  158. case INTC_INT_DISABLED: /* 0:0:0 */
  159. au_writel(1<<irq_nr, IC0_CFG0CLR);
  160. au_writel(1<<irq_nr, IC0_CFG1CLR);
  161. au_writel(1<<irq_nr, IC0_CFG2CLR);
  162. break;
  163. default: /* disable the interrupt */
  164. printk("unexpected int type %d (irq %d)n", type, irq_nr);
  165. au_writel(1<<irq_nr, IC0_CFG0CLR);
  166. au_writel(1<<irq_nr, IC0_CFG1CLR);
  167. au_writel(1<<irq_nr, IC0_CFG2CLR);
  168. return;
  169. }
  170. if (int_req) /* assign to interrupt request 1 */
  171. au_writel(1<<irq_nr, IC0_ASSIGNCLR);
  172. else      /* assign to interrupt request 0 */
  173. au_writel(1<<irq_nr, IC0_ASSIGNSET);
  174. au_writel(1<<irq_nr, IC0_SRCSET);
  175. au_writel(1<<irq_nr, IC0_MASKCLR);
  176. au_writel(1<<irq_nr, IC0_WAKECLR);
  177. }
  178. au_sync();
  179. }
  180. static unsigned int startup_irq(unsigned int irq_nr)
  181. {
  182. local_enable_irq(irq_nr);
  183. return 0;
  184. }
  185. static void shutdown_irq(unsigned int irq_nr)
  186. {
  187. local_disable_irq(irq_nr);
  188. return;
  189. }
  190. inline void local_enable_irq(unsigned int irq_nr)
  191. {
  192. if (irq_nr > AU1000_LAST_INTC0_INT) {
  193. au_writel(1<<(irq_nr-32), IC1_MASKSET);
  194. au_writel(1<<(irq_nr-32), IC1_WAKESET);
  195. }
  196. else {
  197. au_writel(1<<irq_nr, IC0_MASKSET);
  198. au_writel(1<<irq_nr, IC0_WAKESET);
  199. }
  200. au_sync();
  201. }
  202. inline void local_disable_irq(unsigned int irq_nr)
  203. {
  204. if (irq_nr > AU1000_LAST_INTC0_INT) {
  205. au_writel(1<<(irq_nr-32), IC1_MASKCLR);
  206. au_writel(1<<(irq_nr-32), IC1_WAKECLR);
  207. }
  208. else {
  209. au_writel(1<<irq_nr, IC0_MASKCLR);
  210. au_writel(1<<irq_nr, IC0_WAKECLR);
  211. }
  212. au_sync();
  213. }
  214. static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr)
  215. {
  216. if (irq_nr > AU1000_LAST_INTC0_INT) {
  217. au_writel(1<<(irq_nr-32), IC1_RISINGCLR);
  218. au_writel(1<<(irq_nr-32), IC1_MASKCLR);
  219. }
  220. else {
  221. au_writel(1<<irq_nr, IC0_RISINGCLR);
  222. au_writel(1<<irq_nr, IC0_MASKCLR);
  223. }
  224. au_sync();
  225. }
  226. static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr)
  227. {
  228. if (irq_nr > AU1000_LAST_INTC0_INT) {
  229. au_writel(1<<(irq_nr-32), IC1_FALLINGCLR);
  230. au_writel(1<<(irq_nr-32), IC1_MASKCLR);
  231. }
  232. else {
  233. au_writel(1<<irq_nr, IC0_FALLINGCLR);
  234. au_writel(1<<irq_nr, IC0_MASKCLR);
  235. }
  236. au_sync();
  237. }
  238. static inline void mask_and_ack_level_irq(unsigned int irq_nr)
  239. {
  240. local_disable_irq(irq_nr);
  241. au_sync();
  242. #if defined(CONFIG_MIPS_PB1000)
  243. if (irq_nr == AU1000_GPIO_15) {
  244. au_writel(0x8000, PB1000_MDR); /* ack int */
  245. au_sync();
  246. }
  247. #endif
  248. return;
  249. }
  250. static void end_irq(unsigned int irq_nr)
  251. {
  252. if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
  253. local_enable_irq(irq_nr);
  254. }
  255. else {
  256. printk("warning: end_irq %d did not enable (%x)n",
  257. irq_nr, irq_desc[irq_nr].status);
  258. }
  259. #if defined(CONFIG_MIPS_PB1000)
  260. if (irq_nr == AU1000_GPIO_15) {
  261. au_writel(0x4000, PB1000_MDR); /* enable int */
  262. au_sync();
  263. }
  264. #endif
  265. }
  266. unsigned long save_local_and_disable(int controller)
  267. {
  268. int i;
  269. unsigned long flags, mask;
  270. save_and_cli(flags);
  271. if (controller) {
  272. mask = au_readl(IC1_MASKSET);
  273. for (i=32; i<64; i++) {
  274. local_disable_irq(i);
  275. }
  276. }
  277. else {
  278. mask = au_readl(IC0_MASKSET);
  279. for (i=0; i<32; i++) {
  280. local_disable_irq(i);
  281. }
  282. }
  283. restore_flags(flags);
  284. return mask;
  285. }
  286. void restore_local_and_enable(int controller, unsigned long mask)
  287. {
  288. int i;
  289. unsigned long flags, new_mask;
  290. save_and_cli(flags);
  291. for (i=0; i<32; i++) {
  292. if (mask & (1<<i)) {
  293. if (controller)
  294. local_enable_irq(i+32);
  295. else
  296. local_enable_irq(i);
  297. }
  298. }
  299. if (controller)
  300. new_mask = au_readl(IC1_MASKSET);
  301. else
  302. new_mask = au_readl(IC0_MASKSET);
  303. restore_flags(flags);
  304. }
  305. static struct hw_interrupt_type rise_edge_irq_type = {
  306. "Au1000 Rise Edge",
  307. startup_irq,
  308. shutdown_irq,
  309. local_enable_irq,
  310. local_disable_irq,
  311. mask_and_ack_rise_edge_irq,
  312. end_irq,
  313. NULL
  314. };
  315. static struct hw_interrupt_type fall_edge_irq_type = {
  316. "Au1000 Fall Edge",
  317. startup_irq,
  318. shutdown_irq,
  319. local_enable_irq,
  320. local_disable_irq,
  321. mask_and_ack_fall_edge_irq,
  322. end_irq,
  323. NULL
  324. };
  325. static struct hw_interrupt_type level_irq_type = {
  326. "Au1000 Level",
  327. startup_irq,
  328. shutdown_irq,
  329. local_enable_irq,
  330. local_disable_irq,
  331. mask_and_ack_level_irq,
  332. end_irq,
  333. NULL
  334. };
  335. #ifdef CONFIG_PM
  336. void startup_match20_interrupt(void)
  337. {
  338. local_enable_irq(AU1000_TOY_MATCH2_INT);
  339. }
  340. #endif
  341. void __init init_IRQ(void)
  342. {
  343. int i;
  344. unsigned long cp0_status;
  345. extern char except_vec0_au1000;
  346. cp0_status = read_32bit_cp0_register(CP0_STATUS);
  347. memset(irq_desc, 0, sizeof(irq_desc));
  348. set_except_vector(0, au1000_IRQ);
  349. init_generic_irq();
  350. for (i = 0; i <= AU1000_MAX_INTR; i++) {
  351. switch (i) {
  352. case AU1000_UART0_INT:
  353. case AU1000_UART3_INT:
  354. #ifdef CONFIG_MIPS_PB1000
  355. case AU1000_UART1_INT:
  356. case AU1000_UART2_INT:
  357. case AU1000_SSI0_INT:
  358. case AU1000_SSI1_INT:
  359. #endif
  360. #ifdef CONFIG_MIPS_PB1100
  361. case AU1000_UART1_INT:
  362. case AU1000_SSI0_INT:
  363. case AU1000_SSI1_INT:
  364. #endif
  365.         case AU1000_DMA_INT_BASE:
  366.         case AU1000_DMA_INT_BASE+1:
  367.         case AU1000_DMA_INT_BASE+2:
  368.         case AU1000_DMA_INT_BASE+3:
  369.         case AU1000_DMA_INT_BASE+4:
  370.         case AU1000_DMA_INT_BASE+5:
  371.         case AU1000_DMA_INT_BASE+6:
  372.         case AU1000_DMA_INT_BASE+7:
  373. case AU1000_IRDA_TX_INT:
  374. case AU1000_IRDA_RX_INT:
  375. case AU1000_MAC0_DMA_INT:
  376. #ifdef CONFIG_MIPS_PB1000
  377. case AU1000_MAC1_DMA_INT:
  378. #endif
  379. #ifdef CONFIG_MIPS_PB1500
  380. case AU1000_MAC1_DMA_INT:
  381. #endif
  382. case AU1500_GPIO_204:
  383. setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0);
  384. irq_desc[i].handler = &level_irq_type;
  385. break;
  386. #ifdef CONFIG_MIPS_PB1000
  387. case AU1000_GPIO_15:
  388. #endif
  389.         case AU1000_USB_HOST_INT:
  390. #ifdef CONFIG_MIPS_PB1500
  391. case AU1000_PCI_INTA:
  392. case AU1000_PCI_INTB:
  393. case AU1000_PCI_INTC:
  394. case AU1000_PCI_INTD:
  395. case AU1500_GPIO_201:
  396. case AU1500_GPIO_202:
  397. case AU1500_GPIO_203:
  398. case AU1500_GPIO_205:
  399. case AU1500_GPIO_207:
  400. #endif
  401. #ifdef CONFIG_MIPS_PB1100
  402. case AU1000_GPIO_9: // PCMCIA Card Fully_Interted#
  403. case AU1000_GPIO_10: // PCMCIA_STSCHG#
  404. case AU1000_GPIO_11: // PCMCIA_IRQ#
  405. case AU1000_GPIO_13: // DC_IRQ#
  406. case AU1000_GPIO_23: // 2-wire SCL
  407. #endif
  408. setup_local_irq(i, INTC_INT_LOW_LEVEL, 0);
  409. irq_desc[i].handler = &level_irq_type;
  410.                                 break;
  411. case AU1000_ACSYNC_INT:
  412. case AU1000_AC97C_INT:
  413. case AU1000_TOY_INT:
  414. case AU1000_TOY_MATCH0_INT:
  415. case AU1000_TOY_MATCH1_INT:
  416.         case AU1000_USB_DEV_SUS_INT:
  417.         case AU1000_USB_DEV_REQ_INT:
  418. case AU1000_RTC_INT:
  419. case AU1000_RTC_MATCH0_INT:
  420. case AU1000_RTC_MATCH1_INT:
  421. case AU1000_RTC_MATCH2_INT:
  422.         setup_local_irq(i, INTC_INT_RISE_EDGE, 0);
  423.                                 irq_desc[i].handler = &rise_edge_irq_type;
  424.                                 break;
  425.  // Careful if you change match 2 request!
  426.  // The interrupt handler is called directly
  427.  // from the low level dispatch code.
  428. case AU1000_TOY_MATCH2_INT:
  429.  setup_local_irq(i, INTC_INT_RISE_EDGE, 1);
  430.  irq_desc[i].handler = &rise_edge_irq_type;
  431.   break;
  432. default: /* active high, level interrupt */
  433. setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0);
  434. irq_desc[i].handler = &level_irq_type;
  435. break;
  436. }
  437. }
  438. set_cp0_status(ALLINTS);
  439. #ifdef CONFIG_REMOTE_DEBUG
  440. /* If local serial I/O used for debug port, enter kgdb at once */
  441. puts("Waiting for kgdb to connect...");
  442. set_debug_traps();
  443. breakpoint();
  444. #endif
  445. }
  446. /*
  447.  * Interrupts are nested. Even if an interrupt handler is registered
  448.  * as "fast", we might get another interrupt before we return from
  449.  * intcX_reqX_irqdispatch().
  450.  */
  451. void intc0_req0_irqdispatch(struct pt_regs *regs)
  452. {
  453. int irq = 0, i;
  454. static unsigned long intc0_req0 = 0;
  455. intc0_req0 |= au_readl(IC0_REQ0INT);
  456. if (!intc0_req0) return;
  457. /*
  458.  * Because of the tight timing of SETUP token to reply
  459.  * transactions, the USB devices-side packet complete
  460.  * interrupt needs the highest priority.
  461.  */
  462. if ((intc0_req0 & (1<<AU1000_USB_DEV_REQ_INT))) {
  463. intc0_req0 &= ~(1<<AU1000_USB_DEV_REQ_INT);
  464. do_IRQ(AU1000_USB_DEV_REQ_INT, regs);
  465. return;
  466. }
  467. for (i=0; i<32; i++) {
  468. if ((intc0_req0 & (1<<i))) {
  469. intc0_req0 &= ~(1<<i);
  470. do_IRQ(irq, regs);
  471. break;
  472. }
  473. irq++;
  474. }
  475. }
  476. void intc0_req1_irqdispatch(struct pt_regs *regs)
  477. {
  478. int irq = 0, i;
  479. static unsigned long intc0_req1 = 0;
  480. intc0_req1 = au_readl(IC0_REQ1INT);
  481. if (!intc0_req1) return;
  482. for (i=0; i<32; i++) {
  483. if ((intc0_req1 & (1<<i))) {
  484. intc0_req1 &= ~(1<<i);
  485. #ifdef CONFIG_PM
  486. if (i == AU1000_TOY_MATCH2_INT) {
  487. mask_and_ack_rise_edge_irq(irq);
  488. counter0_irq(irq, NULL, regs);
  489. local_enable_irq(irq);
  490. }
  491. else
  492. #endif
  493. {
  494. do_IRQ(irq, regs);
  495. }
  496. break;
  497. }
  498. irq++;
  499. }
  500. }
  501. /*
  502.  * Interrupt Controller 1:
  503.  * interrupts 32 - 63
  504.  */
  505. void intc1_req0_irqdispatch(struct pt_regs *regs)
  506. {
  507. int irq = 0, i;
  508. static unsigned long intc1_req0 = 0;
  509. volatile unsigned short levels, mdr;
  510. unsigned char ide_status;
  511. intc1_req0 |= au_readl(IC1_REQ0INT);
  512. if (!intc1_req0) return;
  513. #if defined(CONFIG_MIPS_PB1000) && defined(DEBUG_IRQ)
  514. au_writel(1, CPLD_AUX0); /* debug led 0 */
  515. #endif
  516. for (i=0; i<32; i++) {
  517. if ((intc1_req0 & (1<<i))) {
  518. intc1_req0 &= ~(1<<i);
  519. #if defined(CONFIG_MIPS_PB1000) && defined(DEBUG_IRQ)
  520. au_writel(2, CPLD_AUX0); /* turn on debug led 1  */
  521. do_IRQ(irq+32, regs);
  522. au_writel(0, CPLD_AUX0); /* turn off debug led 1 */
  523. #else
  524. do_IRQ(irq+32, regs);
  525. #endif
  526. break;
  527. }
  528. irq++;
  529. }
  530. #if defined(CONFIG_MIPS_PB1000) && defined(DEBUG_IRQ)
  531. au_writel(0, CPLD_AUX0);
  532. #endif
  533. }
  534. void intc1_req1_irqdispatch(struct pt_regs *regs)
  535. {
  536. int irq = 0, i;
  537. static unsigned long intc1_req1 = 0;
  538. intc1_req1 |= au_readl(IC1_REQ1INT);
  539. if (!intc1_req1) return;
  540. for (i=0; i<32; i++) {
  541. if ((intc1_req1 & (1<<i))) {
  542. intc1_req1 &= ~(1<<i);
  543. do_IRQ(irq+32, regs);
  544. break;
  545. }
  546. irq++;
  547. }
  548. }