irq-s3c24xx.c 42 KB

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