irq-s3c24xx.c 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339
  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 <linux/irqchip.h>
  28. #include <linux/irqchip/chained_irq.h>
  29. #include <linux/of.h>
  30. #include <linux/of_irq.h>
  31. #include <linux/of_address.h>
  32. #include <asm/exception.h>
  33. #include <asm/mach/irq.h>
  34. #include <mach/regs-irq.h>
  35. #include <mach/regs-gpio.h>
  36. #include <plat/cpu.h>
  37. #include <plat/regs-irqtype.h>
  38. #include <plat/pm.h>
  39. #define S3C_IRQTYPE_NONE 0
  40. #define S3C_IRQTYPE_EINT 1
  41. #define S3C_IRQTYPE_EDGE 2
  42. #define S3C_IRQTYPE_LEVEL 3
  43. struct s3c_irq_data {
  44. unsigned int type;
  45. unsigned long offset;
  46. unsigned long parent_irq;
  47. /* data gets filled during init */
  48. struct s3c_irq_intc *intc;
  49. unsigned long sub_bits;
  50. struct s3c_irq_intc *sub_intc;
  51. };
  52. /*
  53. * Sructure holding the controller data
  54. * @reg_pending register holding pending irqs
  55. * @reg_intpnd special register intpnd in main intc
  56. * @reg_mask mask register
  57. * @domain irq_domain of the controller
  58. * @parent parent controller for ext and sub irqs
  59. * @irqs irq-data, always s3c_irq_data[32]
  60. */
  61. struct s3c_irq_intc {
  62. void __iomem *reg_pending;
  63. void __iomem *reg_intpnd;
  64. void __iomem *reg_mask;
  65. struct irq_domain *domain;
  66. struct s3c_irq_intc *parent;
  67. struct s3c_irq_data *irqs;
  68. };
  69. /*
  70. * Array holding pointers to the global controller structs
  71. * [0] ... main_intc
  72. * [1] ... sub_intc
  73. * [2] ... main_intc2 on s3c2416
  74. */
  75. static struct s3c_irq_intc *s3c_intc[3];
  76. static void s3c_irq_mask(struct irq_data *data)
  77. {
  78. struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data);
  79. struct s3c_irq_intc *intc = irq_data->intc;
  80. struct s3c_irq_intc *parent_intc = intc->parent;
  81. struct s3c_irq_data *parent_data;
  82. unsigned long mask;
  83. unsigned int irqno;
  84. mask = __raw_readl(intc->reg_mask);
  85. mask |= (1UL << irq_data->offset);
  86. __raw_writel(mask, intc->reg_mask);
  87. if (parent_intc) {
  88. parent_data = &parent_intc->irqs[irq_data->parent_irq];
  89. /* check to see if we need to mask the parent IRQ
  90. * The parent_irq is always in main_intc, so the hwirq
  91. * for find_mapping does not need an offset in any case.
  92. */
  93. if ((mask & parent_data->sub_bits) == parent_data->sub_bits) {
  94. irqno = irq_find_mapping(parent_intc->domain,
  95. irq_data->parent_irq);
  96. s3c_irq_mask(irq_get_irq_data(irqno));
  97. }
  98. }
  99. }
  100. static void s3c_irq_unmask(struct irq_data *data)
  101. {
  102. struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data);
  103. struct s3c_irq_intc *intc = irq_data->intc;
  104. struct s3c_irq_intc *parent_intc = intc->parent;
  105. unsigned long mask;
  106. unsigned int irqno;
  107. mask = __raw_readl(intc->reg_mask);
  108. mask &= ~(1UL << irq_data->offset);
  109. __raw_writel(mask, intc->reg_mask);
  110. if (parent_intc) {
  111. irqno = irq_find_mapping(parent_intc->domain,
  112. irq_data->parent_irq);
  113. s3c_irq_unmask(irq_get_irq_data(irqno));
  114. }
  115. }
  116. static inline void s3c_irq_ack(struct irq_data *data)
  117. {
  118. struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data);
  119. struct s3c_irq_intc *intc = irq_data->intc;
  120. unsigned long bitval = 1UL << irq_data->offset;
  121. __raw_writel(bitval, intc->reg_pending);
  122. if (intc->reg_intpnd)
  123. __raw_writel(bitval, intc->reg_intpnd);
  124. }
  125. static int s3c_irq_type(struct irq_data *data, unsigned int type)
  126. {
  127. switch (type) {
  128. case IRQ_TYPE_NONE:
  129. break;
  130. case IRQ_TYPE_EDGE_RISING:
  131. case IRQ_TYPE_EDGE_FALLING:
  132. case IRQ_TYPE_EDGE_BOTH:
  133. irq_set_handler(data->irq, handle_edge_irq);
  134. break;
  135. case IRQ_TYPE_LEVEL_LOW:
  136. case IRQ_TYPE_LEVEL_HIGH:
  137. irq_set_handler(data->irq, handle_level_irq);
  138. break;
  139. default:
  140. pr_err("No such irq type %d", type);
  141. return -EINVAL;
  142. }
  143. return 0;
  144. }
  145. static int s3c_irqext_type_set(void __iomem *gpcon_reg,
  146. void __iomem *extint_reg,
  147. unsigned long gpcon_offset,
  148. unsigned long extint_offset,
  149. unsigned int type)
  150. {
  151. unsigned long newvalue = 0, value;
  152. /* Set the GPIO to external interrupt mode */
  153. value = __raw_readl(gpcon_reg);
  154. value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
  155. __raw_writel(value, gpcon_reg);
  156. /* Set the external interrupt to pointed trigger type */
  157. switch (type)
  158. {
  159. case IRQ_TYPE_NONE:
  160. pr_warn("No edge setting!\n");
  161. break;
  162. case IRQ_TYPE_EDGE_RISING:
  163. newvalue = S3C2410_EXTINT_RISEEDGE;
  164. break;
  165. case IRQ_TYPE_EDGE_FALLING:
  166. newvalue = S3C2410_EXTINT_FALLEDGE;
  167. break;
  168. case IRQ_TYPE_EDGE_BOTH:
  169. newvalue = S3C2410_EXTINT_BOTHEDGE;
  170. break;
  171. case IRQ_TYPE_LEVEL_LOW:
  172. newvalue = S3C2410_EXTINT_LOWLEV;
  173. break;
  174. case IRQ_TYPE_LEVEL_HIGH:
  175. newvalue = S3C2410_EXTINT_HILEV;
  176. break;
  177. default:
  178. pr_err("No such irq type %d", type);
  179. return -EINVAL;
  180. }
  181. value = __raw_readl(extint_reg);
  182. value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
  183. __raw_writel(value, extint_reg);
  184. return 0;
  185. }
  186. static int s3c_irqext_type(struct irq_data *data, unsigned int type)
  187. {
  188. void __iomem *extint_reg;
  189. void __iomem *gpcon_reg;
  190. unsigned long gpcon_offset, extint_offset;
  191. if ((data->hwirq >= 4) && (data->hwirq <= 7)) {
  192. gpcon_reg = S3C2410_GPFCON;
  193. extint_reg = S3C24XX_EXTINT0;
  194. gpcon_offset = (data->hwirq) * 2;
  195. extint_offset = (data->hwirq) * 4;
  196. } else if ((data->hwirq >= 8) && (data->hwirq <= 15)) {
  197. gpcon_reg = S3C2410_GPGCON;
  198. extint_reg = S3C24XX_EXTINT1;
  199. gpcon_offset = (data->hwirq - 8) * 2;
  200. extint_offset = (data->hwirq - 8) * 4;
  201. } else if ((data->hwirq >= 16) && (data->hwirq <= 23)) {
  202. gpcon_reg = S3C2410_GPGCON;
  203. extint_reg = S3C24XX_EXTINT2;
  204. gpcon_offset = (data->hwirq - 8) * 2;
  205. extint_offset = (data->hwirq - 16) * 4;
  206. } else {
  207. return -EINVAL;
  208. }
  209. return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
  210. extint_offset, type);
  211. }
  212. static int s3c_irqext0_type(struct irq_data *data, unsigned int type)
  213. {
  214. void __iomem *extint_reg;
  215. void __iomem *gpcon_reg;
  216. unsigned long gpcon_offset, extint_offset;
  217. if ((data->hwirq >= 0) && (data->hwirq <= 3)) {
  218. gpcon_reg = S3C2410_GPFCON;
  219. extint_reg = S3C24XX_EXTINT0;
  220. gpcon_offset = (data->hwirq) * 2;
  221. extint_offset = (data->hwirq) * 4;
  222. } else {
  223. return -EINVAL;
  224. }
  225. return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
  226. extint_offset, type);
  227. }
  228. static struct irq_chip s3c_irq_chip = {
  229. .name = "s3c",
  230. .irq_ack = s3c_irq_ack,
  231. .irq_mask = s3c_irq_mask,
  232. .irq_unmask = s3c_irq_unmask,
  233. .irq_set_type = s3c_irq_type,
  234. .irq_set_wake = s3c_irq_wake
  235. };
  236. static struct irq_chip s3c_irq_level_chip = {
  237. .name = "s3c-level",
  238. .irq_mask = s3c_irq_mask,
  239. .irq_unmask = s3c_irq_unmask,
  240. .irq_ack = s3c_irq_ack,
  241. .irq_set_type = s3c_irq_type,
  242. };
  243. static struct irq_chip s3c_irqext_chip = {
  244. .name = "s3c-ext",
  245. .irq_mask = s3c_irq_mask,
  246. .irq_unmask = s3c_irq_unmask,
  247. .irq_ack = s3c_irq_ack,
  248. .irq_set_type = s3c_irqext_type,
  249. .irq_set_wake = s3c_irqext_wake
  250. };
  251. static struct irq_chip s3c_irq_eint0t4 = {
  252. .name = "s3c-ext0",
  253. .irq_ack = s3c_irq_ack,
  254. .irq_mask = s3c_irq_mask,
  255. .irq_unmask = s3c_irq_unmask,
  256. .irq_set_wake = s3c_irq_wake,
  257. .irq_set_type = s3c_irqext0_type,
  258. };
  259. static void s3c_irq_demux(struct irq_desc *desc)
  260. {
  261. struct irq_chip *chip = irq_desc_get_chip(desc);
  262. struct s3c_irq_data *irq_data = irq_desc_get_chip_data(desc);
  263. struct s3c_irq_intc *intc = irq_data->intc;
  264. struct s3c_irq_intc *sub_intc = irq_data->sub_intc;
  265. unsigned int n, offset, irq;
  266. unsigned long src, msk;
  267. /* we're using individual domains for the non-dt case
  268. * and one big domain for the dt case where the subintc
  269. * starts at hwirq number 32.
  270. */
  271. offset = irq_domain_get_of_node(intc->domain) ? 32 : 0;
  272. chained_irq_enter(chip, desc);
  273. src = __raw_readl(sub_intc->reg_pending);
  274. msk = __raw_readl(sub_intc->reg_mask);
  275. src &= ~msk;
  276. src &= irq_data->sub_bits;
  277. while (src) {
  278. n = __ffs(src);
  279. src &= ~(1 << n);
  280. irq = irq_find_mapping(sub_intc->domain, offset + n);
  281. generic_handle_irq(irq);
  282. }
  283. chained_irq_exit(chip, desc);
  284. }
  285. static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc,
  286. struct pt_regs *regs, int intc_offset)
  287. {
  288. int pnd;
  289. int offset;
  290. pnd = __raw_readl(intc->reg_intpnd);
  291. if (!pnd)
  292. return false;
  293. /* non-dt machines use individual domains */
  294. if (!irq_domain_get_of_node(intc->domain))
  295. intc_offset = 0;
  296. /* We have a problem that the INTOFFSET register does not always
  297. * show one interrupt. Occasionally we get two interrupts through
  298. * the prioritiser, and this causes the INTOFFSET register to show
  299. * what looks like the logical-or of the two interrupt numbers.
  300. *
  301. * Thanks to Klaus, Shannon, et al for helping to debug this problem
  302. */
  303. offset = __raw_readl(intc->reg_intpnd + 4);
  304. /* Find the bit manually, when the offset is wrong.
  305. * The pending register only ever contains the one bit of the next
  306. * interrupt to handle.
  307. */
  308. if (!(pnd & (1 << offset)))
  309. offset = __ffs(pnd);
  310. handle_domain_irq(intc->domain, intc_offset + offset, regs);
  311. return true;
  312. }
  313. asmlinkage void __exception_irq_entry s3c24xx_handle_irq(struct pt_regs *regs)
  314. {
  315. do {
  316. if (likely(s3c_intc[0]))
  317. if (s3c24xx_handle_intc(s3c_intc[0], regs, 0))
  318. continue;
  319. if (s3c_intc[2])
  320. if (s3c24xx_handle_intc(s3c_intc[2], regs, 64))
  321. continue;
  322. break;
  323. } while (1);
  324. }
  325. #ifdef CONFIG_FIQ
  326. /**
  327. * s3c24xx_set_fiq - set the FIQ routing
  328. * @irq: IRQ number to route to FIQ on processor.
  329. * @on: Whether to route @irq to the FIQ, or to remove the FIQ routing.
  330. *
  331. * Change the state of the IRQ to FIQ routing depending on @irq and @on. If
  332. * @on is true, the @irq is checked to see if it can be routed and the
  333. * interrupt controller updated to route the IRQ. If @on is false, the FIQ
  334. * routing is cleared, regardless of which @irq is specified.
  335. */
  336. int s3c24xx_set_fiq(unsigned int irq, bool on)
  337. {
  338. u32 intmod;
  339. unsigned offs;
  340. if (on) {
  341. offs = irq - FIQ_START;
  342. if (offs > 31)
  343. return -EINVAL;
  344. intmod = 1 << offs;
  345. } else {
  346. intmod = 0;
  347. }
  348. __raw_writel(intmod, S3C2410_INTMOD);
  349. return 0;
  350. }
  351. EXPORT_SYMBOL_GPL(s3c24xx_set_fiq);
  352. #endif
  353. static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
  354. irq_hw_number_t hw)
  355. {
  356. struct s3c_irq_intc *intc = h->host_data;
  357. struct s3c_irq_data *irq_data = &intc->irqs[hw];
  358. struct s3c_irq_intc *parent_intc;
  359. struct s3c_irq_data *parent_irq_data;
  360. unsigned int irqno;
  361. /* attach controller pointer to irq_data */
  362. irq_data->intc = intc;
  363. irq_data->offset = hw;
  364. parent_intc = intc->parent;
  365. /* set handler and flags */
  366. switch (irq_data->type) {
  367. case S3C_IRQTYPE_NONE:
  368. return 0;
  369. case S3C_IRQTYPE_EINT:
  370. /* On the S3C2412, the EINT0to3 have a parent irq
  371. * but need the s3c_irq_eint0t4 chip
  372. */
  373. if (parent_intc && (!soc_is_s3c2412() || hw >= 4))
  374. irq_set_chip_and_handler(virq, &s3c_irqext_chip,
  375. handle_edge_irq);
  376. else
  377. irq_set_chip_and_handler(virq, &s3c_irq_eint0t4,
  378. handle_edge_irq);
  379. break;
  380. case S3C_IRQTYPE_EDGE:
  381. if (parent_intc || intc->reg_pending == S3C2416_SRCPND2)
  382. irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
  383. handle_edge_irq);
  384. else
  385. irq_set_chip_and_handler(virq, &s3c_irq_chip,
  386. handle_edge_irq);
  387. break;
  388. case S3C_IRQTYPE_LEVEL:
  389. if (parent_intc)
  390. irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
  391. handle_level_irq);
  392. else
  393. irq_set_chip_and_handler(virq, &s3c_irq_chip,
  394. handle_level_irq);
  395. break;
  396. default:
  397. pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type);
  398. return -EINVAL;
  399. }
  400. irq_set_chip_data(virq, irq_data);
  401. if (parent_intc && irq_data->type != S3C_IRQTYPE_NONE) {
  402. if (irq_data->parent_irq > 31) {
  403. pr_err("irq-s3c24xx: parent irq %lu is out of range\n",
  404. irq_data->parent_irq);
  405. return -EINVAL;
  406. }
  407. parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
  408. parent_irq_data->sub_intc = intc;
  409. parent_irq_data->sub_bits |= (1UL << hw);
  410. /* attach the demuxer to the parent irq */
  411. irqno = irq_find_mapping(parent_intc->domain,
  412. irq_data->parent_irq);
  413. if (!irqno) {
  414. pr_err("irq-s3c24xx: could not find mapping for parent irq %lu\n",
  415. irq_data->parent_irq);
  416. return -EINVAL;
  417. }
  418. irq_set_chained_handler(irqno, s3c_irq_demux);
  419. }
  420. return 0;
  421. }
  422. static const struct irq_domain_ops s3c24xx_irq_ops = {
  423. .map = s3c24xx_irq_map,
  424. .xlate = irq_domain_xlate_twocell,
  425. };
  426. static void s3c24xx_clear_intc(struct s3c_irq_intc *intc)
  427. {
  428. void __iomem *reg_source;
  429. unsigned long pend;
  430. unsigned long last;
  431. int i;
  432. /* if intpnd is set, read the next pending irq from there */
  433. reg_source = intc->reg_intpnd ? intc->reg_intpnd : intc->reg_pending;
  434. last = 0;
  435. for (i = 0; i < 4; i++) {
  436. pend = __raw_readl(reg_source);
  437. if (pend == 0 || pend == last)
  438. break;
  439. __raw_writel(pend, intc->reg_pending);
  440. if (intc->reg_intpnd)
  441. __raw_writel(pend, intc->reg_intpnd);
  442. pr_info("irq: clearing pending status %08x\n", (int)pend);
  443. last = pend;
  444. }
  445. }
  446. static struct s3c_irq_intc * __init s3c24xx_init_intc(struct device_node *np,
  447. struct s3c_irq_data *irq_data,
  448. struct s3c_irq_intc *parent,
  449. unsigned long address)
  450. {
  451. struct s3c_irq_intc *intc;
  452. void __iomem *base = (void *)0xf6000000; /* static mapping */
  453. int irq_num;
  454. int irq_start;
  455. int ret;
  456. intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
  457. if (!intc)
  458. return ERR_PTR(-ENOMEM);
  459. intc->irqs = irq_data;
  460. if (parent)
  461. intc->parent = parent;
  462. /* select the correct data for the controller.
  463. * Need to hard code the irq num start and offset
  464. * to preserve the static mapping for now
  465. */
  466. switch (address) {
  467. case 0x4a000000:
  468. pr_debug("irq: found main intc\n");
  469. intc->reg_pending = base;
  470. intc->reg_mask = base + 0x08;
  471. intc->reg_intpnd = base + 0x10;
  472. irq_num = 32;
  473. irq_start = S3C2410_IRQ(0);
  474. break;
  475. case 0x4a000018:
  476. pr_debug("irq: found subintc\n");
  477. intc->reg_pending = base + 0x18;
  478. intc->reg_mask = base + 0x1c;
  479. irq_num = 29;
  480. irq_start = S3C2410_IRQSUB(0);
  481. break;
  482. case 0x4a000040:
  483. pr_debug("irq: found intc2\n");
  484. intc->reg_pending = base + 0x40;
  485. intc->reg_mask = base + 0x48;
  486. intc->reg_intpnd = base + 0x50;
  487. irq_num = 8;
  488. irq_start = S3C2416_IRQ(0);
  489. break;
  490. case 0x560000a4:
  491. pr_debug("irq: found eintc\n");
  492. base = (void *)0xfd000000;
  493. intc->reg_mask = base + 0xa4;
  494. intc->reg_pending = base + 0xa8;
  495. irq_num = 24;
  496. irq_start = S3C2410_IRQ(32);
  497. break;
  498. default:
  499. pr_err("irq: unsupported controller address\n");
  500. ret = -EINVAL;
  501. goto err;
  502. }
  503. /* now that all the data is complete, init the irq-domain */
  504. s3c24xx_clear_intc(intc);
  505. intc->domain = irq_domain_add_legacy(np, irq_num, irq_start,
  506. 0, &s3c24xx_irq_ops,
  507. intc);
  508. if (!intc->domain) {
  509. pr_err("irq: could not create irq-domain\n");
  510. ret = -EINVAL;
  511. goto err;
  512. }
  513. set_handle_irq(s3c24xx_handle_irq);
  514. return intc;
  515. err:
  516. kfree(intc);
  517. return ERR_PTR(ret);
  518. }
  519. static struct s3c_irq_data init_eint[32] = {
  520. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  521. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  522. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  523. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  524. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */
  525. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */
  526. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */
  527. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */
  528. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */
  529. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */
  530. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */
  531. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */
  532. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */
  533. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */
  534. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */
  535. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */
  536. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */
  537. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */
  538. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */
  539. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */
  540. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */
  541. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */
  542. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */
  543. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */
  544. };
  545. #ifdef CONFIG_CPU_S3C2410
  546. static struct s3c_irq_data init_s3c2410base[32] = {
  547. { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  548. { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  549. { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  550. { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  551. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  552. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  553. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  554. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  555. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  556. { .type = S3C_IRQTYPE_EDGE, }, /* WDT */
  557. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  558. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  559. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  560. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  561. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  562. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  563. { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
  564. { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
  565. { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
  566. { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
  567. { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
  568. { .type = S3C_IRQTYPE_EDGE, }, /* SDI */
  569. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  570. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  571. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  572. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  573. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  574. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  575. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  576. { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  577. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  578. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  579. };
  580. static struct s3c_irq_data init_s3c2410subint[32] = {
  581. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  582. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  583. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  584. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  585. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  586. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  587. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  588. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  589. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  590. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  591. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  592. };
  593. void __init s3c2410_init_irq(void)
  594. {
  595. #ifdef CONFIG_FIQ
  596. init_FIQ(FIQ_START);
  597. #endif
  598. s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2410base[0], NULL,
  599. 0x4a000000);
  600. if (IS_ERR(s3c_intc[0])) {
  601. pr_err("irq: could not create main interrupt controller\n");
  602. return;
  603. }
  604. s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2410subint[0],
  605. s3c_intc[0], 0x4a000018);
  606. s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4);
  607. }
  608. #endif
  609. #ifdef CONFIG_CPU_S3C2412
  610. static struct s3c_irq_data init_s3c2412base[32] = {
  611. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT0 */
  612. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT1 */
  613. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT2 */
  614. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT3 */
  615. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  616. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  617. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  618. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  619. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  620. { .type = S3C_IRQTYPE_EDGE, }, /* WDT */
  621. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  622. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  623. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  624. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  625. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  626. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  627. { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
  628. { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
  629. { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
  630. { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
  631. { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
  632. { .type = S3C_IRQTYPE_LEVEL, }, /* SDI/CF */
  633. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  634. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  635. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  636. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  637. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  638. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  639. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  640. { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  641. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  642. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  643. };
  644. static struct s3c_irq_data init_s3c2412eint[32] = {
  645. { .type = S3C_IRQTYPE_EINT, .parent_irq = 0 }, /* EINT0 */
  646. { .type = S3C_IRQTYPE_EINT, .parent_irq = 1 }, /* EINT1 */
  647. { .type = S3C_IRQTYPE_EINT, .parent_irq = 2 }, /* EINT2 */
  648. { .type = S3C_IRQTYPE_EINT, .parent_irq = 3 }, /* EINT3 */
  649. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */
  650. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */
  651. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */
  652. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */
  653. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */
  654. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */
  655. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */
  656. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */
  657. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */
  658. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */
  659. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */
  660. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */
  661. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */
  662. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */
  663. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */
  664. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */
  665. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */
  666. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */
  667. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */
  668. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */
  669. };
  670. static struct s3c_irq_data init_s3c2412subint[32] = {
  671. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  672. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  673. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  674. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  675. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  676. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  677. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  678. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  679. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  680. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  681. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  682. { .type = S3C_IRQTYPE_NONE, },
  683. { .type = S3C_IRQTYPE_NONE, },
  684. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* SDI */
  685. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* CF */
  686. };
  687. void __init s3c2412_init_irq(void)
  688. {
  689. pr_info("S3C2412: IRQ Support\n");
  690. #ifdef CONFIG_FIQ
  691. init_FIQ(FIQ_START);
  692. #endif
  693. s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2412base[0], NULL,
  694. 0x4a000000);
  695. if (IS_ERR(s3c_intc[0])) {
  696. pr_err("irq: could not create main interrupt controller\n");
  697. return;
  698. }
  699. s3c24xx_init_intc(NULL, &init_s3c2412eint[0], s3c_intc[0], 0x560000a4);
  700. s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2412subint[0],
  701. s3c_intc[0], 0x4a000018);
  702. }
  703. #endif
  704. #ifdef CONFIG_CPU_S3C2416
  705. static struct s3c_irq_data init_s3c2416base[32] = {
  706. { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  707. { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  708. { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  709. { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  710. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  711. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  712. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  713. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  714. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  715. { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
  716. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  717. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  718. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  719. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  720. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  721. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  722. { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */
  723. { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
  724. { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */
  725. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  726. { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
  727. { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
  728. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  729. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  730. { .type = S3C_IRQTYPE_EDGE, }, /* NAND */
  731. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  732. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  733. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  734. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  735. { .type = S3C_IRQTYPE_NONE, },
  736. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  737. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  738. };
  739. static struct s3c_irq_data init_s3c2416subint[32] = {
  740. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  741. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  742. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  743. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  744. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  745. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  746. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  747. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  748. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  749. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  750. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  751. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  752. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  753. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  754. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  755. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
  756. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
  757. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
  758. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
  759. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
  760. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
  761. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
  762. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
  763. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
  764. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
  765. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
  766. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
  767. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
  768. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
  769. };
  770. static struct s3c_irq_data init_s3c2416_second[32] = {
  771. { .type = S3C_IRQTYPE_EDGE }, /* 2D */
  772. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  773. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  774. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  775. { .type = S3C_IRQTYPE_EDGE }, /* PCM0 */
  776. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  777. { .type = S3C_IRQTYPE_EDGE }, /* I2S0 */
  778. };
  779. void __init s3c2416_init_irq(void)
  780. {
  781. pr_info("S3C2416: IRQ Support\n");
  782. #ifdef CONFIG_FIQ
  783. init_FIQ(FIQ_START);
  784. #endif
  785. s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2416base[0], NULL,
  786. 0x4a000000);
  787. if (IS_ERR(s3c_intc[0])) {
  788. pr_err("irq: could not create main interrupt controller\n");
  789. return;
  790. }
  791. s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4);
  792. s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2416subint[0],
  793. s3c_intc[0], 0x4a000018);
  794. s3c_intc[2] = s3c24xx_init_intc(NULL, &init_s3c2416_second[0],
  795. NULL, 0x4a000040);
  796. }
  797. #endif
  798. #ifdef CONFIG_CPU_S3C2440
  799. static struct s3c_irq_data init_s3c2440base[32] = {
  800. { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  801. { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  802. { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  803. { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  804. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  805. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  806. { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
  807. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  808. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  809. { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
  810. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  811. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  812. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  813. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  814. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  815. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  816. { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
  817. { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
  818. { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
  819. { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
  820. { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
  821. { .type = S3C_IRQTYPE_EDGE, }, /* SDI */
  822. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  823. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  824. { .type = S3C_IRQTYPE_LEVEL, }, /* NFCON */
  825. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  826. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  827. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  828. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  829. { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  830. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  831. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  832. };
  833. static struct s3c_irq_data init_s3c2440subint[32] = {
  834. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  835. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  836. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  837. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  838. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  839. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  840. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  841. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  842. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  843. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  844. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  845. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */
  846. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */
  847. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
  848. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
  849. };
  850. void __init s3c2440_init_irq(void)
  851. {
  852. pr_info("S3C2440: IRQ Support\n");
  853. #ifdef CONFIG_FIQ
  854. init_FIQ(FIQ_START);
  855. #endif
  856. s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2440base[0], NULL,
  857. 0x4a000000);
  858. if (IS_ERR(s3c_intc[0])) {
  859. pr_err("irq: could not create main interrupt controller\n");
  860. return;
  861. }
  862. s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4);
  863. s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2440subint[0],
  864. s3c_intc[0], 0x4a000018);
  865. }
  866. #endif
  867. #ifdef CONFIG_CPU_S3C2442
  868. static struct s3c_irq_data init_s3c2442base[32] = {
  869. { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  870. { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  871. { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  872. { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  873. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  874. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  875. { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
  876. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  877. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  878. { .type = S3C_IRQTYPE_EDGE, }, /* WDT */
  879. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  880. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  881. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  882. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  883. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  884. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  885. { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
  886. { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
  887. { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
  888. { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
  889. { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
  890. { .type = S3C_IRQTYPE_EDGE, }, /* SDI */
  891. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  892. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  893. { .type = S3C_IRQTYPE_LEVEL, }, /* NFCON */
  894. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  895. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  896. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  897. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  898. { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  899. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  900. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  901. };
  902. static struct s3c_irq_data init_s3c2442subint[32] = {
  903. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  904. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  905. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  906. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  907. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  908. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  909. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  910. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  911. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  912. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  913. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  914. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */
  915. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */
  916. };
  917. void __init s3c2442_init_irq(void)
  918. {
  919. pr_info("S3C2442: IRQ Support\n");
  920. #ifdef CONFIG_FIQ
  921. init_FIQ(FIQ_START);
  922. #endif
  923. s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2442base[0], NULL,
  924. 0x4a000000);
  925. if (IS_ERR(s3c_intc[0])) {
  926. pr_err("irq: could not create main interrupt controller\n");
  927. return;
  928. }
  929. s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4);
  930. s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2442subint[0],
  931. s3c_intc[0], 0x4a000018);
  932. }
  933. #endif
  934. #ifdef CONFIG_CPU_S3C2443
  935. static struct s3c_irq_data init_s3c2443base[32] = {
  936. { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  937. { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  938. { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  939. { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  940. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  941. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  942. { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
  943. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  944. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  945. { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
  946. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  947. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  948. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  949. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  950. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  951. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  952. { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */
  953. { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
  954. { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */
  955. { .type = S3C_IRQTYPE_EDGE, }, /* CFON */
  956. { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
  957. { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
  958. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  959. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  960. { .type = S3C_IRQTYPE_EDGE, }, /* NAND */
  961. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  962. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  963. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  964. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  965. { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  966. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  967. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  968. };
  969. static struct s3c_irq_data init_s3c2443subint[32] = {
  970. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  971. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  972. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  973. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  974. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  975. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  976. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  977. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  978. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  979. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  980. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  981. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */
  982. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */
  983. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  984. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD1 */
  985. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
  986. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
  987. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
  988. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
  989. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
  990. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
  991. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
  992. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
  993. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
  994. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
  995. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
  996. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
  997. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
  998. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
  999. };
  1000. void __init s3c2443_init_irq(void)
  1001. {
  1002. pr_info("S3C2443: IRQ Support\n");
  1003. #ifdef CONFIG_FIQ
  1004. init_FIQ(FIQ_START);
  1005. #endif
  1006. s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2443base[0], NULL,
  1007. 0x4a000000);
  1008. if (IS_ERR(s3c_intc[0])) {
  1009. pr_err("irq: could not create main interrupt controller\n");
  1010. return;
  1011. }
  1012. s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4);
  1013. s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2443subint[0],
  1014. s3c_intc[0], 0x4a000018);
  1015. }
  1016. #endif
  1017. #ifdef CONFIG_OF
  1018. static int s3c24xx_irq_map_of(struct irq_domain *h, unsigned int virq,
  1019. irq_hw_number_t hw)
  1020. {
  1021. unsigned int ctrl_num = hw / 32;
  1022. unsigned int intc_hw = hw % 32;
  1023. struct s3c_irq_intc *intc = s3c_intc[ctrl_num];
  1024. struct s3c_irq_intc *parent_intc = intc->parent;
  1025. struct s3c_irq_data *irq_data = &intc->irqs[intc_hw];
  1026. /* attach controller pointer to irq_data */
  1027. irq_data->intc = intc;
  1028. irq_data->offset = intc_hw;
  1029. if (!parent_intc)
  1030. irq_set_chip_and_handler(virq, &s3c_irq_chip, handle_edge_irq);
  1031. else
  1032. irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
  1033. handle_edge_irq);
  1034. irq_set_chip_data(virq, irq_data);
  1035. return 0;
  1036. }
  1037. /* Translate our of irq notation
  1038. * format: <ctrl_num ctrl_irq parent_irq type>
  1039. */
  1040. static int s3c24xx_irq_xlate_of(struct irq_domain *d, struct device_node *n,
  1041. const u32 *intspec, unsigned int intsize,
  1042. irq_hw_number_t *out_hwirq, unsigned int *out_type)
  1043. {
  1044. struct s3c_irq_intc *intc;
  1045. struct s3c_irq_intc *parent_intc;
  1046. struct s3c_irq_data *irq_data;
  1047. struct s3c_irq_data *parent_irq_data;
  1048. int irqno;
  1049. if (WARN_ON(intsize < 4))
  1050. return -EINVAL;
  1051. if (intspec[0] > 2 || !s3c_intc[intspec[0]]) {
  1052. pr_err("controller number %d invalid\n", intspec[0]);
  1053. return -EINVAL;
  1054. }
  1055. intc = s3c_intc[intspec[0]];
  1056. *out_hwirq = intspec[0] * 32 + intspec[2];
  1057. *out_type = intspec[3] & IRQ_TYPE_SENSE_MASK;
  1058. parent_intc = intc->parent;
  1059. if (parent_intc) {
  1060. irq_data = &intc->irqs[intspec[2]];
  1061. irq_data->parent_irq = intspec[1];
  1062. parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
  1063. parent_irq_data->sub_intc = intc;
  1064. parent_irq_data->sub_bits |= (1UL << intspec[2]);
  1065. /* parent_intc is always s3c_intc[0], so no offset */
  1066. irqno = irq_create_mapping(parent_intc->domain, intspec[1]);
  1067. if (irqno < 0) {
  1068. pr_err("irq: could not map parent interrupt\n");
  1069. return irqno;
  1070. }
  1071. irq_set_chained_handler(irqno, s3c_irq_demux);
  1072. }
  1073. return 0;
  1074. }
  1075. static const struct irq_domain_ops s3c24xx_irq_ops_of = {
  1076. .map = s3c24xx_irq_map_of,
  1077. .xlate = s3c24xx_irq_xlate_of,
  1078. };
  1079. struct s3c24xx_irq_of_ctrl {
  1080. char *name;
  1081. unsigned long offset;
  1082. struct s3c_irq_intc **handle;
  1083. struct s3c_irq_intc **parent;
  1084. struct irq_domain_ops *ops;
  1085. };
  1086. static int __init s3c_init_intc_of(struct device_node *np,
  1087. struct device_node *interrupt_parent,
  1088. struct s3c24xx_irq_of_ctrl *s3c_ctrl, int num_ctrl)
  1089. {
  1090. struct s3c_irq_intc *intc;
  1091. struct s3c24xx_irq_of_ctrl *ctrl;
  1092. struct irq_domain *domain;
  1093. void __iomem *reg_base;
  1094. int i;
  1095. reg_base = of_iomap(np, 0);
  1096. if (!reg_base) {
  1097. pr_err("irq-s3c24xx: could not map irq registers\n");
  1098. return -EINVAL;
  1099. }
  1100. domain = irq_domain_add_linear(np, num_ctrl * 32,
  1101. &s3c24xx_irq_ops_of, NULL);
  1102. if (!domain) {
  1103. pr_err("irq: could not create irq-domain\n");
  1104. return -EINVAL;
  1105. }
  1106. for (i = 0; i < num_ctrl; i++) {
  1107. ctrl = &s3c_ctrl[i];
  1108. pr_debug("irq: found controller %s\n", ctrl->name);
  1109. intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
  1110. if (!intc)
  1111. return -ENOMEM;
  1112. intc->domain = domain;
  1113. intc->irqs = kzalloc(sizeof(struct s3c_irq_data) * 32,
  1114. GFP_KERNEL);
  1115. if (!intc->irqs) {
  1116. kfree(intc);
  1117. return -ENOMEM;
  1118. }
  1119. if (ctrl->parent) {
  1120. intc->reg_pending = reg_base + ctrl->offset;
  1121. intc->reg_mask = reg_base + ctrl->offset + 0x4;
  1122. if (*(ctrl->parent)) {
  1123. intc->parent = *(ctrl->parent);
  1124. } else {
  1125. pr_warn("irq: parent of %s missing\n",
  1126. ctrl->name);
  1127. kfree(intc->irqs);
  1128. kfree(intc);
  1129. continue;
  1130. }
  1131. } else {
  1132. intc->reg_pending = reg_base + ctrl->offset;
  1133. intc->reg_mask = reg_base + ctrl->offset + 0x08;
  1134. intc->reg_intpnd = reg_base + ctrl->offset + 0x10;
  1135. }
  1136. s3c24xx_clear_intc(intc);
  1137. s3c_intc[i] = intc;
  1138. }
  1139. set_handle_irq(s3c24xx_handle_irq);
  1140. return 0;
  1141. }
  1142. static struct s3c24xx_irq_of_ctrl s3c2410_ctrl[] = {
  1143. {
  1144. .name = "intc",
  1145. .offset = 0,
  1146. }, {
  1147. .name = "subintc",
  1148. .offset = 0x18,
  1149. .parent = &s3c_intc[0],
  1150. }
  1151. };
  1152. int __init s3c2410_init_intc_of(struct device_node *np,
  1153. struct device_node *interrupt_parent)
  1154. {
  1155. return s3c_init_intc_of(np, interrupt_parent,
  1156. s3c2410_ctrl, ARRAY_SIZE(s3c2410_ctrl));
  1157. }
  1158. IRQCHIP_DECLARE(s3c2410_irq, "samsung,s3c2410-irq", s3c2410_init_intc_of);
  1159. static struct s3c24xx_irq_of_ctrl s3c2416_ctrl[] = {
  1160. {
  1161. .name = "intc",
  1162. .offset = 0,
  1163. }, {
  1164. .name = "subintc",
  1165. .offset = 0x18,
  1166. .parent = &s3c_intc[0],
  1167. }, {
  1168. .name = "intc2",
  1169. .offset = 0x40,
  1170. }
  1171. };
  1172. int __init s3c2416_init_intc_of(struct device_node *np,
  1173. struct device_node *interrupt_parent)
  1174. {
  1175. return s3c_init_intc_of(np, interrupt_parent,
  1176. s3c2416_ctrl, ARRAY_SIZE(s3c2416_ctrl));
  1177. }
  1178. IRQCHIP_DECLARE(s3c2416_irq, "samsung,s3c2416-irq", s3c2416_init_intc_of);
  1179. #endif