irq-s3c24xx.c 37 KB

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