irq.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107
  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/exception.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. #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) {
  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) {
  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. static int s3c_irqext_type(struct irq_data *data, unsigned int type)
  150. {
  151. void __iomem *extint_reg;
  152. void __iomem *gpcon_reg;
  153. unsigned long gpcon_offset, extint_offset;
  154. if ((data->hwirq >= 4) && (data->hwirq <= 7)) {
  155. gpcon_reg = S3C2410_GPFCON;
  156. extint_reg = S3C24XX_EXTINT0;
  157. gpcon_offset = (data->hwirq) * 2;
  158. extint_offset = (data->hwirq) * 4;
  159. } else if ((data->hwirq >= 8) && (data->hwirq <= 15)) {
  160. gpcon_reg = S3C2410_GPGCON;
  161. extint_reg = S3C24XX_EXTINT1;
  162. gpcon_offset = (data->hwirq - 8) * 2;
  163. extint_offset = (data->hwirq - 8) * 4;
  164. } else if ((data->hwirq >= 16) && (data->hwirq <= 23)) {
  165. gpcon_reg = S3C2410_GPGCON;
  166. extint_reg = S3C24XX_EXTINT2;
  167. gpcon_offset = (data->hwirq - 8) * 2;
  168. extint_offset = (data->hwirq - 16) * 4;
  169. } else {
  170. return -EINVAL;
  171. }
  172. return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
  173. extint_offset, type);
  174. }
  175. static int s3c_irqext0_type(struct irq_data *data, unsigned int type)
  176. {
  177. void __iomem *extint_reg;
  178. void __iomem *gpcon_reg;
  179. unsigned long gpcon_offset, extint_offset;
  180. if ((data->hwirq >= 0) && (data->hwirq <= 3)) {
  181. gpcon_reg = S3C2410_GPFCON;
  182. extint_reg = S3C24XX_EXTINT0;
  183. gpcon_offset = (data->hwirq) * 2;
  184. extint_offset = (data->hwirq) * 4;
  185. } else {
  186. return -EINVAL;
  187. }
  188. return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
  189. extint_offset, type);
  190. }
  191. static struct irq_chip s3c_irq_chip = {
  192. .name = "s3c",
  193. .irq_ack = s3c_irq_ack,
  194. .irq_mask = s3c_irq_mask,
  195. .irq_unmask = s3c_irq_unmask,
  196. .irq_set_wake = s3c_irq_wake
  197. };
  198. static struct irq_chip s3c_irq_level_chip = {
  199. .name = "s3c-level",
  200. .irq_mask = s3c_irq_mask,
  201. .irq_unmask = s3c_irq_unmask,
  202. .irq_ack = s3c_irq_ack,
  203. };
  204. static struct irq_chip s3c_irqext_chip = {
  205. .name = "s3c-ext",
  206. .irq_mask = s3c_irq_mask,
  207. .irq_unmask = s3c_irq_unmask,
  208. .irq_ack = s3c_irq_ack,
  209. .irq_set_type = s3c_irqext_type,
  210. .irq_set_wake = s3c_irqext_wake
  211. };
  212. static struct irq_chip s3c_irq_eint0t4 = {
  213. .name = "s3c-ext0",
  214. .irq_ack = s3c_irq_ack,
  215. .irq_mask = s3c_irq_mask,
  216. .irq_unmask = s3c_irq_unmask,
  217. .irq_set_wake = s3c_irq_wake,
  218. .irq_set_type = s3c_irqext0_type,
  219. };
  220. static void s3c_irq_demux(unsigned int irq, struct irq_desc *desc)
  221. {
  222. struct irq_chip *chip = irq_desc_get_chip(desc);
  223. struct s3c_irq_intc *intc = desc->irq_data.domain->host_data;
  224. struct s3c_irq_data *irq_data = &intc->irqs[desc->irq_data.hwirq];
  225. struct s3c_irq_intc *sub_intc = irq_data->sub_intc;
  226. unsigned long src;
  227. unsigned long msk;
  228. unsigned int n;
  229. chained_irq_enter(chip, desc);
  230. src = __raw_readl(sub_intc->reg_pending);
  231. msk = __raw_readl(sub_intc->reg_mask);
  232. src &= ~msk;
  233. src &= irq_data->sub_bits;
  234. while (src) {
  235. n = __ffs(src);
  236. src &= ~(1 << n);
  237. generic_handle_irq(irq_find_mapping(sub_intc->domain, n));
  238. }
  239. chained_irq_exit(chip, desc);
  240. }
  241. static struct s3c_irq_intc *main_intc;
  242. static struct s3c_irq_intc *main_intc2;
  243. static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc,
  244. struct pt_regs *regs)
  245. {
  246. int pnd;
  247. int offset;
  248. int irq;
  249. pnd = __raw_readl(intc->reg_intpnd);
  250. if (!pnd)
  251. return false;
  252. /* We have a problem that the INTOFFSET register does not always
  253. * show one interrupt. Occasionally we get two interrupts through
  254. * the prioritiser, and this causes the INTOFFSET register to show
  255. * what looks like the logical-or of the two interrupt numbers.
  256. *
  257. * Thanks to Klaus, Shannon, et al for helping to debug this problem
  258. */
  259. offset = __raw_readl(intc->reg_intpnd + 4);
  260. /* Find the bit manually, when the offset is wrong.
  261. * The pending register only ever contains the one bit of the next
  262. * interrupt to handle.
  263. */
  264. if (!(pnd & (1 << offset)))
  265. offset = __ffs(pnd);
  266. irq = irq_find_mapping(intc->domain, offset);
  267. handle_IRQ(irq, regs);
  268. return true;
  269. }
  270. asmlinkage void __exception_irq_entry s3c24xx_handle_irq(struct pt_regs *regs)
  271. {
  272. do {
  273. if (likely(main_intc))
  274. if (s3c24xx_handle_intc(main_intc, regs))
  275. continue;
  276. if (main_intc2)
  277. if (s3c24xx_handle_intc(main_intc2, regs))
  278. continue;
  279. break;
  280. } while (1);
  281. }
  282. #ifdef CONFIG_FIQ
  283. /**
  284. * s3c24xx_set_fiq - set the FIQ routing
  285. * @irq: IRQ number to route to FIQ on processor.
  286. * @on: Whether to route @irq to the FIQ, or to remove the FIQ routing.
  287. *
  288. * Change the state of the IRQ to FIQ routing depending on @irq and @on. If
  289. * @on is true, the @irq is checked to see if it can be routed and the
  290. * interrupt controller updated to route the IRQ. If @on is false, the FIQ
  291. * routing is cleared, regardless of which @irq is specified.
  292. */
  293. int s3c24xx_set_fiq(unsigned int irq, bool on)
  294. {
  295. u32 intmod;
  296. unsigned offs;
  297. if (on) {
  298. offs = irq - FIQ_START;
  299. if (offs > 31)
  300. return -EINVAL;
  301. intmod = 1 << offs;
  302. } else {
  303. intmod = 0;
  304. }
  305. __raw_writel(intmod, S3C2410_INTMOD);
  306. return 0;
  307. }
  308. EXPORT_SYMBOL_GPL(s3c24xx_set_fiq);
  309. #endif
  310. static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
  311. irq_hw_number_t hw)
  312. {
  313. struct s3c_irq_intc *intc = h->host_data;
  314. struct s3c_irq_data *irq_data = &intc->irqs[hw];
  315. struct s3c_irq_intc *parent_intc;
  316. struct s3c_irq_data *parent_irq_data;
  317. unsigned int irqno;
  318. /* attach controller pointer to irq_data */
  319. irq_data->intc = intc;
  320. parent_intc = intc->parent;
  321. /* set handler and flags */
  322. switch (irq_data->type) {
  323. case S3C_IRQTYPE_NONE:
  324. return 0;
  325. case S3C_IRQTYPE_EINT:
  326. /* On the S3C2412, the EINT0to3 have a parent irq
  327. * but need the s3c_irq_eint0t4 chip
  328. */
  329. if (parent_intc && (!soc_is_s3c2412() || hw >= 4))
  330. irq_set_chip_and_handler(virq, &s3c_irqext_chip,
  331. handle_edge_irq);
  332. else
  333. irq_set_chip_and_handler(virq, &s3c_irq_eint0t4,
  334. handle_edge_irq);
  335. break;
  336. case S3C_IRQTYPE_EDGE:
  337. if (parent_intc || intc->reg_pending == S3C2416_SRCPND2)
  338. irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
  339. handle_edge_irq);
  340. else
  341. irq_set_chip_and_handler(virq, &s3c_irq_chip,
  342. handle_edge_irq);
  343. break;
  344. case S3C_IRQTYPE_LEVEL:
  345. if (parent_intc)
  346. irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
  347. handle_level_irq);
  348. else
  349. irq_set_chip_and_handler(virq, &s3c_irq_chip,
  350. handle_level_irq);
  351. break;
  352. default:
  353. pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type);
  354. return -EINVAL;
  355. }
  356. set_irq_flags(virq, IRQF_VALID);
  357. if (parent_intc && irq_data->type != S3C_IRQTYPE_NONE) {
  358. if (irq_data->parent_irq > 31) {
  359. pr_err("irq-s3c24xx: parent irq %lu is out of range\n",
  360. irq_data->parent_irq);
  361. goto err;
  362. }
  363. parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
  364. parent_irq_data->sub_intc = intc;
  365. parent_irq_data->sub_bits |= (1UL << hw);
  366. /* attach the demuxer to the parent irq */
  367. irqno = irq_find_mapping(parent_intc->domain,
  368. irq_data->parent_irq);
  369. if (!irqno) {
  370. pr_err("irq-s3c24xx: could not find mapping for parent irq %lu\n",
  371. irq_data->parent_irq);
  372. goto err;
  373. }
  374. irq_set_chained_handler(irqno, s3c_irq_demux);
  375. }
  376. return 0;
  377. err:
  378. set_irq_flags(virq, 0);
  379. /* the only error can result from bad mapping data*/
  380. return -EINVAL;
  381. }
  382. static struct irq_domain_ops s3c24xx_irq_ops = {
  383. .map = s3c24xx_irq_map,
  384. .xlate = irq_domain_xlate_twocell,
  385. };
  386. static void s3c24xx_clear_intc(struct s3c_irq_intc *intc)
  387. {
  388. void __iomem *reg_source;
  389. unsigned long pend;
  390. unsigned long last;
  391. int i;
  392. /* if intpnd is set, read the next pending irq from there */
  393. reg_source = intc->reg_intpnd ? intc->reg_intpnd : intc->reg_pending;
  394. last = 0;
  395. for (i = 0; i < 4; i++) {
  396. pend = __raw_readl(reg_source);
  397. if (pend == 0 || pend == last)
  398. break;
  399. __raw_writel(pend, intc->reg_pending);
  400. if (intc->reg_intpnd)
  401. __raw_writel(pend, intc->reg_intpnd);
  402. pr_info("irq: clearing pending status %08x\n", (int)pend);
  403. last = pend;
  404. }
  405. }
  406. static struct s3c_irq_intc *s3c24xx_init_intc(struct device_node *np,
  407. struct s3c_irq_data *irq_data,
  408. struct s3c_irq_intc *parent,
  409. unsigned long address)
  410. {
  411. struct s3c_irq_intc *intc;
  412. void __iomem *base = (void *)0xf6000000; /* static mapping */
  413. int irq_num;
  414. int irq_start;
  415. int ret;
  416. intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
  417. if (!intc)
  418. return ERR_PTR(-ENOMEM);
  419. intc->irqs = irq_data;
  420. if (parent)
  421. intc->parent = parent;
  422. /* select the correct data for the controller.
  423. * Need to hard code the irq num start and offset
  424. * to preserve the static mapping for now
  425. */
  426. switch (address) {
  427. case 0x4a000000:
  428. pr_debug("irq: found main intc\n");
  429. intc->reg_pending = base;
  430. intc->reg_mask = base + 0x08;
  431. intc->reg_intpnd = base + 0x10;
  432. irq_num = 32;
  433. irq_start = S3C2410_IRQ(0);
  434. break;
  435. case 0x4a000018:
  436. pr_debug("irq: found subintc\n");
  437. intc->reg_pending = base + 0x18;
  438. intc->reg_mask = base + 0x1c;
  439. irq_num = 29;
  440. irq_start = S3C2410_IRQSUB(0);
  441. break;
  442. case 0x4a000040:
  443. pr_debug("irq: found intc2\n");
  444. intc->reg_pending = base + 0x40;
  445. intc->reg_mask = base + 0x48;
  446. intc->reg_intpnd = base + 0x50;
  447. irq_num = 8;
  448. irq_start = S3C2416_IRQ(0);
  449. break;
  450. case 0x560000a4:
  451. pr_debug("irq: found eintc\n");
  452. base = (void *)0xfd000000;
  453. intc->reg_mask = base + 0xa4;
  454. intc->reg_pending = base + 0x08;
  455. irq_num = 24;
  456. irq_start = S3C2410_IRQ(32);
  457. break;
  458. default:
  459. pr_err("irq: unsupported controller address\n");
  460. ret = -EINVAL;
  461. goto err;
  462. }
  463. /* now that all the data is complete, init the irq-domain */
  464. s3c24xx_clear_intc(intc);
  465. intc->domain = irq_domain_add_legacy(np, irq_num, irq_start,
  466. 0, &s3c24xx_irq_ops,
  467. intc);
  468. if (!intc->domain) {
  469. pr_err("irq: could not create irq-domain\n");
  470. ret = -EINVAL;
  471. goto err;
  472. }
  473. if (address == 0x4a000000)
  474. main_intc = intc;
  475. else if (address == 0x4a000040)
  476. main_intc2 = intc;
  477. set_handle_irq(s3c24xx_handle_irq);
  478. return intc;
  479. err:
  480. kfree(intc);
  481. return ERR_PTR(ret);
  482. }
  483. static struct s3c_irq_data init_eint[32] = {
  484. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  485. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  486. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  487. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  488. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */
  489. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */
  490. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */
  491. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */
  492. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */
  493. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */
  494. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */
  495. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */
  496. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */
  497. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */
  498. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */
  499. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */
  500. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */
  501. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */
  502. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */
  503. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */
  504. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */
  505. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */
  506. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */
  507. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */
  508. };
  509. #ifdef CONFIG_CPU_S3C2410
  510. static struct s3c_irq_data init_s3c2410base[32] = {
  511. { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  512. { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  513. { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  514. { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  515. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  516. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  517. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  518. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  519. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  520. { .type = S3C_IRQTYPE_EDGE, }, /* WDT */
  521. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  522. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  523. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  524. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  525. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  526. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  527. { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
  528. { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
  529. { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
  530. { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
  531. { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
  532. { .type = S3C_IRQTYPE_EDGE, }, /* SDI */
  533. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  534. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  535. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  536. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  537. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  538. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  539. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  540. { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  541. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  542. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  543. };
  544. static struct s3c_irq_data init_s3c2410subint[32] = {
  545. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  546. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  547. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  548. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  549. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  550. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  551. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  552. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  553. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  554. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  555. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  556. };
  557. void __init s3c2410_init_irq(void)
  558. {
  559. struct s3c_irq_intc *main_intc;
  560. #ifdef CONFIG_FIQ
  561. init_FIQ(FIQ_START);
  562. #endif
  563. main_intc = s3c24xx_init_intc(NULL, &init_s3c2410base[0], NULL, 0x4a000000);
  564. if (IS_ERR(main_intc)) {
  565. pr_err("irq: could not create main interrupt controller\n");
  566. return;
  567. }
  568. s3c24xx_init_intc(NULL, &init_s3c2410subint[0], main_intc, 0x4a000018);
  569. s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
  570. }
  571. #endif
  572. #ifdef CONFIG_CPU_S3C2412
  573. static struct s3c_irq_data init_s3c2412base[32] = {
  574. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT0 */
  575. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT1 */
  576. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT2 */
  577. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT3 */
  578. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  579. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  580. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  581. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  582. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  583. { .type = S3C_IRQTYPE_EDGE, }, /* WDT */
  584. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  585. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  586. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  587. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  588. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  589. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  590. { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
  591. { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
  592. { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
  593. { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
  594. { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
  595. { .type = S3C_IRQTYPE_LEVEL, }, /* SDI/CF */
  596. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  597. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  598. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  599. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  600. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  601. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  602. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  603. { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  604. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  605. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  606. };
  607. static struct s3c_irq_data init_s3c2412eint[32] = {
  608. { .type = S3C_IRQTYPE_EINT, .parent_irq = 0 }, /* EINT0 */
  609. { .type = S3C_IRQTYPE_EINT, .parent_irq = 1 }, /* EINT1 */
  610. { .type = S3C_IRQTYPE_EINT, .parent_irq = 2 }, /* EINT2 */
  611. { .type = S3C_IRQTYPE_EINT, .parent_irq = 3 }, /* EINT3 */
  612. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */
  613. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */
  614. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */
  615. { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */
  616. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */
  617. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */
  618. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */
  619. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */
  620. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */
  621. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */
  622. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */
  623. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */
  624. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */
  625. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */
  626. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */
  627. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */
  628. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */
  629. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */
  630. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */
  631. { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */
  632. };
  633. static struct s3c_irq_data init_s3c2412subint[32] = {
  634. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  635. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  636. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  637. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  638. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  639. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  640. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  641. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  642. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  643. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  644. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  645. { .type = S3C_IRQTYPE_NONE, },
  646. { .type = S3C_IRQTYPE_NONE, },
  647. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* SDI */
  648. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* CF */
  649. };
  650. void s3c2412_init_irq(void)
  651. {
  652. struct s3c_irq_intc *main_intc;
  653. pr_info("S3C2412: IRQ Support\n");
  654. #ifdef CONFIG_FIQ
  655. init_FIQ(FIQ_START);
  656. #endif
  657. main_intc = s3c24xx_init_intc(NULL, &init_s3c2412base[0], NULL, 0x4a000000);
  658. if (IS_ERR(main_intc)) {
  659. pr_err("irq: could not create main interrupt controller\n");
  660. return;
  661. }
  662. s3c24xx_init_intc(NULL, &init_s3c2412eint[0], main_intc, 0x560000a4);
  663. s3c24xx_init_intc(NULL, &init_s3c2412subint[0], main_intc, 0x4a000018);
  664. }
  665. #endif
  666. #ifdef CONFIG_CPU_S3C2416
  667. static struct s3c_irq_data init_s3c2416base[32] = {
  668. { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  669. { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  670. { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  671. { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  672. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  673. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  674. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  675. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  676. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  677. { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
  678. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  679. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  680. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  681. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  682. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  683. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  684. { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */
  685. { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
  686. { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */
  687. { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  688. { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
  689. { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
  690. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  691. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  692. { .type = S3C_IRQTYPE_EDGE, }, /* NAND */
  693. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  694. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  695. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  696. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  697. { .type = S3C_IRQTYPE_NONE, },
  698. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  699. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  700. };
  701. static struct s3c_irq_data init_s3c2416subint[32] = {
  702. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  703. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  704. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  705. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  706. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  707. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  708. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  709. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  710. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  711. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  712. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  713. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  714. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  715. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  716. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  717. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
  718. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
  719. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
  720. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
  721. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
  722. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
  723. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
  724. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
  725. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
  726. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
  727. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
  728. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
  729. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
  730. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
  731. };
  732. static struct s3c_irq_data init_s3c2416_second[32] = {
  733. { .type = S3C_IRQTYPE_EDGE }, /* 2D */
  734. { .type = S3C_IRQTYPE_EDGE }, /* IIC1 */
  735. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  736. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  737. { .type = S3C_IRQTYPE_EDGE }, /* PCM0 */
  738. { .type = S3C_IRQTYPE_EDGE }, /* PCM1 */
  739. { .type = S3C_IRQTYPE_EDGE }, /* I2S0 */
  740. { .type = S3C_IRQTYPE_EDGE }, /* I2S1 */
  741. };
  742. void __init s3c2416_init_irq(void)
  743. {
  744. struct s3c_irq_intc *main_intc;
  745. pr_info("S3C2416: IRQ Support\n");
  746. #ifdef CONFIG_FIQ
  747. init_FIQ(FIQ_START);
  748. #endif
  749. main_intc = s3c24xx_init_intc(NULL, &init_s3c2416base[0], NULL, 0x4a000000);
  750. if (IS_ERR(main_intc)) {
  751. pr_err("irq: could not create main interrupt controller\n");
  752. return;
  753. }
  754. s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
  755. s3c24xx_init_intc(NULL, &init_s3c2416subint[0], main_intc, 0x4a000018);
  756. s3c24xx_init_intc(NULL, &init_s3c2416_second[0], NULL, 0x4a000040);
  757. }
  758. #endif
  759. #ifdef CONFIG_CPU_S3C2440
  760. static struct s3c_irq_data init_s3c2440base[32] = {
  761. { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  762. { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  763. { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  764. { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  765. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  766. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  767. { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
  768. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  769. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  770. { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
  771. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  772. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  773. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  774. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  775. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  776. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  777. { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
  778. { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
  779. { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
  780. { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
  781. { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
  782. { .type = S3C_IRQTYPE_EDGE, }, /* SDI */
  783. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  784. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  785. { .type = S3C_IRQTYPE_LEVEL, }, /* NFCON */
  786. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  787. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  788. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  789. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  790. { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  791. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  792. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  793. };
  794. static struct s3c_irq_data init_s3c2440subint[32] = {
  795. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  796. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  797. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  798. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  799. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  800. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  801. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  802. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  803. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  804. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  805. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  806. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* TC */
  807. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* ADC */
  808. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
  809. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
  810. };
  811. void __init s3c2440_init_irq(void)
  812. {
  813. struct s3c_irq_intc *main_intc;
  814. pr_info("S3C2440: IRQ Support\n");
  815. #ifdef CONFIG_FIQ
  816. init_FIQ(FIQ_START);
  817. #endif
  818. main_intc = s3c24xx_init_intc(NULL, &init_s3c2440base[0], NULL, 0x4a000000);
  819. if (IS_ERR(main_intc)) {
  820. pr_err("irq: could not create main interrupt controller\n");
  821. return;
  822. }
  823. s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
  824. s3c24xx_init_intc(NULL, &init_s3c2440subint[0], main_intc, 0x4a000018);
  825. }
  826. #endif
  827. #ifdef CONFIG_CPU_S3C2442
  828. static struct s3c_irq_data init_s3c2442base[32] = {
  829. { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  830. { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  831. { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  832. { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  833. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  834. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  835. { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
  836. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  837. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  838. { .type = S3C_IRQTYPE_EDGE, }, /* WDT */
  839. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  840. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  841. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  842. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  843. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  844. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  845. { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
  846. { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
  847. { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
  848. { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
  849. { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
  850. { .type = S3C_IRQTYPE_EDGE, }, /* SDI */
  851. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  852. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  853. { .type = S3C_IRQTYPE_LEVEL, }, /* NFCON */
  854. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  855. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  856. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  857. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  858. { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  859. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  860. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  861. };
  862. static struct s3c_irq_data init_s3c2442subint[32] = {
  863. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  864. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  865. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  866. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  867. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  868. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  869. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  870. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  871. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  872. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  873. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  874. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* TC */
  875. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* ADC */
  876. };
  877. void __init s3c2442_init_irq(void)
  878. {
  879. struct s3c_irq_intc *main_intc;
  880. pr_info("S3C2442: IRQ Support\n");
  881. #ifdef CONFIG_FIQ
  882. init_FIQ(FIQ_START);
  883. #endif
  884. main_intc = s3c24xx_init_intc(NULL, &init_s3c2442base[0], NULL, 0x4a000000);
  885. if (IS_ERR(main_intc)) {
  886. pr_err("irq: could not create main interrupt controller\n");
  887. return;
  888. }
  889. s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
  890. s3c24xx_init_intc(NULL, &init_s3c2442subint[0], main_intc, 0x4a000018);
  891. }
  892. #endif
  893. #ifdef CONFIG_CPU_S3C2443
  894. static struct s3c_irq_data init_s3c2443base[32] = {
  895. { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  896. { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  897. { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  898. { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  899. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  900. { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  901. { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
  902. { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  903. { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  904. { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
  905. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  906. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  907. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  908. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  909. { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  910. { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  911. { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */
  912. { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
  913. { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */
  914. { .type = S3C_IRQTYPE_EDGE, }, /* CFON */
  915. { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
  916. { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
  917. { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  918. { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  919. { .type = S3C_IRQTYPE_EDGE, }, /* NAND */
  920. { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  921. { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  922. { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  923. { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  924. { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  925. { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  926. { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  927. };
  928. static struct s3c_irq_data init_s3c2443subint[32] = {
  929. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  930. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  931. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  932. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  933. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  934. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  935. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  936. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  937. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  938. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  939. { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  940. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */
  941. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */
  942. { .type = S3C_IRQTYPE_NONE }, /* reserved */
  943. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD1 */
  944. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
  945. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
  946. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
  947. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
  948. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
  949. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
  950. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
  951. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
  952. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
  953. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
  954. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
  955. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
  956. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
  957. { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
  958. };
  959. void __init s3c2443_init_irq(void)
  960. {
  961. struct s3c_irq_intc *main_intc;
  962. pr_info("S3C2443: IRQ Support\n");
  963. #ifdef CONFIG_FIQ
  964. init_FIQ(FIQ_START);
  965. #endif
  966. main_intc = s3c24xx_init_intc(NULL, &init_s3c2443base[0], NULL, 0x4a000000);
  967. if (IS_ERR(main_intc)) {
  968. pr_err("irq: could not create main interrupt controller\n");
  969. return;
  970. }
  971. s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
  972. s3c24xx_init_intc(NULL, &init_s3c2443subint[0], main_intc, 0x4a000018);
  973. }
  974. #endif