extint.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*
  2. * External interrupt handling for AT32AP CPUs
  3. *
  4. * Copyright (C) 2006 Atmel Corporation
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #include <linux/errno.h>
  11. #include <linux/init.h>
  12. #include <linux/interrupt.h>
  13. #include <linux/irq.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/random.h>
  16. #include <asm/io.h>
  17. /* EIC register offsets */
  18. #define EIC_IER 0x0000
  19. #define EIC_IDR 0x0004
  20. #define EIC_IMR 0x0008
  21. #define EIC_ISR 0x000c
  22. #define EIC_ICR 0x0010
  23. #define EIC_MODE 0x0014
  24. #define EIC_EDGE 0x0018
  25. #define EIC_LEVEL 0x001c
  26. #define EIC_TEST 0x0020
  27. #define EIC_NMIC 0x0024
  28. /* Bitfields in TEST */
  29. #define EIC_TESTEN_OFFSET 31
  30. #define EIC_TESTEN_SIZE 1
  31. /* Bitfields in NMIC */
  32. #define EIC_EN_OFFSET 0
  33. #define EIC_EN_SIZE 1
  34. /* Bit manipulation macros */
  35. #define EIC_BIT(name) \
  36. (1 << EIC_##name##_OFFSET)
  37. #define EIC_BF(name,value) \
  38. (((value) & ((1 << EIC_##name##_SIZE) - 1)) \
  39. << EIC_##name##_OFFSET)
  40. #define EIC_BFEXT(name,value) \
  41. (((value) >> EIC_##name##_OFFSET) \
  42. & ((1 << EIC_##name##_SIZE) - 1))
  43. #define EIC_BFINS(name,value,old) \
  44. (((old) & ~(((1 << EIC_##name##_SIZE) - 1) \
  45. << EIC_##name##_OFFSET)) \
  46. | EIC_BF(name,value))
  47. /* Register access macros */
  48. #define eic_readl(port,reg) \
  49. __raw_readl((port)->regs + EIC_##reg)
  50. #define eic_writel(port,reg,value) \
  51. __raw_writel((value), (port)->regs + EIC_##reg)
  52. struct eic {
  53. void __iomem *regs;
  54. struct irq_chip *chip;
  55. unsigned int first_irq;
  56. };
  57. static void eic_ack_irq(unsigned int irq)
  58. {
  59. struct eic *eic = get_irq_chip_data(irq);
  60. eic_writel(eic, ICR, 1 << (irq - eic->first_irq));
  61. }
  62. static void eic_mask_irq(unsigned int irq)
  63. {
  64. struct eic *eic = get_irq_chip_data(irq);
  65. eic_writel(eic, IDR, 1 << (irq - eic->first_irq));
  66. }
  67. static void eic_mask_ack_irq(unsigned int irq)
  68. {
  69. struct eic *eic = get_irq_chip_data(irq);
  70. eic_writel(eic, ICR, 1 << (irq - eic->first_irq));
  71. eic_writel(eic, IDR, 1 << (irq - eic->first_irq));
  72. }
  73. static void eic_unmask_irq(unsigned int irq)
  74. {
  75. struct eic *eic = get_irq_chip_data(irq);
  76. eic_writel(eic, IER, 1 << (irq - eic->first_irq));
  77. }
  78. static int eic_set_irq_type(unsigned int irq, unsigned int flow_type)
  79. {
  80. struct eic *eic = get_irq_chip_data(irq);
  81. struct irq_desc *desc;
  82. unsigned int i = irq - eic->first_irq;
  83. u32 mode, edge, level;
  84. int ret = 0;
  85. flow_type &= IRQ_TYPE_SENSE_MASK;
  86. if (flow_type == IRQ_TYPE_NONE)
  87. flow_type = IRQ_TYPE_LEVEL_LOW;
  88. desc = &irq_desc[irq];
  89. mode = eic_readl(eic, MODE);
  90. edge = eic_readl(eic, EDGE);
  91. level = eic_readl(eic, LEVEL);
  92. switch (flow_type) {
  93. case IRQ_TYPE_LEVEL_LOW:
  94. mode |= 1 << i;
  95. level &= ~(1 << i);
  96. break;
  97. case IRQ_TYPE_LEVEL_HIGH:
  98. mode |= 1 << i;
  99. level |= 1 << i;
  100. break;
  101. case IRQ_TYPE_EDGE_RISING:
  102. mode &= ~(1 << i);
  103. edge |= 1 << i;
  104. break;
  105. case IRQ_TYPE_EDGE_FALLING:
  106. mode &= ~(1 << i);
  107. edge &= ~(1 << i);
  108. break;
  109. default:
  110. ret = -EINVAL;
  111. break;
  112. }
  113. if (ret == 0) {
  114. eic_writel(eic, MODE, mode);
  115. eic_writel(eic, EDGE, edge);
  116. eic_writel(eic, LEVEL, level);
  117. if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
  118. flow_type |= IRQ_LEVEL;
  119. desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
  120. desc->status |= flow_type;
  121. }
  122. return ret;
  123. }
  124. struct irq_chip eic_chip = {
  125. .name = "eic",
  126. .ack = eic_ack_irq,
  127. .mask = eic_mask_irq,
  128. .mask_ack = eic_mask_ack_irq,
  129. .unmask = eic_unmask_irq,
  130. .set_type = eic_set_irq_type,
  131. };
  132. static void demux_eic_irq(unsigned int irq, struct irq_desc *desc)
  133. {
  134. struct eic *eic = desc->handler_data;
  135. struct irq_desc *ext_desc;
  136. unsigned long status, pending;
  137. unsigned int i, ext_irq;
  138. status = eic_readl(eic, ISR);
  139. pending = status & eic_readl(eic, IMR);
  140. while (pending) {
  141. i = fls(pending) - 1;
  142. pending &= ~(1 << i);
  143. ext_irq = i + eic->first_irq;
  144. ext_desc = irq_desc + ext_irq;
  145. if (ext_desc->status & IRQ_LEVEL)
  146. handle_level_irq(ext_irq, ext_desc);
  147. else
  148. handle_edge_irq(ext_irq, ext_desc);
  149. }
  150. }
  151. static int __init eic_probe(struct platform_device *pdev)
  152. {
  153. struct eic *eic;
  154. struct resource *regs;
  155. unsigned int i;
  156. unsigned int nr_irqs;
  157. unsigned int int_irq;
  158. int ret;
  159. u32 pattern;
  160. regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  161. int_irq = platform_get_irq(pdev, 0);
  162. if (!regs || !int_irq) {
  163. dev_dbg(&pdev->dev, "missing regs and/or irq resource\n");
  164. return -ENXIO;
  165. }
  166. ret = -ENOMEM;
  167. eic = kzalloc(sizeof(struct eic), GFP_KERNEL);
  168. if (!eic) {
  169. dev_dbg(&pdev->dev, "no memory for eic structure\n");
  170. goto err_kzalloc;
  171. }
  172. eic->first_irq = EIM_IRQ_BASE + 32 * pdev->id;
  173. eic->regs = ioremap(regs->start, regs->end - regs->start + 1);
  174. if (!eic->regs) {
  175. dev_dbg(&pdev->dev, "failed to map regs\n");
  176. goto err_ioremap;
  177. }
  178. /*
  179. * Find out how many interrupt lines that are actually
  180. * implemented in hardware.
  181. */
  182. eic_writel(eic, IDR, ~0UL);
  183. eic_writel(eic, MODE, ~0UL);
  184. pattern = eic_readl(eic, MODE);
  185. nr_irqs = fls(pattern);
  186. /* Trigger on falling edge unless overridden by driver */
  187. eic_writel(eic, MODE, 0UL);
  188. eic_writel(eic, EDGE, 0UL);
  189. eic->chip = &eic_chip;
  190. for (i = 0; i < nr_irqs; i++) {
  191. /* NOTE the handler we set here is ignored by the demux */
  192. set_irq_chip_and_handler(eic->first_irq + i, &eic_chip,
  193. handle_level_irq);
  194. set_irq_chip_data(eic->first_irq + i, eic);
  195. }
  196. set_irq_chained_handler(int_irq, demux_eic_irq);
  197. set_irq_data(int_irq, eic);
  198. dev_info(&pdev->dev,
  199. "External Interrupt Controller at 0x%p, IRQ %u\n",
  200. eic->regs, int_irq);
  201. dev_info(&pdev->dev,
  202. "Handling %u external IRQs, starting with IRQ %u\n",
  203. nr_irqs, eic->first_irq);
  204. return 0;
  205. err_ioremap:
  206. kfree(eic);
  207. err_kzalloc:
  208. return ret;
  209. }
  210. static struct platform_driver eic_driver = {
  211. .driver = {
  212. .name = "at32_eic",
  213. },
  214. };
  215. static int __init eic_init(void)
  216. {
  217. return platform_driver_probe(&eic_driver, eic_probe);
  218. }
  219. arch_initcall(eic_init);