irq.c 23 KB

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