2 * Copyright (C) 2007-2013 Michal Simek <monstr@monstr.eu>
3 * Copyright (C) 2012-2013 Xilinx, Inc.
4 * Copyright (C) 2007-2009 PetaLogix
5 * Copyright (C) 2006 Atmark Techno, Inc.
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
12 #include <linux/irqdomain.h>
13 #include <linux/irq.h>
14 #include <linux/irqchip.h>
15 #include <linux/irqchip/chained_irq.h>
16 #include <linux/of_address.h>
18 #include <linux/bug.h>
19 #include <linux/of_irq.h>
21 static struct xintc_irq_chip *primary_intc;
23 /* No one else should require these constants, so define them locally here. */
24 #define ISR 0x00 /* Interrupt Status Register */
25 #define IPR 0x04 /* Interrupt Pending Register */
26 #define IER 0x08 /* Interrupt Enable Register */
27 #define IAR 0x0c /* Interrupt Acknowledge Register */
28 #define SIE 0x10 /* Set Interrupt Enable bits */
29 #define CIE 0x14 /* Clear Interrupt Enable bits */
30 #define IVR 0x18 /* Interrupt Vector Register */
31 #define MER 0x1c /* Master Enable Register */
34 #define MER_HIE (1<<1)
36 struct xintc_irq_chip {
38 struct irq_domain *root_domain;
40 struct irq_chip *intc_dev;
42 unsigned int (*read_fn)(void __iomem *addr);
43 void (*write_fn)(void __iomem *addr, u32);
46 static void xintc_write(void __iomem *addr, u32 data)
48 iowrite32(data, addr);
51 static unsigned int xintc_read(void __iomem *addr)
53 return ioread32(addr);
56 static void xintc_write_be(void __iomem *addr, u32 data)
58 iowrite32be(data, addr);
61 static unsigned int xintc_read_be(void __iomem *addr)
63 return ioread32be(addr);
66 static void intc_enable_or_unmask(struct irq_data *d)
68 unsigned long mask = 1 << d->hwirq;
69 struct xintc_irq_chip *local_intc = irq_data_get_irq_chip_data(d);
71 pr_debug("irq-xilinx: enable_or_unmask: %ld\n", d->hwirq);
73 /* ack level irqs because they can't be acked during
74 * ack function since the handle_level_irq function
75 * acks the irq before calling the interrupt handler
77 if (irqd_is_level_type(d))
78 local_intc->write_fn(local_intc->base + IAR, mask);
80 local_intc->write_fn(local_intc->base + SIE, mask);
83 static void intc_disable_or_mask(struct irq_data *d)
85 struct xintc_irq_chip *local_intc = irq_data_get_irq_chip_data(d);
87 pr_debug("irq-xilinx: disable: %ld\n", d->hwirq);
88 local_intc->write_fn(local_intc->base + CIE, 1 << d->hwirq);
91 static void intc_ack(struct irq_data *d)
93 struct xintc_irq_chip *local_intc = irq_data_get_irq_chip_data(d);
95 pr_debug("irq-xilinx: ack: %ld\n", d->hwirq);
96 local_intc->write_fn(local_intc->base + IAR, 1 << d->hwirq);
99 static void intc_mask_ack(struct irq_data *d)
101 unsigned long mask = 1 << d->hwirq;
102 struct xintc_irq_chip *local_intc = irq_data_get_irq_chip_data(d);
104 pr_debug("irq-xilinx: disable_and_ack: %ld\n", d->hwirq);
105 local_intc->write_fn(local_intc->base + CIE, mask);
106 local_intc->write_fn(local_intc->base + IAR, mask);
109 static unsigned int xintc_get_irq_local(struct xintc_irq_chip *local_intc)
113 hwirq = local_intc->read_fn(local_intc->base + IVR);
115 irq = irq_find_mapping(local_intc->root_domain, hwirq);
117 pr_debug("irq-xilinx: hwirq=%d, irq=%d\n", hwirq, irq);
122 unsigned int xintc_get_irq(void)
126 hwirq = primary_intc->read_fn(primary_intc->base + IVR);
128 irq = irq_find_mapping(primary_intc->root_domain, hwirq);
130 pr_debug("irq-xilinx: hwirq=%d, irq=%d\n", hwirq, irq);
135 static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
137 struct xintc_irq_chip *local_intc = d->host_data;
139 if (local_intc->intr_mask & (1 << hw)) {
140 irq_set_chip_and_handler_name(irq, local_intc->intc_dev,
141 handle_edge_irq, "edge");
142 irq_clear_status_flags(irq, IRQ_LEVEL);
144 irq_set_chip_and_handler_name(irq, local_intc->intc_dev,
145 handle_level_irq, "level");
146 irq_set_status_flags(irq, IRQ_LEVEL);
148 irq_set_chip_data(irq, local_intc);
152 static const struct irq_domain_ops xintc_irq_domain_ops = {
153 .xlate = irq_domain_xlate_onetwocell,
157 static void xil_intc_irq_handler(struct irq_desc *desc)
159 struct irq_chip *chip = irq_desc_get_chip(desc);
160 struct xintc_irq_chip *local_intc =
161 irq_data_get_irq_handler_data(&desc->irq_data);
164 chained_irq_enter(chip, desc);
166 pending = xintc_get_irq_local(local_intc);
169 generic_handle_irq(pending);
171 chained_irq_exit(chip, desc);
174 static int __init xilinx_intc_of_init(struct device_node *intc,
175 struct device_node *parent)
178 struct xintc_irq_chip *irqc;
179 struct irq_chip *intc_dev;
181 irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);
184 irqc->base = of_iomap(intc, 0);
187 ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &irqc->nr_irq);
189 pr_err("irq-xilinx: unable to read xlnx,num-intr-inputs\n");
193 ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &irqc->intr_mask);
195 pr_warn("irq-xilinx: unable to read xlnx,kind-of-intr\n");
199 if (irqc->intr_mask >> irqc->nr_irq)
200 pr_warn("irq-xilinx: mismatch in kind-of-intr param\n");
202 pr_info("irq-xilinx: %pOF: num_irq=%d, edge=0x%x\n",
203 intc, irqc->nr_irq, irqc->intr_mask);
205 intc_dev = kzalloc(sizeof(*intc_dev), GFP_KERNEL);
211 intc_dev->name = intc->full_name;
212 intc_dev->irq_unmask = intc_enable_or_unmask,
213 intc_dev->irq_mask = intc_disable_or_mask,
214 intc_dev->irq_ack = intc_ack,
215 intc_dev->irq_mask_ack = intc_mask_ack,
216 irqc->intc_dev = intc_dev;
218 irqc->write_fn = xintc_write;
219 irqc->read_fn = xintc_read;
221 * Disable all external interrupts until they are
222 * explicity requested.
224 irqc->write_fn(irqc->base + IER, 0);
226 /* Acknowledge any pending interrupts just in case. */
227 irqc->write_fn(irqc->base + IAR, 0xffffffff);
229 /* Turn on the Master Enable. */
230 irqc->write_fn(irqc->base + MER, MER_HIE | MER_ME);
231 if (!(irqc->read_fn(irqc->base + MER) & (MER_HIE | MER_ME))) {
232 irqc->write_fn = xintc_write_be;
233 irqc->read_fn = xintc_read_be;
234 irqc->write_fn(irqc->base + MER, MER_HIE | MER_ME);
237 irqc->root_domain = irq_domain_add_linear(intc, irqc->nr_irq,
238 &xintc_irq_domain_ops, irqc);
239 if (!irqc->root_domain) {
240 pr_err("irq-xilinx: Unable to create IRQ domain\n");
245 irq = irq_of_parse_and_map(intc, 0);
247 irq_set_chained_handler_and_data(irq,
248 xil_intc_irq_handler,
251 pr_err("irq-xilinx: interrupts property not in DT\n");
257 irq_set_default_host(primary_intc->root_domain);
271 IRQCHIP_DECLARE(xilinx_intc_xps, "xlnx,xps-intc-1.00.a", xilinx_intc_of_init);
272 IRQCHIP_DECLARE(xilinx_intc_opb, "xlnx,opb-intc-1.00.c", xilinx_intc_of_init);