irq.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823
  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/chained_irq.h>
  28. #include <asm/mach/irq.h>
  29. #include <mach/regs-irq.h>
  30. #include <mach/regs-gpio.h>
  31. #include <plat/cpu.h>
  32. #include <plat/regs-irqtype.h>
  33. #include <plat/pm.h>
  34. #include <plat/irq.h>
  35. #define S3C_IRQTYPE_NONE 0
  36. #define S3C_IRQTYPE_EINT 1
  37. #define S3C_IRQTYPE_EDGE 2
  38. #define S3C_IRQTYPE_LEVEL 3
  39. struct s3c_irq_data {
  40. unsigned int type;
  41. unsigned long parent_irq;
  42. /* data gets filled during init */
  43. struct s3c_irq_intc *intc;
  44. unsigned long sub_bits;
  45. struct s3c_irq_intc *sub_intc;
  46. };
  47. /*
  48. * Sructure holding the controller data
  49. * @reg_pending register holding pending irqs
  50. * @reg_intpnd special register intpnd in main intc
  51. * @reg_mask mask register
  52. * @domain irq_domain of the controller
  53. * @parent parent controller for ext and sub irqs
  54. * @irqs irq-data, always s3c_irq_data[32]
  55. */
  56. struct s3c_irq_intc {
  57. void __iomem *reg_pending;
  58. void __iomem *reg_intpnd;
  59. void __iomem *reg_mask;
  60. struct irq_domain *domain;
  61. struct s3c_irq_intc *parent;
  62. struct s3c_irq_data *irqs;
  63. };
  64. static void s3c_irq_mask(struct irq_data *data)
  65. {
  66. struct s3c_irq_intc *intc = data->domain->host_data;
  67. struct s3c_irq_intc *parent_intc = intc->parent;
  68. struct s3c_irq_data *irq_data = &intc->irqs[data->hwirq];
  69. struct s3c_irq_data *parent_data;
  70. unsigned long mask;
  71. unsigned int irqno;
  72. mask = __raw_readl(intc->reg_mask);
  73. mask |= (1UL << data->hwirq);
  74. __raw_writel(mask, intc->reg_mask);
  75. if (parent_intc && irq_data->parent_irq) {
  76. parent_data = &parent_intc->irqs[irq_data->parent_irq];
  77. /* check to see if we need to mask the parent IRQ */
  78. if ((mask & parent_data->sub_bits) == parent_data->sub_bits) {
  79. irqno = irq_find_mapping(parent_intc->domain,
  80. irq_data->parent_irq);
  81. s3c_irq_mask(irq_get_irq_data(irqno));
  82. }
  83. }
  84. }
  85. static void s3c_irq_unmask(struct irq_data *data)
  86. {
  87. struct s3c_irq_intc *intc = data->domain->host_data;
  88. struct s3c_irq_intc *parent_intc = intc->parent;
  89. struct s3c_irq_data *irq_data = &intc->irqs[data->hwirq];
  90. unsigned long mask;
  91. unsigned int irqno;
  92. mask = __raw_readl(intc->reg_mask);
  93. mask &= ~(1UL << data->hwirq);
  94. __raw_writel(mask, intc->reg_mask);
  95. if (parent_intc && irq_data->parent_irq) {
  96. irqno = irq_find_mapping(parent_intc->domain,
  97. irq_data->parent_irq);
  98. s3c_irq_unmask(irq_get_irq_data(irqno));
  99. }
  100. }
  101. static inline void s3c_irq_ack(struct irq_data *data)
  102. {
  103. struct s3c_irq_intc *intc = data->domain->host_data;
  104. unsigned long bitval = 1UL << data->hwirq;
  105. __raw_writel(bitval, intc->reg_pending);
  106. if (intc->reg_intpnd)
  107. __raw_writel(bitval, intc->reg_intpnd);
  108. }
  109. static int s3c_irqext_type_set(void __iomem *gpcon_reg,
  110. void __iomem *extint_reg,
  111. unsigned long gpcon_offset,
  112. unsigned long extint_offset,
  113. unsigned int type)
  114. {
  115. unsigned long newvalue = 0, value;
  116. /* Set the GPIO to external interrupt mode */
  117. value = __raw_readl(gpcon_reg);
  118. value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
  119. __raw_writel(value, gpcon_reg);
  120. /* Set the external interrupt to pointed trigger type */
  121. switch (type)
  122. {
  123. case IRQ_TYPE_NONE:
  124. pr_warn("No edge setting!\n");
  125. break;
  126. case IRQ_TYPE_EDGE_RISING:
  127. newvalue = S3C2410_EXTINT_RISEEDGE;
  128. break;
  129. case IRQ_TYPE_EDGE_FALLING:
  130. newvalue = S3C2410_EXTINT_FALLEDGE;
  131. break;
  132. case IRQ_TYPE_EDGE_BOTH:
  133. newvalue = S3C2410_EXTINT_BOTHEDGE;
  134. break;
  135. case IRQ_TYPE_LEVEL_LOW:
  136. newvalue = S3C2410_EXTINT_LOWLEV;
  137. break;
  138. case IRQ_TYPE_LEVEL_HIGH:
  139. newvalue = S3C2410_EXTINT_HILEV;
  140. break;
  141. default:
  142. pr_err("No such irq type %d", type);
  143. return -EINVAL;
  144. }
  145. value = __raw_readl(extint_reg);
  146. value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
  147. __raw_writel(value, extint_reg);
  148. return 0;
  149. }
  150. /* FIXME: make static when it's out of plat-samsung/irq.h */
  151. int s3c_irqext_type(struct irq_data *data, unsigned int type)
  152. {
  153. void __iomem *extint_reg;
  154. void __iomem *gpcon_reg;
  155. unsigned long gpcon_offset, extint_offset;
  156. if ((data->hwirq >= 4) && (data->hwirq <= 7)) {
  157. gpcon_reg = S3C2410_GPFCON;
  158. extint_reg = S3C24XX_EXTINT0;
  159. gpcon_offset = (data->hwirq) * 2;
  160. extint_offset = (data->hwirq) * 4;
  161. } else if ((data->hwirq >= 8) && (data->hwirq <= 15)) {
  162. gpcon_reg = S3C2410_GPGCON;
  163. extint_reg = S3C24XX_EXTINT1;
  164. gpcon_offset = (data->hwirq - 8) * 2;
  165. extint_offset = (data->hwirq - 8) * 4;
  166. } else if ((data->hwirq >= 16) && (data->hwirq <= 23)) {
  167. gpcon_reg = S3C2410_GPGCON;
  168. extint_reg = S3C24XX_EXTINT2;
  169. gpcon_offset = (data->hwirq - 8) * 2;
  170. extint_offset = (data->hwirq - 16) * 4;
  171. } else {
  172. return -EINVAL;
  173. }
  174. return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
  175. extint_offset, type);
  176. }
  177. static int s3c_irqext0_type(struct irq_data *data, unsigned int type)
  178. {
  179. void __iomem *extint_reg;
  180. void __iomem *gpcon_reg;
  181. unsigned long gpcon_offset, extint_offset;
  182. if ((data->hwirq >= 0) && (data->hwirq <= 3)) {
  183. gpcon_reg = S3C2410_GPFCON;
  184. extint_reg = S3C24XX_EXTINT0;
  185. gpcon_offset = (data->hwirq) * 2;
  186. extint_offset = (data->hwirq) * 4;
  187. } else {
  188. return -EINVAL;
  189. }
  190. return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
  191. extint_offset, type);
  192. }
  193. struct irq_chip s3c_irq_chip = {
  194. .name = "s3c",
  195. .irq_ack = s3c_irq_ack,
  196. .irq_mask = s3c_irq_mask,
  197. .irq_unmask = s3c_irq_unmask,
  198. .irq_set_wake = s3c_irq_wake
  199. };
  200. struct irq_chip s3c_irq_level_chip = {
  201. .name = "s3c-level",
  202. .irq_mask = s3c_irq_mask,
  203. .irq_unmask = s3c_irq_unmask,
  204. .irq_ack = s3c_irq_ack,
  205. };
  206. static struct irq_chip s3c_irqext_chip = {
  207. .name = "s3c-ext",
  208. .irq_mask = s3c_irq_mask,
  209. .irq_unmask = s3c_irq_unmask,
  210. .irq_ack = s3c_irq_ack,
  211. .irq_set_type = s3c_irqext_type,
  212. .irq_set_wake = s3c_irqext_wake
  213. };
  214. static struct irq_chip s3c_irq_eint0t4 = {
  215. .name = "s3c-ext0",
  216. .irq_ack = s3c_irq_ack,
  217. .irq_mask = s3c_irq_mask,
  218. .irq_unmask = s3c_irq_unmask,
  219. .irq_set_wake = s3c_irq_wake,
  220. .irq_set_type = s3c_irqext0_type,
  221. };
  222. static void s3c_irq_demux(unsigned int irq, struct irq_desc *desc)
  223. {
  224. struct irq_chip *chip = irq_desc_get_chip(desc);
  225. struct s3c_irq_intc *intc = desc->irq_data.domain->host_data;
  226. struct s3c_irq_data *irq_data = &intc->irqs[desc->irq_data.hwirq];
  227. struct s3c_irq_intc *sub_intc = irq_data->sub_intc;
  228. unsigned long src;
  229. unsigned long msk;
  230. unsigned int n;
  231. chained_irq_enter(chip, desc);
  232. src = __raw_readl(sub_intc->reg_pending);
  233. msk = __raw_readl(sub_intc->reg_mask);
  234. src &= ~msk;
  235. src &= irq_data->sub_bits;
  236. while (src) {
  237. n = __ffs(src);
  238. src &= ~(1 << n);
  239. generic_handle_irq(irq_find_mapping(sub_intc->domain, n));
  240. }
  241. chained_irq_exit(chip, desc);
  242. }
  243. #ifdef CONFIG_FIQ
  244. /**
  245. * s3c24xx_set_fiq - set the FIQ routing
  246. * @irq: IRQ number to route to FIQ on processor.
  247. * @on: Whether to route @irq to the FIQ, or to remove the FIQ routing.
  248. *
  249. * Change the state of the IRQ to FIQ routing depending on @irq and @on. If
  250. * @on is true, the @irq is checked to see if it can be routed and the
  251. * interrupt controller updated to route the IRQ. If @on is false, the FIQ
  252. * routing is cleared, regardless of which @irq is specified.
  253. */
  254. int s3c24xx_set_fiq(unsigned int irq, bool on)
  255. {
  256. u32 intmod;
  257. unsigned offs;
  258. if (on) {
  259. offs = irq - FIQ_START;
  260. if (offs > 31)
  261. return -EINVAL;
  262. intmod = 1 << offs;
  263. } else {
  264. intmod = 0;
  265. }
  266. __raw_writel(intmod, S3C2410_INTMOD);
  267. return 0;
  268. }
  269. EXPORT_SYMBOL_GPL(s3c24xx_set_fiq);
  270. #endif
  271. static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
  272. irq_hw_number_t hw)
  273. {
  274. struct s3c_irq_intc *intc = h->host_data;
  275. struct s3c_irq_data *irq_data = &intc->irqs[hw];
  276. struct s3c_irq_intc *parent_intc;
  277. struct s3c_irq_data *parent_irq_data;
  278. unsigned int irqno;
  279. if (!intc) {
  280. pr_err("irq-s3c24xx: no controller found for hwirq %lu\n", hw);
  281. return -EINVAL;
  282. }
  283. if (!irq_data) {
  284. pr_err("irq-s3c24xx: no irq data found for hwirq %lu\n", hw);
  285. return -EINVAL;
  286. }
  287. /* attach controller pointer to irq_data */
  288. irq_data->intc = intc;
  289. /* set handler and flags */
  290. switch (irq_data->type) {
  291. case S3C_IRQTYPE_NONE:
  292. return 0;
  293. case S3C_IRQTYPE_EINT:
  294. if (irq_data->parent_irq)
  295. irq_set_chip_and_handler(virq, &s3c_irqext_chip,
  296. handle_edge_irq);
  297. else
  298. irq_set_chip_and_handler(virq, &s3c_irq_eint0t4,
  299. handle_edge_irq);
  300. break;
  301. case S3C_IRQTYPE_EDGE:
  302. if (irq_data->parent_irq ||
  303. intc->reg_pending == S3C2416_SRCPND2)
  304. irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
  305. handle_edge_irq);
  306. else
  307. irq_set_chip_and_handler(virq, &s3c_irq_chip,
  308. handle_edge_irq);
  309. break;
  310. case S3C_IRQTYPE_LEVEL:
  311. if (irq_data->parent_irq)
  312. irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
  313. handle_level_irq);
  314. else
  315. irq_set_chip_and_handler(virq, &s3c_irq_chip,
  316. handle_level_irq);
  317. break;
  318. default:
  319. pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type);
  320. return -EINVAL;
  321. }
  322. set_irq_flags(virq, IRQF_VALID);
  323. if (irq_data->parent_irq) {
  324. parent_intc = intc->parent;
  325. if (!parent_intc) {
  326. pr_err("irq-s3c24xx: no parent controller found for hwirq %lu\n",
  327. hw);
  328. goto err;
  329. }
  330. parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
  331. if (!irq_data) {
  332. pr_err("irq-s3c24xx: no irq data found for hwirq %lu\n",
  333. hw);
  334. goto err;
  335. }
  336. parent_irq_data->sub_intc = intc;
  337. parent_irq_data->sub_bits |= (1UL << hw);
  338. /* attach the demuxer to the parent irq */
  339. irqno = irq_find_mapping(parent_intc->domain,
  340. irq_data->parent_irq);
  341. if (!irqno) {
  342. pr_err("irq-s3c24xx: could not find mapping for parent irq %lu\n",
  343. irq_data->parent_irq);
  344. goto err;
  345. }
  346. irq_set_chained_handler(irqno, s3c_irq_demux);
  347. }
  348. return 0;
  349. err:
  350. set_irq_flags(virq, 0);
  351. /* the only error can result from bad mapping data*/
  352. return -EINVAL;
  353. }
  354. static struct irq_domain_ops s3c24xx_irq_ops = {
  355. .map = s3c24xx_irq_map,
  356. .xlate = irq_domain_xlate_twocell,
  357. };
  358. static void s3c24xx_clear_intc(struct s3c_irq_intc *intc)
  359. {
  360. void __iomem *reg_source;
  361. unsigned long pend;
  362. unsigned long last;
  363. int i;
  364. /* if intpnd is set, read the next pending irq from there */
  365. reg_source = intc->reg_intpnd ? intc->reg_intpnd : intc->reg_pending;
  366. last = 0;
  367. for (i = 0; i < 4; i++) {
  368. pend = __raw_readl(reg_source);
  369. if (pend == 0 || pend == last)
  370. break;
  371. __raw_writel(pend, intc->reg_pending);
  372. if (intc->reg_intpnd)
  373. __raw_writel(pend, intc->reg_intpnd);
  374. pr_info("irq: clearing pending status %08x\n", (int)pend);
  375. last = pend;
  376. }
  377. }
  378. struct s3c_irq_intc *s3c24xx_init_intc(struct device_node *np,
  379. struct s3c_irq_data *irq_data,
  380. struct s3c_irq_intc *parent,
  381. unsigned long address)
  382. {
  383. struct s3c_irq_intc *intc;
  384. void __iomem *base = (void *)0xf6000000; /* static mapping */
  385. int irq_num;
  386. int irq_start;
  387. int irq_offset;
  388. int ret;
  389. intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
  390. if (!intc)
  391. return ERR_PTR(-ENOMEM);
  392. intc->irqs = irq_data;
  393. if (parent)
  394. intc->parent = parent;
  395. /* select the correct data for the controller.
  396. * Need to hard code the irq num start and offset
  397. * to preserve the static mapping for now
  398. */
  399. switch (address) {
  400. case 0x4a000000:
  401. pr_debug("irq: found main intc\n");
  402. intc->reg_pending = base;
  403. intc->reg_mask = base + 0x08;
  404. intc->reg_intpnd = base + 0x10;
  405. irq_num = 32;
  406. irq_start = S3C2410_IRQ(0);
  407. irq_offset = 0;
  408. break;
  409. case 0x4a000018:
  410. pr_debug("irq: found subintc\n");
  411. intc->reg_pending = base + 0x18;
  412. intc->reg_mask = base + 0x1c;
  413. irq_num = 29;
  414. irq_start = S3C2410_IRQSUB(0);
  415. irq_offset = 0;
  416. break;
  417. case 0x4a000040:
  418. pr_debug("irq: found intc2\n");
  419. intc->reg_pending = base + 0x40;
  420. intc->reg_mask = base + 0x48;
  421. intc->reg_intpnd = base + 0x50;
  422. irq_num = 8;
  423. irq_start = S3C2416_IRQ(0);
  424. irq_offset = 0;
  425. break;
  426. case 0x560000a4:
  427. pr_debug("irq: found eintc\n");
  428. base = (void *)0xfd000000;
  429. intc->reg_mask = base + 0xa4;
  430. intc->reg_pending = base + 0x08;
  431. irq_num = 20;
  432. irq_start = S3C2410_IRQ(32);
  433. irq_offset = 4;
  434. break;
  435. default:
  436. pr_err("irq: unsupported controller address\n");
  437. ret = -EINVAL;
  438. goto err;
  439. }
  440. /* now that all the data is complete, init the irq-domain */
  441. s3c24xx_clear_intc(intc);
  442. intc->domain = irq_domain_add_legacy(np, irq_num, irq_start,
  443. irq_offset, &s3c24xx_irq_ops,
  444. intc);
  445. if (!intc->domain) {
  446. pr_err("irq: could not create irq-domain\n");
  447. ret = -EINVAL;
  448. goto err;
  449. }
  450. return intc;
  451. err:
  452. kfree(intc);
  453. return ERR_PTR(ret);
  454. }
  455. /* s3c24xx_init_irq
  456. *
  457. * Initialise S3C2410 IRQ system
  458. */
  459. static struct s3c_irq_data init_base[32] = {
  460. { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  461. { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  462. { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  463. { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  464. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  465. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  466. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  467. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  468. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  469. { .type = S3C_IRQTYPE_EDGE, }, /* WDT */
  470. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  471. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  472. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  473. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  474. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  475. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  476. { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
  477. { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
  478. { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
  479. { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
  480. { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
  481. { .type = S3C_IRQTYPE_EDGE, }, /* SDI */
  482. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  483. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  484. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  485. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  486. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  487. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  488. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  489. { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  490. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  491. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  492. };
  493. static struct s3c_irq_data init_eint[32] = {
  494. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  495. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  496. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  497. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  498. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */
  499. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */
  500. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */
  501. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */
  502. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */
  503. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */
  504. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */
  505. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */
  506. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */
  507. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */
  508. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */
  509. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */
  510. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */
  511. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */
  512. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */
  513. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */
  514. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */
  515. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */
  516. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */
  517. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */
  518. };
  519. static struct s3c_irq_data init_subint[32] = {
  520. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  521. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  522. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  523. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  524. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  525. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  526. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  527. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  528. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  529. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  530. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  531. };
  532. void __init s3c24xx_init_irq(void)
  533. {
  534. struct s3c_irq_intc *main_intc;
  535. #ifdef CONFIG_FIQ
  536. init_FIQ(FIQ_START);
  537. #endif
  538. main_intc = s3c24xx_init_intc(NULL, &init_base[0], NULL, 0x4a000000);
  539. if (IS_ERR(main_intc)) {
  540. pr_err("irq: could not create main interrupt controller\n");
  541. return;
  542. }
  543. s3c24xx_init_intc(NULL, &init_subint[0], main_intc, 0x4a000018);
  544. s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
  545. }
  546. #ifdef CONFIG_CPU_S3C2416
  547. static struct s3c_irq_data init_s3c2416base[32] = {
  548. { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  549. { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  550. { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  551. { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  552. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  553. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  554. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  555. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  556. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  557. { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
  558. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  559. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  560. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  561. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  562. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  563. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  564. { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */
  565. { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
  566. { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */
  567. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  568. { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
  569. { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
  570. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  571. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  572. { .type = S3C_IRQTYPE_EDGE, }, /* NAND */
  573. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  574. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  575. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  576. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  577. { .type = S3C_IRQTYPE_NONE, },
  578. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  579. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  580. };
  581. static struct s3c_irq_data init_s3c2416subint[32] = {
  582. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  583. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  584. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  585. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  586. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  587. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  588. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  589. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  590. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  591. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  592. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  593. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  594. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  595. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  596. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  597. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
  598. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
  599. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
  600. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
  601. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
  602. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
  603. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
  604. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
  605. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
  606. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
  607. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
  608. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
  609. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
  610. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
  611. };
  612. static struct s3c_irq_data init_s3c2416_second[32] = {
  613. { .type = S3C_IRQTYPE_EDGE }, /* 2D */
  614. { .type = S3C_IRQTYPE_EDGE }, /* IIC1 */
  615. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  616. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  617. { .type = S3C_IRQTYPE_EDGE }, /* PCM0 */
  618. { .type = S3C_IRQTYPE_EDGE }, /* PCM1 */
  619. { .type = S3C_IRQTYPE_EDGE }, /* I2S0 */
  620. { .type = S3C_IRQTYPE_EDGE }, /* I2S1 */
  621. };
  622. void __init s3c2416_init_irq(void)
  623. {
  624. struct s3c_irq_intc *main_intc;
  625. pr_info("S3C2416: IRQ Support\n");
  626. #ifdef CONFIG_FIQ
  627. init_FIQ(FIQ_START);
  628. #endif
  629. main_intc = s3c24xx_init_intc(NULL, &init_s3c2416base[0], NULL, 0x4a000000);
  630. if (IS_ERR(main_intc)) {
  631. pr_err("irq: could not create main interrupt controller\n");
  632. return;
  633. }
  634. s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
  635. s3c24xx_init_intc(NULL, &init_s3c2416subint[0], main_intc, 0x4a000018);
  636. s3c24xx_init_intc(NULL, &init_s3c2416_second[0], NULL, 0x4a000040);
  637. }
  638. #endif
  639. #ifdef CONFIG_CPU_S3C2443
  640. static struct s3c_irq_data init_s3c2443base[32] = {
  641. { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  642. { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  643. { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  644. { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  645. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  646. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  647. { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
  648. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  649. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  650. { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
  651. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  652. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  653. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  654. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  655. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  656. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  657. { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */
  658. { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
  659. { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */
  660. { .type = S3C_IRQTYPE_EDGE, }, /* CFON */
  661. { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
  662. { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
  663. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  664. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  665. { .type = S3C_IRQTYPE_EDGE, }, /* NAND */
  666. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  667. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  668. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  669. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  670. { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  671. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  672. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  673. };
  674. static struct s3c_irq_data init_s3c2443subint[32] = {
  675. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  676. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  677. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  678. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  679. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  680. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  681. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  682. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  683. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  684. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  685. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  686. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */
  687. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */
  688. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  689. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD1 */
  690. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
  691. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
  692. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
  693. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
  694. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
  695. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
  696. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
  697. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
  698. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
  699. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
  700. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
  701. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
  702. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
  703. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
  704. };
  705. void __init s3c2443_init_irq(void)
  706. {
  707. struct s3c_irq_intc *main_intc;
  708. pr_info("S3C2443: IRQ Support\n");
  709. #ifdef CONFIG_FIQ
  710. init_FIQ(FIQ_START);
  711. #endif
  712. main_intc = s3c24xx_init_intc(NULL, &init_s3c2443base[0], NULL, 0x4a000000);
  713. if (IS_ERR(main_intc)) {
  714. pr_err("irq: could not create main interrupt controller\n");
  715. return;
  716. }
  717. s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
  718. s3c24xx_init_intc(NULL, &init_s3c2443subint[0], main_intc, 0x4a000018);
  719. }
  720. #endif