irq.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042
  1. /*
  2. * S3C24XX IRQ handling
  3. *
  4. * Copyright (c) 2003-2004 Simtec Electronics
  5. * Ben Dooks <ben@simtec.co.uk>
  6. * Copyright (c) 2012 Heiko Stuebner <heiko@sntech.de>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. */
  18. #include <linux/init.h>
  19. #include <linux/slab.h>
  20. #include <linux/module.h>
  21. #include <linux/io.h>
  22. #include <linux/err.h>
  23. #include <linux/interrupt.h>
  24. #include <linux/ioport.h>
  25. #include <linux/device.h>
  26. #include <linux/irqdomain.h>
  27. #include <asm/mach/irq.h>
  28. #include <mach/regs-irq.h>
  29. #include <mach/regs-gpio.h>
  30. #include <plat/cpu.h>
  31. #include <plat/regs-irqtype.h>
  32. #include <plat/pm.h>
  33. #define S3C_IRQTYPE_NONE 0
  34. #define S3C_IRQTYPE_EINT 1
  35. #define S3C_IRQTYPE_EDGE 2
  36. #define S3C_IRQTYPE_LEVEL 3
  37. struct s3c_irq_data {
  38. unsigned int type;
  39. unsigned long parent_irq;
  40. /* data gets filled during init */
  41. struct s3c_irq_intc *intc;
  42. unsigned long sub_bits;
  43. struct s3c_irq_intc *sub_intc;
  44. };
  45. /*
  46. * Sructure holding the controller data
  47. * @reg_pending register holding pending irqs
  48. * @reg_intpnd special register intpnd in main intc
  49. * @reg_mask mask register
  50. * @domain irq_domain of the controller
  51. * @parent parent controller for ext and sub irqs
  52. * @irqs irq-data, always s3c_irq_data[32]
  53. */
  54. struct s3c_irq_intc {
  55. void __iomem *reg_pending;
  56. void __iomem *reg_intpnd;
  57. void __iomem *reg_mask;
  58. struct irq_domain *domain;
  59. struct s3c_irq_intc *parent;
  60. struct s3c_irq_data *irqs;
  61. };
  62. static void s3c_irq_mask(struct irq_data *data)
  63. {
  64. struct s3c_irq_intc *intc = data->domain->host_data;
  65. struct s3c_irq_intc *parent_intc = intc->parent;
  66. struct s3c_irq_data *irq_data = &intc->irqs[data->hwirq];
  67. struct s3c_irq_data *parent_data;
  68. unsigned long mask;
  69. unsigned int irqno;
  70. mask = __raw_readl(intc->reg_mask);
  71. mask |= (1UL << data->hwirq);
  72. __raw_writel(mask, intc->reg_mask);
  73. if (parent_intc && irq_data->parent_irq) {
  74. parent_data = &parent_intc->irqs[irq_data->parent_irq];
  75. /* check to see if we need to mask the parent IRQ */
  76. if ((mask & parent_data->sub_bits) == parent_data->sub_bits) {
  77. irqno = irq_find_mapping(parent_intc->domain,
  78. irq_data->parent_irq);
  79. s3c_irq_mask(irq_get_irq_data(irqno));
  80. }
  81. }
  82. }
  83. static void s3c_irq_unmask(struct irq_data *data)
  84. {
  85. struct s3c_irq_intc *intc = data->domain->host_data;
  86. struct s3c_irq_intc *parent_intc = intc->parent;
  87. struct s3c_irq_data *irq_data = &intc->irqs[data->hwirq];
  88. unsigned long mask;
  89. unsigned int irqno;
  90. mask = __raw_readl(intc->reg_mask);
  91. mask &= ~(1UL << data->hwirq);
  92. __raw_writel(mask, intc->reg_mask);
  93. if (parent_intc && irq_data->parent_irq) {
  94. irqno = irq_find_mapping(parent_intc->domain,
  95. irq_data->parent_irq);
  96. s3c_irq_unmask(irq_get_irq_data(irqno));
  97. }
  98. }
  99. static inline void s3c_irq_ack(struct irq_data *data)
  100. {
  101. struct s3c_irq_intc *intc = data->domain->host_data;
  102. unsigned long bitval = 1UL << data->hwirq;
  103. __raw_writel(bitval, intc->reg_pending);
  104. if (intc->reg_intpnd)
  105. __raw_writel(bitval, intc->reg_intpnd);
  106. }
  107. static int s3c_irqext_type_set(void __iomem *gpcon_reg,
  108. void __iomem *extint_reg,
  109. unsigned long gpcon_offset,
  110. unsigned long extint_offset,
  111. unsigned int type)
  112. {
  113. unsigned long newvalue = 0, value;
  114. /* Set the GPIO to external interrupt mode */
  115. value = __raw_readl(gpcon_reg);
  116. value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
  117. __raw_writel(value, gpcon_reg);
  118. /* Set the external interrupt to pointed trigger type */
  119. switch (type)
  120. {
  121. case IRQ_TYPE_NONE:
  122. pr_warn("No edge setting!\n");
  123. break;
  124. case IRQ_TYPE_EDGE_RISING:
  125. newvalue = S3C2410_EXTINT_RISEEDGE;
  126. break;
  127. case IRQ_TYPE_EDGE_FALLING:
  128. newvalue = S3C2410_EXTINT_FALLEDGE;
  129. break;
  130. case IRQ_TYPE_EDGE_BOTH:
  131. newvalue = S3C2410_EXTINT_BOTHEDGE;
  132. break;
  133. case IRQ_TYPE_LEVEL_LOW:
  134. newvalue = S3C2410_EXTINT_LOWLEV;
  135. break;
  136. case IRQ_TYPE_LEVEL_HIGH:
  137. newvalue = S3C2410_EXTINT_HILEV;
  138. break;
  139. default:
  140. pr_err("No such irq type %d", type);
  141. return -EINVAL;
  142. }
  143. value = __raw_readl(extint_reg);
  144. value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
  145. __raw_writel(value, extint_reg);
  146. return 0;
  147. }
  148. static int s3c_irqext_type(struct irq_data *data, unsigned int type)
  149. {
  150. void __iomem *extint_reg;
  151. void __iomem *gpcon_reg;
  152. unsigned long gpcon_offset, extint_offset;
  153. if ((data->hwirq >= 4) && (data->hwirq <= 7)) {
  154. gpcon_reg = S3C2410_GPFCON;
  155. extint_reg = S3C24XX_EXTINT0;
  156. gpcon_offset = (data->hwirq) * 2;
  157. extint_offset = (data->hwirq) * 4;
  158. } else if ((data->hwirq >= 8) && (data->hwirq <= 15)) {
  159. gpcon_reg = S3C2410_GPGCON;
  160. extint_reg = S3C24XX_EXTINT1;
  161. gpcon_offset = (data->hwirq - 8) * 2;
  162. extint_offset = (data->hwirq - 8) * 4;
  163. } else if ((data->hwirq >= 16) && (data->hwirq <= 23)) {
  164. gpcon_reg = S3C2410_GPGCON;
  165. extint_reg = S3C24XX_EXTINT2;
  166. gpcon_offset = (data->hwirq - 8) * 2;
  167. extint_offset = (data->hwirq - 16) * 4;
  168. } else {
  169. return -EINVAL;
  170. }
  171. return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
  172. extint_offset, type);
  173. }
  174. static int s3c_irqext0_type(struct irq_data *data, unsigned int type)
  175. {
  176. void __iomem *extint_reg;
  177. void __iomem *gpcon_reg;
  178. unsigned long gpcon_offset, extint_offset;
  179. if ((data->hwirq >= 0) && (data->hwirq <= 3)) {
  180. gpcon_reg = S3C2410_GPFCON;
  181. extint_reg = S3C24XX_EXTINT0;
  182. gpcon_offset = (data->hwirq) * 2;
  183. extint_offset = (data->hwirq) * 4;
  184. } else {
  185. return -EINVAL;
  186. }
  187. return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
  188. extint_offset, type);
  189. }
  190. static struct irq_chip s3c_irq_chip = {
  191. .name = "s3c",
  192. .irq_ack = s3c_irq_ack,
  193. .irq_mask = s3c_irq_mask,
  194. .irq_unmask = s3c_irq_unmask,
  195. .irq_set_wake = s3c_irq_wake
  196. };
  197. static struct irq_chip s3c_irq_level_chip = {
  198. .name = "s3c-level",
  199. .irq_mask = s3c_irq_mask,
  200. .irq_unmask = s3c_irq_unmask,
  201. .irq_ack = s3c_irq_ack,
  202. };
  203. static struct irq_chip s3c_irqext_chip = {
  204. .name = "s3c-ext",
  205. .irq_mask = s3c_irq_mask,
  206. .irq_unmask = s3c_irq_unmask,
  207. .irq_ack = s3c_irq_ack,
  208. .irq_set_type = s3c_irqext_type,
  209. .irq_set_wake = s3c_irqext_wake
  210. };
  211. static struct irq_chip s3c_irq_eint0t4 = {
  212. .name = "s3c-ext0",
  213. .irq_ack = s3c_irq_ack,
  214. .irq_mask = s3c_irq_mask,
  215. .irq_unmask = s3c_irq_unmask,
  216. .irq_set_wake = s3c_irq_wake,
  217. .irq_set_type = s3c_irqext0_type,
  218. };
  219. static void s3c_irq_demux(unsigned int irq, struct irq_desc *desc)
  220. {
  221. struct irq_chip *chip = irq_desc_get_chip(desc);
  222. struct s3c_irq_intc *intc = desc->irq_data.domain->host_data;
  223. struct s3c_irq_data *irq_data = &intc->irqs[desc->irq_data.hwirq];
  224. struct s3c_irq_intc *sub_intc = irq_data->sub_intc;
  225. unsigned long src;
  226. unsigned long msk;
  227. unsigned int n;
  228. chained_irq_enter(chip, desc);
  229. src = __raw_readl(sub_intc->reg_pending);
  230. msk = __raw_readl(sub_intc->reg_mask);
  231. src &= ~msk;
  232. src &= irq_data->sub_bits;
  233. while (src) {
  234. n = __ffs(src);
  235. src &= ~(1 << n);
  236. generic_handle_irq(irq_find_mapping(sub_intc->domain, n));
  237. }
  238. chained_irq_exit(chip, desc);
  239. }
  240. #ifdef CONFIG_FIQ
  241. /**
  242. * s3c24xx_set_fiq - set the FIQ routing
  243. * @irq: IRQ number to route to FIQ on processor.
  244. * @on: Whether to route @irq to the FIQ, or to remove the FIQ routing.
  245. *
  246. * Change the state of the IRQ to FIQ routing depending on @irq and @on. If
  247. * @on is true, the @irq is checked to see if it can be routed and the
  248. * interrupt controller updated to route the IRQ. If @on is false, the FIQ
  249. * routing is cleared, regardless of which @irq is specified.
  250. */
  251. int s3c24xx_set_fiq(unsigned int irq, bool on)
  252. {
  253. u32 intmod;
  254. unsigned offs;
  255. if (on) {
  256. offs = irq - FIQ_START;
  257. if (offs > 31)
  258. return -EINVAL;
  259. intmod = 1 << offs;
  260. } else {
  261. intmod = 0;
  262. }
  263. __raw_writel(intmod, S3C2410_INTMOD);
  264. return 0;
  265. }
  266. EXPORT_SYMBOL_GPL(s3c24xx_set_fiq);
  267. #endif
  268. static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
  269. irq_hw_number_t hw)
  270. {
  271. struct s3c_irq_intc *intc = h->host_data;
  272. struct s3c_irq_data *irq_data = &intc->irqs[hw];
  273. struct s3c_irq_intc *parent_intc;
  274. struct s3c_irq_data *parent_irq_data;
  275. unsigned int irqno;
  276. if (!intc) {
  277. pr_err("irq-s3c24xx: no controller found for hwirq %lu\n", hw);
  278. return -EINVAL;
  279. }
  280. if (!irq_data) {
  281. pr_err("irq-s3c24xx: no irq data found for hwirq %lu\n", hw);
  282. return -EINVAL;
  283. }
  284. /* attach controller pointer to irq_data */
  285. irq_data->intc = intc;
  286. /* set handler and flags */
  287. switch (irq_data->type) {
  288. case S3C_IRQTYPE_NONE:
  289. return 0;
  290. case S3C_IRQTYPE_EINT:
  291. if (irq_data->parent_irq)
  292. irq_set_chip_and_handler(virq, &s3c_irqext_chip,
  293. handle_edge_irq);
  294. else
  295. irq_set_chip_and_handler(virq, &s3c_irq_eint0t4,
  296. handle_edge_irq);
  297. break;
  298. case S3C_IRQTYPE_EDGE:
  299. if (irq_data->parent_irq ||
  300. intc->reg_pending == S3C2416_SRCPND2)
  301. irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
  302. handle_edge_irq);
  303. else
  304. irq_set_chip_and_handler(virq, &s3c_irq_chip,
  305. handle_edge_irq);
  306. break;
  307. case S3C_IRQTYPE_LEVEL:
  308. if (irq_data->parent_irq)
  309. irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
  310. handle_level_irq);
  311. else
  312. irq_set_chip_and_handler(virq, &s3c_irq_chip,
  313. handle_level_irq);
  314. break;
  315. default:
  316. pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type);
  317. return -EINVAL;
  318. }
  319. set_irq_flags(virq, IRQF_VALID);
  320. if (irq_data->parent_irq) {
  321. parent_intc = intc->parent;
  322. if (!parent_intc) {
  323. pr_err("irq-s3c24xx: no parent controller found for hwirq %lu\n",
  324. hw);
  325. goto err;
  326. }
  327. parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
  328. if (!irq_data) {
  329. pr_err("irq-s3c24xx: no irq data found for hwirq %lu\n",
  330. hw);
  331. goto err;
  332. }
  333. parent_irq_data->sub_intc = intc;
  334. parent_irq_data->sub_bits |= (1UL << hw);
  335. /* attach the demuxer to the parent irq */
  336. irqno = irq_find_mapping(parent_intc->domain,
  337. irq_data->parent_irq);
  338. if (!irqno) {
  339. pr_err("irq-s3c24xx: could not find mapping for parent irq %lu\n",
  340. irq_data->parent_irq);
  341. goto err;
  342. }
  343. irq_set_chained_handler(irqno, s3c_irq_demux);
  344. }
  345. return 0;
  346. err:
  347. set_irq_flags(virq, 0);
  348. /* the only error can result from bad mapping data*/
  349. return -EINVAL;
  350. }
  351. static struct irq_domain_ops s3c24xx_irq_ops = {
  352. .map = s3c24xx_irq_map,
  353. .xlate = irq_domain_xlate_twocell,
  354. };
  355. static void s3c24xx_clear_intc(struct s3c_irq_intc *intc)
  356. {
  357. void __iomem *reg_source;
  358. unsigned long pend;
  359. unsigned long last;
  360. int i;
  361. /* if intpnd is set, read the next pending irq from there */
  362. reg_source = intc->reg_intpnd ? intc->reg_intpnd : intc->reg_pending;
  363. last = 0;
  364. for (i = 0; i < 4; i++) {
  365. pend = __raw_readl(reg_source);
  366. if (pend == 0 || pend == last)
  367. break;
  368. __raw_writel(pend, intc->reg_pending);
  369. if (intc->reg_intpnd)
  370. __raw_writel(pend, intc->reg_intpnd);
  371. pr_info("irq: clearing pending status %08x\n", (int)pend);
  372. last = pend;
  373. }
  374. }
  375. struct s3c_irq_intc *s3c24xx_init_intc(struct device_node *np,
  376. struct s3c_irq_data *irq_data,
  377. struct s3c_irq_intc *parent,
  378. unsigned long address)
  379. {
  380. struct s3c_irq_intc *intc;
  381. void __iomem *base = (void *)0xf6000000; /* static mapping */
  382. int irq_num;
  383. int irq_start;
  384. int irq_offset;
  385. int ret;
  386. intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
  387. if (!intc)
  388. return ERR_PTR(-ENOMEM);
  389. intc->irqs = irq_data;
  390. if (parent)
  391. intc->parent = parent;
  392. /* select the correct data for the controller.
  393. * Need to hard code the irq num start and offset
  394. * to preserve the static mapping for now
  395. */
  396. switch (address) {
  397. case 0x4a000000:
  398. pr_debug("irq: found main intc\n");
  399. intc->reg_pending = base;
  400. intc->reg_mask = base + 0x08;
  401. intc->reg_intpnd = base + 0x10;
  402. irq_num = 32;
  403. irq_start = S3C2410_IRQ(0);
  404. irq_offset = 0;
  405. break;
  406. case 0x4a000018:
  407. pr_debug("irq: found subintc\n");
  408. intc->reg_pending = base + 0x18;
  409. intc->reg_mask = base + 0x1c;
  410. irq_num = 29;
  411. irq_start = S3C2410_IRQSUB(0);
  412. irq_offset = 0;
  413. break;
  414. case 0x4a000040:
  415. pr_debug("irq: found intc2\n");
  416. intc->reg_pending = base + 0x40;
  417. intc->reg_mask = base + 0x48;
  418. intc->reg_intpnd = base + 0x50;
  419. irq_num = 8;
  420. irq_start = S3C2416_IRQ(0);
  421. irq_offset = 0;
  422. break;
  423. case 0x560000a4:
  424. pr_debug("irq: found eintc\n");
  425. base = (void *)0xfd000000;
  426. intc->reg_mask = base + 0xa4;
  427. intc->reg_pending = base + 0x08;
  428. irq_num = 20;
  429. irq_start = S3C2410_IRQ(32);
  430. irq_offset = 4;
  431. break;
  432. default:
  433. pr_err("irq: unsupported controller address\n");
  434. ret = -EINVAL;
  435. goto err;
  436. }
  437. /* now that all the data is complete, init the irq-domain */
  438. s3c24xx_clear_intc(intc);
  439. intc->domain = irq_domain_add_legacy(np, irq_num, irq_start,
  440. irq_offset, &s3c24xx_irq_ops,
  441. intc);
  442. if (!intc->domain) {
  443. pr_err("irq: could not create irq-domain\n");
  444. ret = -EINVAL;
  445. goto err;
  446. }
  447. return intc;
  448. err:
  449. kfree(intc);
  450. return ERR_PTR(ret);
  451. }
  452. /* s3c24xx_init_irq
  453. *
  454. * Initialise S3C2410 IRQ system
  455. */
  456. static struct s3c_irq_data init_base[32] = {
  457. { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  458. { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  459. { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  460. { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  461. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  462. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  463. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  464. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  465. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  466. { .type = S3C_IRQTYPE_EDGE, }, /* WDT */
  467. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  468. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  469. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  470. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  471. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  472. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  473. { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
  474. { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
  475. { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
  476. { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
  477. { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
  478. { .type = S3C_IRQTYPE_EDGE, }, /* SDI */
  479. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  480. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  481. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  482. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  483. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  484. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  485. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  486. { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  487. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  488. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  489. };
  490. static struct s3c_irq_data init_eint[32] = {
  491. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  492. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  493. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  494. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  495. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */
  496. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */
  497. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */
  498. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */
  499. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */
  500. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */
  501. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */
  502. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */
  503. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */
  504. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */
  505. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */
  506. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */
  507. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */
  508. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */
  509. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */
  510. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */
  511. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */
  512. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */
  513. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */
  514. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */
  515. };
  516. static struct s3c_irq_data init_subint[32] = {
  517. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  518. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  519. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  520. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  521. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  522. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  523. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  524. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  525. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  526. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  527. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  528. };
  529. void __init s3c24xx_init_irq(void)
  530. {
  531. struct s3c_irq_intc *main_intc;
  532. #ifdef CONFIG_FIQ
  533. init_FIQ(FIQ_START);
  534. #endif
  535. main_intc = s3c24xx_init_intc(NULL, &init_base[0], NULL, 0x4a000000);
  536. if (IS_ERR(main_intc)) {
  537. pr_err("irq: could not create main interrupt controller\n");
  538. return;
  539. }
  540. s3c24xx_init_intc(NULL, &init_subint[0], main_intc, 0x4a000018);
  541. s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
  542. }
  543. #ifdef CONFIG_CPU_S3C2416
  544. static struct s3c_irq_data init_s3c2416base[32] = {
  545. { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  546. { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  547. { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  548. { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  549. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  550. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  551. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  552. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  553. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  554. { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
  555. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  556. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  557. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  558. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  559. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  560. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  561. { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */
  562. { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
  563. { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */
  564. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  565. { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
  566. { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
  567. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  568. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  569. { .type = S3C_IRQTYPE_EDGE, }, /* NAND */
  570. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  571. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  572. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  573. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  574. { .type = S3C_IRQTYPE_NONE, },
  575. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  576. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  577. };
  578. static struct s3c_irq_data init_s3c2416subint[32] = {
  579. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  580. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  581. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  582. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  583. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  584. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  585. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  586. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  587. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  588. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  589. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  590. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  591. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  592. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  593. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  594. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
  595. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
  596. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
  597. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
  598. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
  599. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
  600. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
  601. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
  602. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
  603. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
  604. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
  605. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
  606. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
  607. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
  608. };
  609. static struct s3c_irq_data init_s3c2416_second[32] = {
  610. { .type = S3C_IRQTYPE_EDGE }, /* 2D */
  611. { .type = S3C_IRQTYPE_EDGE }, /* IIC1 */
  612. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  613. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  614. { .type = S3C_IRQTYPE_EDGE }, /* PCM0 */
  615. { .type = S3C_IRQTYPE_EDGE }, /* PCM1 */
  616. { .type = S3C_IRQTYPE_EDGE }, /* I2S0 */
  617. { .type = S3C_IRQTYPE_EDGE }, /* I2S1 */
  618. };
  619. void __init s3c2416_init_irq(void)
  620. {
  621. struct s3c_irq_intc *main_intc;
  622. pr_info("S3C2416: IRQ Support\n");
  623. #ifdef CONFIG_FIQ
  624. init_FIQ(FIQ_START);
  625. #endif
  626. main_intc = s3c24xx_init_intc(NULL, &init_s3c2416base[0], NULL, 0x4a000000);
  627. if (IS_ERR(main_intc)) {
  628. pr_err("irq: could not create main interrupt controller\n");
  629. return;
  630. }
  631. s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
  632. s3c24xx_init_intc(NULL, &init_s3c2416subint[0], main_intc, 0x4a000018);
  633. s3c24xx_init_intc(NULL, &init_s3c2416_second[0], NULL, 0x4a000040);
  634. }
  635. #endif
  636. #ifdef CONFIG_CPU_S3C244X
  637. /* camera irq */
  638. static void s3c_irq_demux_cam(unsigned int irq,
  639. struct irq_desc *desc)
  640. {
  641. unsigned int subsrc, submsk;
  642. /* read the current pending interrupts, and the mask
  643. * for what it is available */
  644. subsrc = __raw_readl(S3C2410_SUBSRCPND);
  645. submsk = __raw_readl(S3C2410_INTSUBMSK);
  646. subsrc &= ~submsk;
  647. subsrc >>= 11;
  648. subsrc &= 3;
  649. if (subsrc != 0) {
  650. if (subsrc & 1) {
  651. generic_handle_irq(IRQ_S3C2440_CAM_C);
  652. }
  653. if (subsrc & 2) {
  654. generic_handle_irq(IRQ_S3C2440_CAM_P);
  655. }
  656. }
  657. }
  658. #define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
  659. static void
  660. s3c_irq_cam_mask(struct irq_data *data)
  661. {
  662. s3c_irqsub_mask(data->irq, INTMSK_CAM, 3 << 11);
  663. }
  664. static void
  665. s3c_irq_cam_unmask(struct irq_data *data)
  666. {
  667. s3c_irqsub_unmask(data->irq, INTMSK_CAM);
  668. }
  669. static void
  670. s3c_irq_cam_ack(struct irq_data *data)
  671. {
  672. s3c_irqsub_maskack(data->irq, INTMSK_CAM, 3 << 11);
  673. }
  674. static struct irq_chip s3c_irq_cam = {
  675. .irq_mask = s3c_irq_cam_mask,
  676. .irq_unmask = s3c_irq_cam_unmask,
  677. .irq_ack = s3c_irq_cam_ack,
  678. };
  679. #ifdef CONFIG_CPU_S3C2440
  680. /* WDT/AC97 */
  681. static void s3c_irq_demux_wdtac97(unsigned int irq,
  682. struct irq_desc *desc)
  683. {
  684. unsigned int subsrc, submsk;
  685. /* read the current pending interrupts, and the mask
  686. * for what it is available */
  687. subsrc = __raw_readl(S3C2410_SUBSRCPND);
  688. submsk = __raw_readl(S3C2410_INTSUBMSK);
  689. subsrc &= ~submsk;
  690. subsrc >>= 13;
  691. subsrc &= 3;
  692. if (subsrc != 0) {
  693. if (subsrc & 1) {
  694. generic_handle_irq(IRQ_S3C2440_WDT);
  695. }
  696. if (subsrc & 2) {
  697. generic_handle_irq(IRQ_S3C2440_AC97);
  698. }
  699. }
  700. }
  701. #define INTMSK_WDT (1UL << (IRQ_WDT - IRQ_EINT0))
  702. static void
  703. s3c_irq_wdtac97_mask(struct irq_data *data)
  704. {
  705. s3c_irqsub_mask(data->irq, INTMSK_WDT, 3 << 13);
  706. }
  707. static void
  708. s3c_irq_wdtac97_unmask(struct irq_data *data)
  709. {
  710. s3c_irqsub_unmask(data->irq, INTMSK_WDT);
  711. }
  712. static void
  713. s3c_irq_wdtac97_ack(struct irq_data *data)
  714. {
  715. s3c_irqsub_maskack(data->irq, INTMSK_WDT, 3 << 13);
  716. }
  717. static struct irq_chip s3c_irq_wdtac97 = {
  718. .irq_mask = s3c_irq_wdtac97_mask,
  719. .irq_unmask = s3c_irq_wdtac97_unmask,
  720. .irq_ack = s3c_irq_wdtac97_ack,
  721. };
  722. void __init s3c2440_init_irq(void)
  723. {
  724. unsigned int irqno;
  725. printk("S3C2440: IRQ Support\n");
  726. s3c24xx_init_irq();
  727. irq_set_chip_and_handler(IRQ_NFCON, &s3c_irq_level_chip,
  728. handle_level_irq);
  729. set_irq_flags(IRQ_NFCON, IRQF_VALID);
  730. /* add chained handler for camera */
  731. irq_set_chip_and_handler(IRQ_CAM, &s3c_irq_level_chip,
  732. handle_level_irq);
  733. irq_set_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
  734. for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
  735. irq_set_chip_and_handler(irqno, &s3c_irq_cam,
  736. handle_level_irq);
  737. set_irq_flags(irqno, IRQF_VALID);
  738. }
  739. /* add new chained handler for wdt, ac7 */
  740. irq_set_chip_and_handler(IRQ_WDT, &s3c_irq_level_chip,
  741. handle_level_irq);
  742. irq_set_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97);
  743. for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) {
  744. irq_set_chip_and_handler(irqno, &s3c_irq_wdtac97,
  745. handle_level_irq);
  746. set_irq_flags(irqno, IRQF_VALID);
  747. }
  748. }
  749. #endif
  750. #ifdef CONFIG_CPU_S3C2442
  751. static struct s3c_irq_data init_s3c2442base[32] = {
  752. { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  753. { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  754. { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  755. { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  756. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  757. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  758. { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
  759. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  760. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  761. { .type = S3C_IRQTYPE_EDGE, }, /* WDT */
  762. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  763. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  764. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  765. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  766. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  767. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  768. { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
  769. { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
  770. { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
  771. { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
  772. { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
  773. { .type = S3C_IRQTYPE_EDGE, }, /* SDI */
  774. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  775. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  776. { .type = S3C_IRQTYPE_LEVEL, }, /* NFCON */
  777. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  778. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  779. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  780. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  781. { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  782. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  783. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  784. };
  785. static struct s3c_irq_data init_s3c2442subint[32] = {
  786. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  787. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  788. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  789. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  790. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  791. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  792. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  793. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  794. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  795. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  796. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  797. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* TC */
  798. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* ADC */
  799. };
  800. void __init s3c2442_init_irq(void)
  801. {
  802. struct s3c_irq_intc *main_intc;
  803. pr_info("S3C2442: IRQ Support\n");
  804. #ifdef CONFIG_FIQ
  805. init_FIQ(FIQ_START);
  806. #endif
  807. main_intc = s3c24xx_init_intc(NULL, &init_s3c2442base[0], NULL, 0x4a000000);
  808. if (IS_ERR(main_intc)) {
  809. pr_err("irq: could not create main interrupt controller\n");
  810. return;
  811. }
  812. s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
  813. s3c24xx_init_intc(NULL, &init_s3c2442subint[0], main_intc, 0x4a000018);
  814. }
  815. #endif
  816. #endif
  817. #ifdef CONFIG_CPU_S3C2443
  818. static struct s3c_irq_data init_s3c2443base[32] = {
  819. { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  820. { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  821. { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  822. { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  823. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  824. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  825. { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
  826. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  827. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  828. { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
  829. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  830. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  831. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  832. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  833. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  834. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  835. { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */
  836. { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
  837. { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */
  838. { .type = S3C_IRQTYPE_EDGE, }, /* CFON */
  839. { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
  840. { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
  841. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  842. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  843. { .type = S3C_IRQTYPE_EDGE, }, /* NAND */
  844. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  845. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  846. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  847. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  848. { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  849. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  850. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  851. };
  852. static struct s3c_irq_data init_s3c2443subint[32] = {
  853. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  854. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  855. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  856. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  857. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  858. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  859. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  860. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  861. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  862. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  863. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  864. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */
  865. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */
  866. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  867. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD1 */
  868. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
  869. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
  870. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
  871. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
  872. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
  873. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
  874. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
  875. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
  876. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
  877. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
  878. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
  879. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
  880. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
  881. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
  882. };
  883. void __init s3c2443_init_irq(void)
  884. {
  885. struct s3c_irq_intc *main_intc;
  886. pr_info("S3C2443: IRQ Support\n");
  887. #ifdef CONFIG_FIQ
  888. init_FIQ(FIQ_START);
  889. #endif
  890. main_intc = s3c24xx_init_intc(NULL, &init_s3c2443base[0], NULL, 0x4a000000);
  891. if (IS_ERR(main_intc)) {
  892. pr_err("irq: could not create main interrupt controller\n");
  893. return;
  894. }
  895. s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
  896. s3c24xx_init_intc(NULL, &init_s3c2443subint[0], main_intc, 0x4a000018);
  897. }
  898. #endif