irq-s3c24xx.c 42 KB

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