irq-s3c24xx.c 42 KB

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