irq-s3c24xx.c 37 KB

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