ints-priority-sc.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. /*
  2. * File: arch/blackfin/mach-common/ints-priority-sc.c
  3. * Based on:
  4. * Author:
  5. *
  6. * Created: ?
  7. * Description: Set up the interrupt priorities
  8. *
  9. * Modified:
  10. * 1996 Roman Zippel
  11. * 1999 D. Jeff Dionne <jeff@uclinux.org>
  12. * 2000-2001 Lineo, Inc. D. Jefff Dionne <jeff@lineo.ca>
  13. * 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca>
  14. * 2003 Metrowerks/Motorola
  15. * 2003 Bas Vermeulen <bas@buyways.nl>
  16. * Copyright 2004-2007 Analog Devices Inc.
  17. *
  18. * Bugs: Enter bugs at http://blackfin.uclinux.org/
  19. *
  20. * This program is free software; you can redistribute it and/or modify
  21. * it under the terms of the GNU General Public License as published by
  22. * the Free Software Foundation; either version 2 of the License, or
  23. * (at your option) any later version.
  24. *
  25. * This program is distributed in the hope that it will be useful,
  26. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  28. * GNU General Public License for more details.
  29. *
  30. * You should have received a copy of the GNU General Public License
  31. * along with this program; if not, see the file COPYING, or write
  32. * to the Free Software Foundation, Inc.,
  33. * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  34. */
  35. #include <linux/module.h>
  36. #include <linux/kernel_stat.h>
  37. #include <linux/seq_file.h>
  38. #include <linux/irq.h>
  39. #ifdef CONFIG_KGDB
  40. #include <linux/kgdb.h>
  41. #endif
  42. #include <asm/traps.h>
  43. #include <asm/blackfin.h>
  44. #include <asm/gpio.h>
  45. #include <asm/irq_handler.h>
  46. #ifdef BF537_FAMILY
  47. # define BF537_GENERIC_ERROR_INT_DEMUX
  48. #else
  49. # undef BF537_GENERIC_ERROR_INT_DEMUX
  50. #endif
  51. /*
  52. * NOTES:
  53. * - we have separated the physical Hardware interrupt from the
  54. * levels that the LINUX kernel sees (see the description in irq.h)
  55. * -
  56. */
  57. unsigned long irq_flags = 0;
  58. /* The number of spurious interrupts */
  59. atomic_t num_spurious;
  60. struct ivgx {
  61. /* irq number for request_irq, available in mach-bf533/irq.h */
  62. unsigned int irqno;
  63. /* corresponding bit in the SIC_ISR register */
  64. unsigned int isrflag;
  65. } ivg_table[NR_PERI_INTS];
  66. struct ivg_slice {
  67. /* position of first irq in ivg_table for given ivg */
  68. struct ivgx *ifirst;
  69. struct ivgx *istop;
  70. } ivg7_13[IVG13 - IVG7 + 1];
  71. static void search_IAR(void);
  72. /*
  73. * Search SIC_IAR and fill tables with the irqvalues
  74. * and their positions in the SIC_ISR register.
  75. */
  76. static void __init search_IAR(void)
  77. {
  78. unsigned ivg, irq_pos = 0;
  79. for (ivg = 0; ivg <= IVG13 - IVG7; ivg++) {
  80. int irqn;
  81. ivg7_13[ivg].istop = ivg7_13[ivg].ifirst =
  82. &ivg_table[irq_pos];
  83. for (irqn = 0; irqn < NR_PERI_INTS; irqn++) {
  84. int iar_shift = (irqn & 7) * 4;
  85. if (ivg ==
  86. (0xf &
  87. bfin_read32((unsigned long *) SIC_IAR0 +
  88. (irqn >> 3)) >> iar_shift)) {
  89. ivg_table[irq_pos].irqno = IVG7 + irqn;
  90. ivg_table[irq_pos].isrflag = 1 << (irqn % 32);
  91. ivg7_13[ivg].istop++;
  92. irq_pos++;
  93. }
  94. }
  95. }
  96. }
  97. /*
  98. * This is for BF533 internal IRQs
  99. */
  100. static void ack_noop(unsigned int irq)
  101. {
  102. /* Dummy function. */
  103. }
  104. static void bfin_core_mask_irq(unsigned int irq)
  105. {
  106. irq_flags &= ~(1 << irq);
  107. if (!irqs_disabled())
  108. local_irq_enable();
  109. }
  110. static void bfin_core_unmask_irq(unsigned int irq)
  111. {
  112. irq_flags |= 1 << irq;
  113. /*
  114. * If interrupts are enabled, IMASK must contain the same value
  115. * as irq_flags. Make sure that invariant holds. If interrupts
  116. * are currently disabled we need not do anything; one of the
  117. * callers will take care of setting IMASK to the proper value
  118. * when reenabling interrupts.
  119. * local_irq_enable just does "STI irq_flags", so it's exactly
  120. * what we need.
  121. */
  122. if (!irqs_disabled())
  123. local_irq_enable();
  124. return;
  125. }
  126. static void bfin_internal_mask_irq(unsigned int irq)
  127. {
  128. #ifndef CONFIG_BF54x
  129. bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
  130. ~(1 << (irq - (IRQ_CORETMR + 1))));
  131. #else
  132. unsigned mask_bank, mask_bit;
  133. mask_bank = (irq - (IRQ_CORETMR +1))/32;
  134. mask_bit = (irq - (IRQ_CORETMR + 1))%32;
  135. bfin_write_SIC_IMASK( mask_bank, bfin_read_SIC_IMASK(mask_bank) & \
  136. ~(1 << mask_bit));
  137. #endif
  138. SSYNC();
  139. }
  140. static void bfin_internal_unmask_irq(unsigned int irq)
  141. {
  142. #ifndef CONFIG_BF54x
  143. bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
  144. (1 << (irq - (IRQ_CORETMR + 1))));
  145. #else
  146. unsigned mask_bank, mask_bit;
  147. mask_bank = (irq - (IRQ_CORETMR +1))/32;
  148. mask_bit = (irq - (IRQ_CORETMR + 1))%32;
  149. bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) | \
  150. ( 1 << mask_bit));
  151. #endif
  152. SSYNC();
  153. }
  154. static struct irq_chip bfin_core_irqchip = {
  155. .ack = ack_noop,
  156. .mask = bfin_core_mask_irq,
  157. .unmask = bfin_core_unmask_irq,
  158. };
  159. static struct irq_chip bfin_internal_irqchip = {
  160. .ack = ack_noop,
  161. .mask = bfin_internal_mask_irq,
  162. .unmask = bfin_internal_unmask_irq,
  163. };
  164. #ifdef BF537_GENERIC_ERROR_INT_DEMUX
  165. static int error_int_mask;
  166. static void bfin_generic_error_ack_irq(unsigned int irq)
  167. {
  168. }
  169. static void bfin_generic_error_mask_irq(unsigned int irq)
  170. {
  171. error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR));
  172. if (!error_int_mask) {
  173. local_irq_disable();
  174. bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
  175. ~(1 <<
  176. (IRQ_GENERIC_ERROR -
  177. (IRQ_CORETMR + 1))));
  178. SSYNC();
  179. local_irq_enable();
  180. }
  181. }
  182. static void bfin_generic_error_unmask_irq(unsigned int irq)
  183. {
  184. local_irq_disable();
  185. bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | 1 <<
  186. (IRQ_GENERIC_ERROR - (IRQ_CORETMR + 1)));
  187. SSYNC();
  188. local_irq_enable();
  189. error_int_mask |= 1L << (irq - IRQ_PPI_ERROR);
  190. }
  191. static struct irq_chip bfin_generic_error_irqchip = {
  192. .ack = bfin_generic_error_ack_irq,
  193. .mask = bfin_generic_error_mask_irq,
  194. .unmask = bfin_generic_error_unmask_irq,
  195. };
  196. static void bfin_demux_error_irq(unsigned int int_err_irq,
  197. struct irq_desc *intb_desc)
  198. {
  199. int irq = 0;
  200. SSYNC();
  201. #if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
  202. if (bfin_read_EMAC_SYSTAT() & EMAC_ERR_MASK)
  203. irq = IRQ_MAC_ERROR;
  204. else
  205. #endif
  206. if (bfin_read_SPORT0_STAT() & SPORT_ERR_MASK)
  207. irq = IRQ_SPORT0_ERROR;
  208. else if (bfin_read_SPORT1_STAT() & SPORT_ERR_MASK)
  209. irq = IRQ_SPORT1_ERROR;
  210. else if (bfin_read_PPI_STATUS() & PPI_ERR_MASK)
  211. irq = IRQ_PPI_ERROR;
  212. else if (bfin_read_CAN_GIF() & CAN_ERR_MASK)
  213. irq = IRQ_CAN_ERROR;
  214. else if (bfin_read_SPI_STAT() & SPI_ERR_MASK)
  215. irq = IRQ_SPI_ERROR;
  216. else if ((bfin_read_UART0_IIR() & UART_ERR_MASK_STAT1) &&
  217. (bfin_read_UART0_IIR() & UART_ERR_MASK_STAT0))
  218. irq = IRQ_UART0_ERROR;
  219. else if ((bfin_read_UART1_IIR() & UART_ERR_MASK_STAT1) &&
  220. (bfin_read_UART1_IIR() & UART_ERR_MASK_STAT0))
  221. irq = IRQ_UART1_ERROR;
  222. if (irq) {
  223. if (error_int_mask & (1L << (irq - IRQ_PPI_ERROR))) {
  224. struct irq_desc *desc = irq_desc + irq;
  225. desc->handle_irq(irq, desc);
  226. } else {
  227. switch (irq) {
  228. case IRQ_PPI_ERROR:
  229. bfin_write_PPI_STATUS(PPI_ERR_MASK);
  230. break;
  231. #if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
  232. case IRQ_MAC_ERROR:
  233. bfin_write_EMAC_SYSTAT(EMAC_ERR_MASK);
  234. break;
  235. #endif
  236. case IRQ_SPORT0_ERROR:
  237. bfin_write_SPORT0_STAT(SPORT_ERR_MASK);
  238. break;
  239. case IRQ_SPORT1_ERROR:
  240. bfin_write_SPORT1_STAT(SPORT_ERR_MASK);
  241. break;
  242. case IRQ_CAN_ERROR:
  243. bfin_write_CAN_GIS(CAN_ERR_MASK);
  244. break;
  245. case IRQ_SPI_ERROR:
  246. bfin_write_SPI_STAT(SPI_ERR_MASK);
  247. break;
  248. default:
  249. break;
  250. }
  251. pr_debug("IRQ %d:"
  252. " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n",
  253. irq);
  254. }
  255. } else
  256. printk(KERN_ERR
  257. "%s : %s : LINE %d :\nIRQ ?: PERIPHERAL ERROR"
  258. " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n",
  259. __FUNCTION__, __FILE__, __LINE__);
  260. }
  261. #endif /* BF537_GENERIC_ERROR_INT_DEMUX */
  262. #ifdef CONFIG_IRQCHIP_DEMUX_GPIO
  263. static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
  264. static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)];
  265. static void bfin_gpio_ack_irq(unsigned int irq)
  266. {
  267. u16 gpionr = irq - IRQ_PF0;
  268. if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
  269. set_gpio_data(gpionr, 0);
  270. SSYNC();
  271. }
  272. }
  273. static void bfin_gpio_mask_ack_irq(unsigned int irq)
  274. {
  275. u16 gpionr = irq - IRQ_PF0;
  276. if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
  277. set_gpio_data(gpionr, 0);
  278. SSYNC();
  279. }
  280. set_gpio_maska(gpionr, 0);
  281. SSYNC();
  282. }
  283. static void bfin_gpio_mask_irq(unsigned int irq)
  284. {
  285. set_gpio_maska(irq - IRQ_PF0, 0);
  286. SSYNC();
  287. }
  288. static void bfin_gpio_unmask_irq(unsigned int irq)
  289. {
  290. set_gpio_maska(irq - IRQ_PF0, 1);
  291. SSYNC();
  292. }
  293. static unsigned int bfin_gpio_irq_startup(unsigned int irq)
  294. {
  295. unsigned int ret;
  296. u16 gpionr = irq - IRQ_PF0;
  297. if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
  298. ret = gpio_request(gpionr, NULL);
  299. if (ret)
  300. return ret;
  301. }
  302. gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr);
  303. bfin_gpio_unmask_irq(irq);
  304. return ret;
  305. }
  306. static void bfin_gpio_irq_shutdown(unsigned int irq)
  307. {
  308. bfin_gpio_mask_irq(irq);
  309. gpio_free(irq - IRQ_PF0);
  310. gpio_enabled[gpio_bank(irq - IRQ_PF0)] &= ~gpio_bit(irq - IRQ_PF0);
  311. }
  312. static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
  313. {
  314. unsigned int ret;
  315. u16 gpionr = irq - IRQ_PF0;
  316. if (type == IRQ_TYPE_PROBE) {
  317. /* only probe unenabled GPIO interrupt lines */
  318. if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))
  319. return 0;
  320. type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
  321. }
  322. if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
  323. IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
  324. {
  325. if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
  326. ret = gpio_request(gpionr, NULL);
  327. if (ret)
  328. return ret;
  329. }
  330. gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr);
  331. } else {
  332. gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr);
  333. return 0;
  334. }
  335. set_gpio_dir(gpionr, 0);
  336. set_gpio_inen(gpionr, 1);
  337. if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
  338. gpio_edge_triggered[gpio_bank(gpionr)] |= gpio_bit(gpionr);
  339. set_gpio_edge(gpionr, 1);
  340. } else {
  341. set_gpio_edge(gpionr, 0);
  342. gpio_edge_triggered[gpio_bank(gpionr)] &= ~gpio_bit(gpionr);
  343. }
  344. if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
  345. == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
  346. set_gpio_both(gpionr, 1);
  347. else
  348. set_gpio_both(gpionr, 0);
  349. if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)))
  350. set_gpio_polar(gpionr, 1); /* low or falling edge denoted by one */
  351. else
  352. set_gpio_polar(gpionr, 0); /* high or rising edge denoted by zero */
  353. SSYNC();
  354. if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
  355. set_irq_handler(irq, handle_edge_irq);
  356. else
  357. set_irq_handler(irq, handle_level_irq);
  358. return 0;
  359. }
  360. static struct irq_chip bfin_gpio_irqchip = {
  361. .ack = bfin_gpio_ack_irq,
  362. .mask = bfin_gpio_mask_irq,
  363. .mask_ack = bfin_gpio_mask_ack_irq,
  364. .unmask = bfin_gpio_unmask_irq,
  365. .set_type = bfin_gpio_irq_type,
  366. .startup = bfin_gpio_irq_startup,
  367. .shutdown = bfin_gpio_irq_shutdown
  368. };
  369. static void bfin_demux_gpio_irq(unsigned int intb_irq,
  370. struct irq_desc *intb_desc)
  371. {
  372. u16 i;
  373. for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=16) {
  374. int irq = IRQ_PF0 + i;
  375. int flag_d = get_gpiop_data(i);
  376. int mask =
  377. flag_d & (gpio_enabled[gpio_bank(i)] &
  378. get_gpiop_maska(i));
  379. while (mask) {
  380. if (mask & 1) {
  381. struct irq_desc *desc = irq_desc + irq;
  382. desc->handle_irq(irq, desc);
  383. }
  384. irq++;
  385. mask >>= 1;
  386. }
  387. }
  388. }
  389. #endif /* CONFIG_IRQCHIP_DEMUX_GPIO */
  390. /*
  391. * This function should be called during kernel startup to initialize
  392. * the BFin IRQ handling routines.
  393. */
  394. int __init init_arch_irq(void)
  395. {
  396. int irq;
  397. unsigned long ilat = 0;
  398. /* Disable all the peripheral intrs - page 4-29 HW Ref manual */
  399. #ifdef CONFIG_BF54x
  400. bfin_write_SIC_IMASK0(SIC_UNMASK_ALL);
  401. bfin_write_SIC_IMASK1(SIC_UNMASK_ALL);
  402. bfin_write_SIC_IMASK2(SIC_UNMASK_ALL);
  403. #else
  404. bfin_write_SIC_IMASK(SIC_UNMASK_ALL);
  405. #endif
  406. SSYNC();
  407. local_irq_disable();
  408. #ifndef CONFIG_KGDB
  409. bfin_write_EVT0(evt_emulation);
  410. #endif
  411. bfin_write_EVT2(evt_evt2);
  412. bfin_write_EVT3(trap);
  413. bfin_write_EVT5(evt_ivhw);
  414. bfin_write_EVT6(evt_timer);
  415. bfin_write_EVT7(evt_evt7);
  416. bfin_write_EVT8(evt_evt8);
  417. bfin_write_EVT9(evt_evt9);
  418. bfin_write_EVT10(evt_evt10);
  419. bfin_write_EVT11(evt_evt11);
  420. bfin_write_EVT12(evt_evt12);
  421. bfin_write_EVT13(evt_evt13);
  422. bfin_write_EVT14(evt14_softirq);
  423. bfin_write_EVT15(evt_system_call);
  424. CSYNC();
  425. for (irq = 0; irq < SYS_IRQS; irq++) {
  426. if (irq <= IRQ_CORETMR)
  427. set_irq_chip(irq, &bfin_core_irqchip);
  428. else
  429. set_irq_chip(irq, &bfin_internal_irqchip);
  430. #ifdef BF537_GENERIC_ERROR_INT_DEMUX
  431. if (irq != IRQ_GENERIC_ERROR) {
  432. #endif
  433. #ifdef CONFIG_IRQCHIP_DEMUX_GPIO
  434. if ((irq != IRQ_PROG_INTA) /*PORT F & G MASK_A Interrupt*/
  435. # if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
  436. && (irq != IRQ_MAC_RX) /*PORT H MASK_A Interrupt*/
  437. # endif
  438. ) {
  439. #endif
  440. set_irq_handler(irq, handle_simple_irq);
  441. #ifdef CONFIG_IRQCHIP_DEMUX_GPIO
  442. } else {
  443. set_irq_chained_handler(irq,
  444. bfin_demux_gpio_irq);
  445. }
  446. #endif
  447. #ifdef BF537_GENERIC_ERROR_INT_DEMUX
  448. } else {
  449. set_irq_handler(irq, bfin_demux_error_irq);
  450. }
  451. #endif
  452. }
  453. #ifdef BF537_GENERIC_ERROR_INT_DEMUX
  454. for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) {
  455. set_irq_chip(irq, &bfin_generic_error_irqchip);
  456. set_irq_handler(irq, handle_level_irq);
  457. }
  458. #endif
  459. #ifdef CONFIG_IRQCHIP_DEMUX_GPIO
  460. for (irq = IRQ_PF0; irq < NR_IRQS; irq++) {
  461. set_irq_chip(irq, &bfin_gpio_irqchip);
  462. /* if configured as edge, then will be changed to do_edge_IRQ */
  463. set_irq_handler(irq, handle_level_irq);
  464. }
  465. #endif
  466. bfin_write_IMASK(0);
  467. CSYNC();
  468. ilat = bfin_read_ILAT();
  469. CSYNC();
  470. bfin_write_ILAT(ilat);
  471. CSYNC();
  472. printk(KERN_INFO
  473. "Configuring Blackfin Priority Driven Interrupts\n");
  474. /* IMASK=xxx is equivalent to STI xx or irq_flags=xx,
  475. * local_irq_enable()
  476. */
  477. program_IAR();
  478. /* Therefore it's better to setup IARs before interrupts enabled */
  479. search_IAR();
  480. /* Enable interrupts IVG7-15 */
  481. irq_flags = irq_flags | IMASK_IVG15 |
  482. IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
  483. IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 |
  484. IMASK_IVGHW;
  485. return 0;
  486. }
  487. #ifdef CONFIG_DO_IRQ_L1
  488. void do_irq(int vec, struct pt_regs *fp)__attribute__((l1_text));
  489. #endif
  490. void do_irq(int vec, struct pt_regs *fp)
  491. {
  492. if (vec == EVT_IVTMR_P) {
  493. vec = IRQ_CORETMR;
  494. } else {
  495. struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst;
  496. struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop;
  497. #ifdef CONFIG_BF54x
  498. unsigned long sic_status[3];
  499. SSYNC();
  500. sic_status[0] = bfin_read_SIC_ISR(0) & bfin_read_SIC_IMASK(0);
  501. sic_status[1] = bfin_read_SIC_ISR(1) & bfin_read_SIC_IMASK(1);
  502. sic_status[2] = bfin_read_SIC_ISR(2) & bfin_read_SIC_IMASK(2);
  503. SSYNC();
  504. for(;; ivg++) {
  505. if (ivg >= ivg_stop) {
  506. atomic_inc(&num_spurious);
  507. return;
  508. }
  509. if (sic_status[(ivg->irqno - IVG7)/32] & ivg->isrflag)
  510. break;
  511. }
  512. #else
  513. unsigned long sic_status;
  514. SSYNC();
  515. sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR();
  516. for (;; ivg++) {
  517. if (ivg >= ivg_stop) {
  518. atomic_inc(&num_spurious);
  519. return;
  520. } else if (sic_status & ivg->isrflag)
  521. break;
  522. }
  523. #endif
  524. vec = ivg->irqno;
  525. }
  526. asm_do_IRQ(vec, fp);
  527. #ifdef CONFIG_KGDB
  528. kgdb_process_breakpoint();
  529. #endif
  530. }