xilinx_intc.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /*
  2. * Interrupt controller driver for Xilinx Virtex FPGAs
  3. *
  4. * Copyright (C) 2007 Secret Lab Technologies Ltd.
  5. *
  6. * This file is licensed under the terms of the GNU General Public License
  7. * version 2. This program is licensed "as is" without any warranty of any
  8. * kind, whether express or implied.
  9. *
  10. */
  11. /*
  12. * This is a driver for the interrupt controller typically found in
  13. * Xilinx Virtex FPGA designs.
  14. *
  15. * The interrupt sense levels are hard coded into the FPGA design with
  16. * typically a 1:1 relationship between irq lines and devices (no shared
  17. * irq lines). Therefore, this driver does not attempt to handle edge
  18. * and level interrupts differently.
  19. */
  20. #undef DEBUG
  21. #include <linux/kernel.h>
  22. #include <linux/irq.h>
  23. #include <linux/of.h>
  24. #include <asm/io.h>
  25. #include <asm/processor.h>
  26. #include <asm/irq.h>
  27. /*
  28. * INTC Registers
  29. */
  30. #define XINTC_ISR 0 /* Interrupt Status */
  31. #define XINTC_IPR 4 /* Interrupt Pending */
  32. #define XINTC_IER 8 /* Interrupt Enable */
  33. #define XINTC_IAR 12 /* Interrupt Acknowledge */
  34. #define XINTC_SIE 16 /* Set Interrupt Enable bits */
  35. #define XINTC_CIE 20 /* Clear Interrupt Enable bits */
  36. #define XINTC_IVR 24 /* Interrupt Vector */
  37. #define XINTC_MER 28 /* Master Enable */
  38. static struct irq_host *master_irqhost;
  39. #define XILINX_INTC_MAXIRQS (32)
  40. /* The following table allows the interrupt type, edge or level,
  41. * to be cached after being read from the device tree until the interrupt
  42. * is mapped
  43. */
  44. static int xilinx_intc_typetable[XILINX_INTC_MAXIRQS];
  45. /* Map the interrupt type from the device tree to the interrupt types
  46. * used by the interrupt subsystem
  47. */
  48. static unsigned char xilinx_intc_map_senses[] = {
  49. IRQ_TYPE_EDGE_RISING,
  50. IRQ_TYPE_EDGE_FALLING,
  51. IRQ_TYPE_LEVEL_HIGH,
  52. IRQ_TYPE_LEVEL_LOW,
  53. };
  54. /*
  55. * The interrupt controller is setup such that it doesn't work well with
  56. * the level interrupt handler in the kernel because the handler acks the
  57. * interrupt before calling the application interrupt handler. To deal with
  58. * that, we use 2 different irq chips so that different functions can be
  59. * used for level and edge type interrupts.
  60. *
  61. * IRQ Chip common (across level and edge) operations
  62. */
  63. static void xilinx_intc_mask(unsigned int virq)
  64. {
  65. int irq = virq_to_hw(virq);
  66. void * regs = get_irq_chip_data(virq);
  67. pr_debug("mask: %d\n", irq);
  68. out_be32(regs + XINTC_CIE, 1 << irq);
  69. }
  70. static int xilinx_intc_set_type(unsigned int virq, unsigned int flow_type)
  71. {
  72. struct irq_desc *desc = get_irq_desc(virq);
  73. desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
  74. desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
  75. if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
  76. desc->status |= IRQ_LEVEL;
  77. return 0;
  78. }
  79. /*
  80. * IRQ Chip level operations
  81. */
  82. static void xilinx_intc_level_unmask(unsigned int virq)
  83. {
  84. int irq = virq_to_hw(virq);
  85. void * regs = get_irq_chip_data(virq);
  86. pr_debug("unmask: %d\n", irq);
  87. out_be32(regs + XINTC_SIE, 1 << irq);
  88. /* ack level irqs because they can't be acked during
  89. * ack function since the handle_level_irq function
  90. * acks the irq before calling the inerrupt handler
  91. */
  92. out_be32(regs + XINTC_IAR, 1 << irq);
  93. }
  94. static struct irq_chip xilinx_intc_level_irqchip = {
  95. .typename = "Xilinx Level INTC",
  96. .mask = xilinx_intc_mask,
  97. .mask_ack = xilinx_intc_mask,
  98. .unmask = xilinx_intc_level_unmask,
  99. .set_type = xilinx_intc_set_type,
  100. };
  101. /*
  102. * IRQ Chip edge operations
  103. */
  104. static void xilinx_intc_edge_unmask(unsigned int virq)
  105. {
  106. int irq = virq_to_hw(virq);
  107. void *regs = get_irq_chip_data(virq);
  108. pr_debug("unmask: %d\n", irq);
  109. out_be32(regs + XINTC_SIE, 1 << irq);
  110. }
  111. static void xilinx_intc_edge_ack(unsigned int virq)
  112. {
  113. int irq = virq_to_hw(virq);
  114. void * regs = get_irq_chip_data(virq);
  115. pr_debug("ack: %d\n", irq);
  116. out_be32(regs + XINTC_IAR, 1 << irq);
  117. }
  118. static struct irq_chip xilinx_intc_edge_irqchip = {
  119. .typename = "Xilinx Edge INTC",
  120. .mask = xilinx_intc_mask,
  121. .unmask = xilinx_intc_edge_unmask,
  122. .ack = xilinx_intc_edge_ack,
  123. .set_type = xilinx_intc_set_type,
  124. };
  125. /*
  126. * IRQ Host operations
  127. */
  128. /**
  129. * xilinx_intc_xlate - translate virq# from device tree interrupts property
  130. */
  131. static int xilinx_intc_xlate(struct irq_host *h, struct device_node *ct,
  132. u32 *intspec, unsigned int intsize,
  133. irq_hw_number_t *out_hwirq,
  134. unsigned int *out_flags)
  135. {
  136. if ((intsize < 2) || (intspec[0] >= XILINX_INTC_MAXIRQS))
  137. return -EINVAL;
  138. /* keep a copy of the interrupt type til the interrupt is mapped
  139. */
  140. xilinx_intc_typetable[intspec[0]] = xilinx_intc_map_senses[intspec[1]];
  141. /* Xilinx uses 2 interrupt entries, the 1st being the h/w
  142. * interrupt number, the 2nd being the interrupt type, edge or level
  143. */
  144. *out_hwirq = intspec[0];
  145. *out_flags = xilinx_intc_map_senses[intspec[1]];
  146. return 0;
  147. }
  148. static int xilinx_intc_map(struct irq_host *h, unsigned int virq,
  149. irq_hw_number_t irq)
  150. {
  151. set_irq_chip_data(virq, h->host_data);
  152. if (xilinx_intc_typetable[irq] == IRQ_TYPE_LEVEL_HIGH ||
  153. xilinx_intc_typetable[irq] == IRQ_TYPE_LEVEL_LOW) {
  154. set_irq_chip_and_handler(virq, &xilinx_intc_level_irqchip,
  155. handle_level_irq);
  156. } else {
  157. set_irq_chip_and_handler(virq, &xilinx_intc_edge_irqchip,
  158. handle_edge_irq);
  159. }
  160. return 0;
  161. }
  162. static struct irq_host_ops xilinx_intc_ops = {
  163. .map = xilinx_intc_map,
  164. .xlate = xilinx_intc_xlate,
  165. };
  166. struct irq_host * __init
  167. xilinx_intc_init(struct device_node *np)
  168. {
  169. struct irq_host * irq;
  170. struct resource res;
  171. void * regs;
  172. int rc;
  173. /* Find and map the intc registers */
  174. rc = of_address_to_resource(np, 0, &res);
  175. if (rc) {
  176. printk(KERN_ERR __FILE__ ": of_address_to_resource() failed\n");
  177. return NULL;
  178. }
  179. regs = ioremap(res.start, 32);
  180. printk(KERN_INFO "Xilinx intc at 0x%08llx mapped to 0x%p\n",
  181. (unsigned long long) res.start, regs);
  182. /* Setup interrupt controller */
  183. out_be32(regs + XINTC_IER, 0); /* disable all irqs */
  184. out_be32(regs + XINTC_IAR, ~(u32) 0); /* Acknowledge pending irqs */
  185. out_be32(regs + XINTC_MER, 0x3UL); /* Turn on the Master Enable. */
  186. /* Allocate and initialize an irq_host structure. */
  187. irq = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, XILINX_INTC_MAXIRQS,
  188. &xilinx_intc_ops, -1);
  189. if (!irq)
  190. panic(__FILE__ ": Cannot allocate IRQ host\n");
  191. irq->host_data = regs;
  192. return irq;
  193. }
  194. int xilinx_intc_get_irq(void)
  195. {
  196. void * regs = master_irqhost->host_data;
  197. pr_debug("get_irq:\n");
  198. return irq_linear_revmap(master_irqhost, in_be32(regs + XINTC_IVR));
  199. }
  200. void __init xilinx_intc_init_tree(void)
  201. {
  202. struct device_node *np;
  203. /* find top level interrupt controller */
  204. for_each_compatible_node(np, NULL, "xlnx,opb-intc-1.00.c") {
  205. if (!of_get_property(np, "interrupts", NULL))
  206. break;
  207. }
  208. if (!np) {
  209. for_each_compatible_node(np, NULL, "xlnx,xps-intc-1.00.a") {
  210. if (!of_get_property(np, "interrupts", NULL))
  211. break;
  212. }
  213. }
  214. /* xilinx interrupt controller needs to be top level */
  215. BUG_ON(!np);
  216. master_irqhost = xilinx_intc_init(np);
  217. BUG_ON(!master_irqhost);
  218. irq_set_default_host(master_irqhost);
  219. of_node_put(np);
  220. }