irq-pl192.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. /* linux/arch/arm/mach-s3c64xx/irq-s3c6400.c
  2. *
  3. *
  4. * S3C6400 interrupt functions.
  5. * Added by JaeCheol Lee(jc.lee@samsung.com)
  6. *
  7. */
  8. #include <linux/init.h>
  9. #include <linux/module.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/ioport.h>
  12. #include <linux/ptrace.h>
  13. #include <linux/sysdev.h>
  14. #include <asm/hardware.h>
  15. #include <asm/irq.h>
  16. #include <asm/io.h>
  17. #include <asm/mach/irq.h>
  18. #include <asm/arch/regs-irq.h>
  19. #include <asm/arch/regs-gpio.h>
  20. #include <asm/arch/regs-s3c6400-clock.h>
  21. #include <asm/plat-s3c24xx/cpu.h>
  22. #include <asm/plat-s3c24xx/pm.h>
  23. #define irqdbf(x...)
  24. #define irqdbf2(x...)
  25. /* "irqno" interrupt acked */
  26. static inline void
  27. s3c_irq_ack (unsigned int irqno)
  28. {
  29. if (irqno < 32) {
  30. __raw_writel(irqno, S3C_VIC0ADDRESS);
  31. } else if (irqno < 64) {
  32. __raw_writel(irqno, S3C_VIC0ADDRESS);
  33. __raw_writel(irqno, S3C_VIC1ADDRESS);
  34. } else {
  35. /* External interrupt */
  36. printk("ext irq %d\n", irqno);
  37. }
  38. }
  39. /* "irqno" interrupt disabled */
  40. static inline void
  41. s3c_irq_mask (unsigned int irqno)
  42. {
  43. if (irqno < 32) {
  44. __raw_writel(1<<irqno, S3C_VIC0INTENCLEAR);
  45. } else if (irqno < 64) {
  46. __raw_writel(1<<(irqno-32), S3C_VIC1INTENCLEAR);
  47. } else {
  48. /* External interrupt */
  49. printk("ext irq %d\n", irqno);
  50. }
  51. }
  52. /* "irqno" interrupt disabled and acked */
  53. static inline void
  54. s3c_irq_maskack (unsigned int irqno)
  55. {
  56. if (irqno < 32) {
  57. __raw_writel(1<<irqno, S3C_VIC0INTENCLEAR);
  58. __raw_writel(irqno, S3C_VIC0ADDRESS);
  59. } else if (irqno < 64) {
  60. __raw_writel(1<<(irqno-32), S3C_VIC1INTENCLEAR);
  61. /* XXX: can explain why this code is here by scsuh */
  62. __raw_writel(irqno, S3C_VIC0ADDRESS);
  63. __raw_writel(irqno, S3C_VIC1ADDRESS);
  64. } else {
  65. /* External interrupt */
  66. printk("ext irq %d\n", irqno);
  67. }
  68. }
  69. /* "irqno" interrupt enabled */
  70. static inline void
  71. s3c_irq_unmask (unsigned int irqno)
  72. {
  73. if (irqno < 32) {
  74. __raw_writel(1<<irqno, S3C_VIC0INTENABLE);
  75. } else if (irqno < 64) {
  76. __raw_writel(1<<(irqno-32), S3C_VIC1INTENABLE);
  77. } else {
  78. /* External Interrupt */
  79. printk("ext irq %d\n", irqno);
  80. }
  81. }
  82. static inline void
  83. s3c_irq_unmaskack(unsigned int irqno)
  84. {
  85. unsigned long unmask;
  86. /* It is common for all interrupt sources */
  87. __raw_writel(1, S3C_VIC0ADDRESS);
  88. if (irqno < 32) {
  89. unmask = __raw_readl(S3C_VIC0INTENABLE);
  90. unmask |= (1UL << irqno);
  91. __raw_writel(unmask, S3C_VIC0INTENABLE);
  92. } else if (irqno < 64) {
  93. unmask = __raw_readl(S3C_VIC1INTENABLE);
  94. unmask |= (1UL << (irqno - 32));
  95. __raw_writel(unmask, S3C_VIC1INTENABLE);
  96. __raw_writel(1, S3C_VIC1ADDRESS);
  97. } else {
  98. /* External Interrupt */
  99. printk("ext irq %d\n", irqno);
  100. }
  101. }
  102. static int
  103. s3c_irq_wake(unsigned int irqno, unsigned int flag)
  104. {
  105. unsigned int pwr_cfg,bit_position;
  106. pwr_cfg = __raw_readl(S3C_PWR_CFG);
  107. switch(irqno) {
  108. case IRQ_RTC_TIC:
  109. bit_position = 11;
  110. break;
  111. case IRQ_TC:
  112. bit_position = 12;
  113. break;
  114. case IRQ_RTC_ALARM:
  115. bit_position = 10;
  116. break;
  117. case IRQ_KEYPAD:
  118. bit_position = 8;
  119. break;
  120. default:
  121. printk("irq %d : Not supporting wakeup \n", irqno);
  122. return -1;
  123. }
  124. if(flag) {
  125. pwr_cfg &=~(1 << bit_position);
  126. } else {
  127. pwr_cfg |= (1 << bit_position);
  128. }
  129. __raw_writel(pwr_cfg, S3C_PWR_CFG);
  130. return 0;
  131. }
  132. //static struct irqchip s3c_irq_level_chip = {
  133. static struct irq_chip s3c_irq_level_chip = {
  134. .ack = s3c_irq_maskack,
  135. .mask = s3c_irq_mask,
  136. .unmask = s3c_irq_unmask,
  137. .set_wake = s3c_irq_wake
  138. };
  139. #if 0 /* XXX: when you want to use it, unmask it. by scsuh */
  140. static struct irqchip s3c_irq_chip = {
  141. .ack = s3c_irq_mask,
  142. .mask = s3c_irq_mask,
  143. .unmask = s3c_irq_unmask,
  144. .set_wake = s3c_irq_wake
  145. };
  146. #endif
  147. static inline void
  148. s3c_irqext_mask(unsigned int irqno)
  149. {
  150. unsigned long gpjcon; // Workaround
  151. unsigned long mask;
  152. if (irqno >= 64) {
  153. gpjcon = __raw_readl(S3C_GPJCON);
  154. irqno -= 64;
  155. mask = __raw_readl(S3C_EINTMASK);
  156. mask |= (1UL << irqno);
  157. __raw_writel(mask, S3C_EINTMASK);
  158. __raw_writel(gpjcon, S3C_GPJCON);
  159. } else {
  160. printk("Invalid ext irq %d\n", irqno);
  161. }
  162. }
  163. static inline void
  164. s3c_irqext_maskack(unsigned int irqno)
  165. {
  166. s3c_irqext_mask(irqno);
  167. if (irqno <= IRQ_EINT3) {
  168. s3c_irq_mask(IRQ_EINT0_3);
  169. } else if (irqno <= IRQ_EINT11) {
  170. s3c_irq_mask(IRQ_EINT4_11);
  171. } else if (irqno <= IRQ_EINT19) {
  172. s3c_irq_mask(IRQ_EINT12_19);
  173. } else if (irqno <= IRQ_EINT27) {
  174. s3c_irq_mask(IRQ_EINT20_27);
  175. } else if (irqno > IRQ_EINT27) {
  176. panic("Wrong IRQ number %d \n ", irqno);
  177. }
  178. }
  179. static inline void
  180. s3c_irqext_unmaskack(unsigned int irqno)
  181. {
  182. unsigned long mask;
  183. if (irqno <= IRQ_EINT3) {
  184. s3c_irq_unmaskack(IRQ_EINT0_3);
  185. } else if (irqno <= IRQ_EINT11) {
  186. s3c_irq_unmaskack(IRQ_EINT4_11);
  187. } else if (irqno <= IRQ_EINT19) {
  188. s3c_irq_unmaskack(IRQ_EINT12_19);
  189. } else if (irqno <= IRQ_EINT27) {
  190. s3c_irq_unmaskack(IRQ_EINT20_27);
  191. }
  192. if (irqno >= 64) {
  193. irqno -= 64;
  194. __raw_writel(1UL << irqno, S3C_EINTPEND);
  195. mask = __raw_readl(S3C_EINTMASK);
  196. mask &= ~(1UL << irqno);
  197. __raw_writel(mask, S3C_EINTMASK);
  198. } else {
  199. printk("Invalid ext irq %d\n", irqno);
  200. }
  201. }
  202. static int
  203. s3c_irqext_type(unsigned int irq, unsigned int type)
  204. {
  205. unsigned long newvalue = 0;
  206. /* Set the external interrupt to pointed trigger type */
  207. switch (type) {
  208. case IRQT_NOEDGE:
  209. printk(KERN_WARNING "No edge setting!\n");
  210. break;
  211. case IRQT_RISING:
  212. newvalue = S3C_EXTINT_RISEEDGE;
  213. break;
  214. case IRQT_FALLING:
  215. newvalue = S3C_EXTINT_FALLEDGE;
  216. break;
  217. case IRQT_BOTHEDGE:
  218. newvalue = S3C_EXTINT_BOTHEDGE;
  219. break;
  220. case IRQT_LOW:
  221. newvalue = S3C_EXTINT_LOWLEV;
  222. break;
  223. case IRQT_HIGH:
  224. newvalue = S3C_EXTINT_HILEV;
  225. break;
  226. default:
  227. printk(KERN_ERR "No such irq type %d", type);
  228. return -1;
  229. }
  230. switch (irq) {
  231. case IRQ_EINT9:
  232. s3c_gpio_cfgpin(S3C_GPN9, S3C_GPN9_EXTINT9);
  233. __raw_writel((__raw_readl(S3C_EINTCON0) & ~(0x7 << 16)) |
  234. (newvalue << 16), S3C_EINTCON0);
  235. break;
  236. case IRQ_EINT10:
  237. s3c_gpio_cfgpin(S3C_GPN10, S3C_GPN10_EXTINT10);
  238. __raw_writel((__raw_readl(S3C_EINTCON0) & ~(0x7 << 20)) |
  239. (newvalue << 20), S3C_EINTCON0);
  240. break;
  241. case IRQ_EINT11:
  242. s3c_gpio_cfgpin(S3C_GPN11, S3C_GPN11_EXTINT11);
  243. __raw_writel((__raw_readl(S3C_EINTCON0) & ~(0x7 << 20)) |
  244. (newvalue << 20), S3C_EINTCON0);
  245. break;
  246. case IRQ_EINT12:
  247. s3c_gpio_cfgpin(S3C_GPN12, S3C_GPN12_EXTINT12);
  248. __raw_writel((__raw_readl(S3C_EINTCON0) & ~(0x7 << 24)) |
  249. (newvalue << 24), S3C_EINTCON0);
  250. break;
  251. case IRQ_EINT13:
  252. s3c_gpio_cfgpin(S3C_GPN13, S3C_GPN13_EXTINT13);
  253. __raw_writel((__raw_readl(S3C_EINTCON0) & ~(0x7 << 24)) |
  254. (newvalue << 24), S3C_EINTCON0);
  255. break;
  256. case IRQ_EINT14:
  257. s3c_gpio_cfgpin(S3C_GPN14, S3C_GPN14_EXTINT14);
  258. __raw_writel((__raw_readl(S3C_EINTCON0) & ~(0x7 << 28)) |
  259. (newvalue << 28), S3C_EINTCON0);
  260. break;
  261. case IRQ_EINT15:
  262. s3c_gpio_cfgpin(S3C_GPN15, S3C_GPN15_EXTINT15);
  263. __raw_writel((__raw_readl(S3C_EINTCON0) & ~(0x7 << 28)) |
  264. (newvalue << 28), S3C_EINTCON0);
  265. break;
  266. default:
  267. printk(KERN_ERR
  268. "s3c_irqext_type : Only support EINT9,10,11,12,13,14,15 interrupt.Need to be updated!!! - Jaecheol Lee \n");
  269. break;
  270. }
  271. return 0;
  272. }
  273. static int s3c_irqext_wake(unsigned int irqno, unsigned int flag)
  274. {
  275. unsigned int eint_mask;
  276. if(irqno < IRQ_EINT0)
  277. printk(KERN_ERR "Check external wake-up source\n");
  278. eint_mask = __raw_readl(S3C_EINT_MASK);
  279. if(flag) {
  280. eint_mask &= ~(1 << (irqno - IRQ_EINT0));
  281. } else {
  282. eint_mask |= (1 << (irqno - IRQ_EINT0));
  283. }
  284. __raw_writel(eint_mask, S3C_EINT_MASK);
  285. return 0;
  286. }
  287. //static struct irqchip s3c_irqext_chip = {
  288. static struct irq_chip s3c_irqext_chip = {
  289. .mask = s3c_irqext_mask,
  290. .unmask = s3c_irqext_unmaskack,
  291. .ack = s3c_irqext_maskack,
  292. .set_type = s3c_irqext_type,
  293. .set_wake = s3c_irqext_wake
  294. };
  295. /* irq demux for EINT0_3 */
  296. static inline void
  297. s3c_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
  298. {
  299. unsigned int eintpend, eintmsk;
  300. unsigned int irqnr = IRQ_EINT0;
  301. unsigned char interruptPending = 0, count = 0;
  302. struct irq_desc *mydesc;
  303. /* read the current pending interrupts, and the mask
  304. * for what it is available */
  305. eintpend = __raw_readl(S3C_EINTPEND);
  306. eintmsk = __raw_readl(S3C_EINTMASK);
  307. eintpend &= ~eintmsk;
  308. interruptPending = (eintpend & 0xf);
  309. while (interruptPending != 0) {
  310. if (interruptPending & 0x1) {
  311. mydesc = irq_desc + (irqnr + count);
  312. //mydesc->handle((irqnr + count), mydesc, regs);
  313. desc_handle_irq((irqnr + count), mydesc);
  314. }
  315. interruptPending >>= 1;
  316. count++;
  317. }
  318. }
  319. /* irq demux for EINT4_11 */
  320. static void
  321. s3c_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc)
  322. {
  323. unsigned int eintpend, eintmsk;
  324. unsigned int irqnr = IRQ_EINT4;
  325. unsigned char interruptPending = 0, count = 0;
  326. struct irq_desc *mydesc;
  327. /* read the current pending interrupts, and the mask
  328. * for what it is available */
  329. eintpend = __raw_readl(S3C_EINTPEND);
  330. eintmsk = __raw_readl(S3C_EINTMASK);
  331. eintpend &= ~eintmsk;
  332. interruptPending = ((eintpend >> 4) & 0xff);
  333. while (interruptPending != 0) {
  334. if (interruptPending & 0x1) {
  335. mydesc = irq_desc + (irqnr + count);
  336. //mydesc->handle((irqnr + count), mydesc, regs);
  337. desc_handle_irq((irqnr + count), mydesc);
  338. }
  339. interruptPending >>= 1;
  340. count++;
  341. }
  342. }
  343. /* irq demux for EINT12_19 */
  344. static void
  345. s3c_irq_demux_eint12_19(unsigned int irq, struct irq_desc *desc)
  346. {
  347. unsigned int eintpend, eintmsk;
  348. unsigned int irqnr = IRQ_EINT12;
  349. unsigned char interruptPending = 0, count = 0;
  350. struct irq_desc *mydesc;
  351. /* read the current pending interrupts, and the mask
  352. * for what it is available */
  353. eintpend = __raw_readl(S3C_EINTPEND);
  354. eintmsk = __raw_readl(S3C_EINTMASK);
  355. eintpend &= ~eintmsk;
  356. interruptPending = ((eintpend >> 12) & 0xff);
  357. while (interruptPending != 0) {
  358. if (interruptPending & 0x1) {
  359. mydesc = irq_desc + (irqnr + count);
  360. //mydesc->handle((irqnr + count), mydesc, regs);
  361. desc_handle_irq((irqnr + count), mydesc);
  362. }
  363. interruptPending >>= 1;
  364. count++;
  365. }
  366. }
  367. /* irq demux for EINT20_27 */
  368. static void
  369. s3c_irq_demux_eint20_27 (unsigned int irq, struct irq_desc *desc)
  370. {
  371. unsigned int eintpend, eintmsk;
  372. unsigned int irqnr = IRQ_EINT20;
  373. unsigned char interruptPending = 0, count = 0;
  374. struct irq_desc *mydesc;
  375. /* read the current pending interrupts, and the mask
  376. * for what it is available */
  377. eintpend = __raw_readl(S3C_EINTPEND);
  378. eintmsk = __raw_readl(S3C_EINTMASK);
  379. eintpend &= ~eintmsk;
  380. interruptPending = ((eintpend >> 20) & 0xff);
  381. while (interruptPending != 0) {
  382. if (interruptPending & 0x1) {
  383. mydesc = irq_desc + (irqnr + count);
  384. //mydesc->handle((irqnr + count), mydesc, regs);
  385. desc_handle_irq((irqnr + count), mydesc);
  386. }
  387. interruptPending >>= 1;
  388. count++;
  389. }
  390. }
  391. #ifdef CONFIG_PM
  392. static struct sleep_save irq_save[] = {
  393. SAVE_ITEM(S3C_VIC0INTSELECT),
  394. SAVE_ITEM(S3C_VIC1INTSELECT),
  395. SAVE_ITEM(S3C_VIC0INTENABLE),
  396. SAVE_ITEM(S3C_VIC1INTENABLE),
  397. SAVE_ITEM(S3C_VIC0SOFTINT),
  398. SAVE_ITEM(S3C_VIC1SOFTINT),
  399. };
  400. static struct sleep_save extirq_save[] = {
  401. SAVE_ITEM(S3C_EINTCON0),
  402. SAVE_ITEM(S3C_EINTCON1),
  403. SAVE_ITEM(S3C_EINTFLTCON0),
  404. SAVE_ITEM(S3C_EINTFLTCON1),
  405. SAVE_ITEM(S3C_EINTFLTCON2),
  406. SAVE_ITEM(S3C_EINTFLTCON3),
  407. SAVE_ITEM(S3C_EINTMASK),
  408. SAVE_ITEM(S3C_EINT12CON),
  409. SAVE_ITEM(S3C_EINT34CON),
  410. SAVE_ITEM(S3C_EINT56CON),
  411. SAVE_ITEM(S3C_EINT78CON),
  412. SAVE_ITEM(S3C_EINT9CON),
  413. SAVE_ITEM(S3C_EINT12FLTCON),
  414. SAVE_ITEM(S3C_EINT34FLTCON),
  415. SAVE_ITEM(S3C_EINT56FLTCON),
  416. SAVE_ITEM(S3C_EINT78FLTCON),
  417. SAVE_ITEM(S3C_EINT9FLTCON),
  418. SAVE_ITEM(S3C_EINT12MASK),
  419. SAVE_ITEM(S3C_EINT34MASK),
  420. SAVE_ITEM(S3C_EINT56MASK),
  421. SAVE_ITEM(S3C_EINT78MASK),
  422. SAVE_ITEM(S3C_EINT9MASK),
  423. SAVE_ITEM(S3C_EINT34FLTCON),
  424. SAVE_ITEM(S3C_EINT56FLTCON),
  425. SAVE_ITEM(S3C_EINT78FLTCON),
  426. SAVE_ITEM(S3C_EINT9FLTCON),
  427. };
  428. int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
  429. {
  430. s3c2410_pm_do_save(extirq_save, ARRAY_SIZE(extirq_save));
  431. s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
  432. return 0;
  433. }
  434. int s3c24xx_irq_resume(struct sys_device *dev)
  435. {
  436. int irqno;
  437. int irqindex = 0;
  438. s3c2410_pm_do_restore(extirq_save, ARRAY_SIZE(extirq_save));
  439. s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
  440. /* For writing the IRQ number into the VICVECTADDR */
  441. for (irqno = IRQ_EINT0_3; irqno <= IRQ_LCD_SYSTEM; irqno++) {
  442. __raw_writel(irqno, S3C_VIC0VECTADDR0 + irqindex);
  443. irqindex = irqindex + 4;
  444. }
  445. irqindex = 0;
  446. for (irqno = IRQ_EINT12_19; irqno <= IRQ_ADC; irqno++) {
  447. __raw_writel(irqno, S3C_VIC1VECTADDR0 + irqindex);
  448. irqindex = irqindex + 4;
  449. }
  450. return 0;
  451. }
  452. #else
  453. #define s3c24xx_irq_suspend NULL
  454. #define s3c24xx_irq_resume NULL
  455. #endif
  456. /* --------------------------------------------------
  457. * s3c_init_irq
  458. *
  459. * Initialise s3c6400 IRQ system
  460. * --------------------------------------------------
  461. */
  462. void __init s3c_init_irq(void)
  463. {
  464. int irqno;
  465. int irqindex = 0;
  466. irqdbf("s3c_init_irq: clearing interrupt status flags\n");
  467. /* first, clear all interrupts pending... */
  468. /* clear external interrupts */
  469. __raw_writel(0xFFFFFFFF, S3C_EINTPEND);
  470. /* clear all vector interrupts */
  471. __raw_writel(0x00000000, S3C_VIC0ADDRESS);
  472. __raw_writel(0x00000000, S3C_VIC1ADDRESS);
  473. /* For writing the IRQ number into the VICVECTADDR */
  474. for (irqno = IRQ_EINT0_3; irqno <= IRQ_LCD_SYSTEM; irqno++) {
  475. __raw_writel(irqno, S3C_VIC0VECTADDR0 + irqindex);
  476. irqindex = irqindex + 4;
  477. }
  478. irqindex = 0;
  479. for (irqno = IRQ_EINT12_19; irqno <= IRQ_ADC; irqno++) {
  480. __raw_writel(irqno, S3C_VIC1VECTADDR0 + irqindex);
  481. irqindex = irqindex + 4;
  482. }
  483. /* register the main interrupts */
  484. irqdbf("s3c6400_init_irq: registering mDirac-III interrupt handlers\n");
  485. for (irqno = IRQ_EINT0_3; irqno <= IRQ_ADC; irqno++) {
  486. switch (irqno) {
  487. /* deal with the special IRQs in ext (cascaded) */
  488. case IRQ_EINT0_3:
  489. set_irq_chained_handler(IRQ_EINT0_3, s3c_irq_demux_eint0_3);
  490. break;
  491. case IRQ_EINT4_11:
  492. set_irq_chained_handler(IRQ_EINT4_11, s3c_irq_demux_eint4_11);
  493. break;
  494. case IRQ_EINT12_19:
  495. set_irq_chained_handler(IRQ_EINT12_19, s3c_irq_demux_eint12_19);
  496. break;
  497. case IRQ_EINT20_27:
  498. set_irq_chained_handler(IRQ_EINT20_27, s3c_irq_demux_eint20_27);
  499. break;
  500. default:
  501. irqdbf("registering irq %d (s3c irq)\n", irqno);
  502. set_irq_chip(irqno, &s3c_irq_level_chip);
  503. //set_irq_handler(irqno, do_level_IRQ);
  504. set_irq_handler(irqno, handle_level_irq);
  505. set_irq_flags(irqno, IRQF_VALID);
  506. break;
  507. }
  508. }
  509. for (irqno = IRQ_EINT0; irqno <= IRQ_EINT27; irqno++) {
  510. irqdbf("registering irq %d (extended s3c irq)\n", irqno);
  511. set_irq_chip(irqno, &s3c_irqext_chip);
  512. //set_irq_handler(irqno, do_level_IRQ);
  513. set_irq_handler(irqno, handle_level_irq);
  514. set_irq_flags(irqno, IRQF_VALID);
  515. }
  516. irqdbf("s3c6400: registered interrupt handlers\n");
  517. }