xref: /OK3568_Linux_fs/kernel/drivers/irqchip/irq-versatile-fpga.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *  Support for Versatile FPGA-based IRQ controllers
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun #include <linux/bitops.h>
6*4882a593Smuzhiyun #include <linux/irq.h>
7*4882a593Smuzhiyun #include <linux/io.h>
8*4882a593Smuzhiyun #include <linux/irqchip.h>
9*4882a593Smuzhiyun #include <linux/irqchip/chained_irq.h>
10*4882a593Smuzhiyun #include <linux/irqchip/versatile-fpga.h>
11*4882a593Smuzhiyun #include <linux/irqdomain.h>
12*4882a593Smuzhiyun #include <linux/module.h>
13*4882a593Smuzhiyun #include <linux/of.h>
14*4882a593Smuzhiyun #include <linux/of_address.h>
15*4882a593Smuzhiyun #include <linux/of_irq.h>
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #include <asm/exception.h>
18*4882a593Smuzhiyun #include <asm/mach/irq.h>
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #define IRQ_STATUS		0x00
21*4882a593Smuzhiyun #define IRQ_RAW_STATUS		0x04
22*4882a593Smuzhiyun #define IRQ_ENABLE_SET		0x08
23*4882a593Smuzhiyun #define IRQ_ENABLE_CLEAR	0x0c
24*4882a593Smuzhiyun #define INT_SOFT_SET		0x10
25*4882a593Smuzhiyun #define INT_SOFT_CLEAR		0x14
26*4882a593Smuzhiyun #define FIQ_STATUS		0x20
27*4882a593Smuzhiyun #define FIQ_RAW_STATUS		0x24
28*4882a593Smuzhiyun #define FIQ_ENABLE		0x28
29*4882a593Smuzhiyun #define FIQ_ENABLE_SET		0x28
30*4882a593Smuzhiyun #define FIQ_ENABLE_CLEAR	0x2C
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #define PIC_ENABLES             0x20	/* set interrupt pass through bits */
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun /**
35*4882a593Smuzhiyun  * struct fpga_irq_data - irq data container for the FPGA IRQ controller
36*4882a593Smuzhiyun  * @base: memory offset in virtual memory
37*4882a593Smuzhiyun  * @chip: chip container for this instance
38*4882a593Smuzhiyun  * @domain: IRQ domain for this instance
39*4882a593Smuzhiyun  * @valid: mask for valid IRQs on this controller
40*4882a593Smuzhiyun  * @used_irqs: number of active IRQs on this controller
41*4882a593Smuzhiyun  */
42*4882a593Smuzhiyun struct fpga_irq_data {
43*4882a593Smuzhiyun 	void __iomem *base;
44*4882a593Smuzhiyun 	struct irq_chip chip;
45*4882a593Smuzhiyun 	u32 valid;
46*4882a593Smuzhiyun 	struct irq_domain *domain;
47*4882a593Smuzhiyun 	u8 used_irqs;
48*4882a593Smuzhiyun };
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun /* we cannot allocate memory when the controllers are initially registered */
51*4882a593Smuzhiyun static struct fpga_irq_data fpga_irq_devices[CONFIG_VERSATILE_FPGA_IRQ_NR];
52*4882a593Smuzhiyun static int fpga_irq_id;
53*4882a593Smuzhiyun 
fpga_irq_mask(struct irq_data * d)54*4882a593Smuzhiyun static void fpga_irq_mask(struct irq_data *d)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun 	struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
57*4882a593Smuzhiyun 	u32 mask = 1 << d->hwirq;
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun 	writel(mask, f->base + IRQ_ENABLE_CLEAR);
60*4882a593Smuzhiyun }
61*4882a593Smuzhiyun 
fpga_irq_unmask(struct irq_data * d)62*4882a593Smuzhiyun static void fpga_irq_unmask(struct irq_data *d)
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun 	struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
65*4882a593Smuzhiyun 	u32 mask = 1 << d->hwirq;
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	writel(mask, f->base + IRQ_ENABLE_SET);
68*4882a593Smuzhiyun }
69*4882a593Smuzhiyun 
fpga_irq_handle(struct irq_desc * desc)70*4882a593Smuzhiyun static void fpga_irq_handle(struct irq_desc *desc)
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun 	struct irq_chip *chip = irq_desc_get_chip(desc);
73*4882a593Smuzhiyun 	struct fpga_irq_data *f = irq_desc_get_handler_data(desc);
74*4882a593Smuzhiyun 	u32 status;
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	chained_irq_enter(chip, desc);
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	status = readl(f->base + IRQ_STATUS);
79*4882a593Smuzhiyun 	if (status == 0) {
80*4882a593Smuzhiyun 		do_bad_IRQ(desc);
81*4882a593Smuzhiyun 		goto out;
82*4882a593Smuzhiyun 	}
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 	do {
85*4882a593Smuzhiyun 		unsigned int irq = ffs(status) - 1;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 		status &= ~(1 << irq);
88*4882a593Smuzhiyun 		generic_handle_irq(irq_find_mapping(f->domain, irq));
89*4882a593Smuzhiyun 	} while (status);
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun out:
92*4882a593Smuzhiyun 	chained_irq_exit(chip, desc);
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun /*
96*4882a593Smuzhiyun  * Handle each interrupt in a single FPGA IRQ controller.  Returns non-zero
97*4882a593Smuzhiyun  * if we've handled at least one interrupt.  This does a single read of the
98*4882a593Smuzhiyun  * status register and handles all interrupts in order from LSB first.
99*4882a593Smuzhiyun  */
handle_one_fpga(struct fpga_irq_data * f,struct pt_regs * regs)100*4882a593Smuzhiyun static int handle_one_fpga(struct fpga_irq_data *f, struct pt_regs *regs)
101*4882a593Smuzhiyun {
102*4882a593Smuzhiyun 	int handled = 0;
103*4882a593Smuzhiyun 	int irq;
104*4882a593Smuzhiyun 	u32 status;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	while ((status  = readl(f->base + IRQ_STATUS))) {
107*4882a593Smuzhiyun 		irq = ffs(status) - 1;
108*4882a593Smuzhiyun 		handle_domain_irq(f->domain, irq, regs);
109*4882a593Smuzhiyun 		handled = 1;
110*4882a593Smuzhiyun 	}
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	return handled;
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun /*
116*4882a593Smuzhiyun  * Keep iterating over all registered FPGA IRQ controllers until there are
117*4882a593Smuzhiyun  * no pending interrupts.
118*4882a593Smuzhiyun  */
fpga_handle_irq(struct pt_regs * regs)119*4882a593Smuzhiyun asmlinkage void __exception_irq_entry fpga_handle_irq(struct pt_regs *regs)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun 	int i, handled;
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun 	do {
124*4882a593Smuzhiyun 		for (i = 0, handled = 0; i < fpga_irq_id; ++i)
125*4882a593Smuzhiyun 			handled |= handle_one_fpga(&fpga_irq_devices[i], regs);
126*4882a593Smuzhiyun 	} while (handled);
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun 
fpga_irqdomain_map(struct irq_domain * d,unsigned int irq,irq_hw_number_t hwirq)129*4882a593Smuzhiyun static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq,
130*4882a593Smuzhiyun 		irq_hw_number_t hwirq)
131*4882a593Smuzhiyun {
132*4882a593Smuzhiyun 	struct fpga_irq_data *f = d->host_data;
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	/* Skip invalid IRQs, only register handlers for the real ones */
135*4882a593Smuzhiyun 	if (!(f->valid & BIT(hwirq)))
136*4882a593Smuzhiyun 		return -EPERM;
137*4882a593Smuzhiyun 	irq_set_chip_data(irq, f);
138*4882a593Smuzhiyun 	irq_set_chip_and_handler(irq, &f->chip,
139*4882a593Smuzhiyun 				handle_level_irq);
140*4882a593Smuzhiyun 	irq_set_probe(irq);
141*4882a593Smuzhiyun 	return 0;
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun static const struct irq_domain_ops fpga_irqdomain_ops = {
145*4882a593Smuzhiyun 	.map = fpga_irqdomain_map,
146*4882a593Smuzhiyun 	.xlate = irq_domain_xlate_onetwocell,
147*4882a593Smuzhiyun };
148*4882a593Smuzhiyun 
fpga_irq_init(void __iomem * base,const char * name,int irq_start,int parent_irq,u32 valid,struct device_node * node)149*4882a593Smuzhiyun void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start,
150*4882a593Smuzhiyun 			  int parent_irq, u32 valid, struct device_node *node)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun 	struct fpga_irq_data *f;
153*4882a593Smuzhiyun 	int i;
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	if (fpga_irq_id >= ARRAY_SIZE(fpga_irq_devices)) {
156*4882a593Smuzhiyun 		pr_err("%s: too few FPGA IRQ controllers, increase CONFIG_VERSATILE_FPGA_IRQ_NR\n", __func__);
157*4882a593Smuzhiyun 		return;
158*4882a593Smuzhiyun 	}
159*4882a593Smuzhiyun 	f = &fpga_irq_devices[fpga_irq_id];
160*4882a593Smuzhiyun 	f->base = base;
161*4882a593Smuzhiyun 	f->chip.name = name;
162*4882a593Smuzhiyun 	f->chip.irq_ack = fpga_irq_mask;
163*4882a593Smuzhiyun 	f->chip.irq_mask = fpga_irq_mask;
164*4882a593Smuzhiyun 	f->chip.irq_unmask = fpga_irq_unmask;
165*4882a593Smuzhiyun 	f->valid = valid;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	if (parent_irq != -1) {
168*4882a593Smuzhiyun 		irq_set_chained_handler_and_data(parent_irq, fpga_irq_handle,
169*4882a593Smuzhiyun 						 f);
170*4882a593Smuzhiyun 	}
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	/* This will also allocate irq descriptors */
173*4882a593Smuzhiyun 	f->domain = irq_domain_add_simple(node, fls(valid), irq_start,
174*4882a593Smuzhiyun 					  &fpga_irqdomain_ops, f);
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	/* This will allocate all valid descriptors in the linear case */
177*4882a593Smuzhiyun 	for (i = 0; i < fls(valid); i++)
178*4882a593Smuzhiyun 		if (valid & BIT(i)) {
179*4882a593Smuzhiyun 			if (!irq_start)
180*4882a593Smuzhiyun 				irq_create_mapping(f->domain, i);
181*4882a593Smuzhiyun 			f->used_irqs++;
182*4882a593Smuzhiyun 		}
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs",
185*4882a593Smuzhiyun 		fpga_irq_id, name, base, f->used_irqs);
186*4882a593Smuzhiyun 	if (parent_irq != -1)
187*4882a593Smuzhiyun 		pr_cont(", parent IRQ: %d\n", parent_irq);
188*4882a593Smuzhiyun 	else
189*4882a593Smuzhiyun 		pr_cont("\n");
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	fpga_irq_id++;
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun #ifdef CONFIG_OF
fpga_irq_of_init(struct device_node * node,struct device_node * parent)195*4882a593Smuzhiyun int __init fpga_irq_of_init(struct device_node *node,
196*4882a593Smuzhiyun 			    struct device_node *parent)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun 	void __iomem *base;
199*4882a593Smuzhiyun 	u32 clear_mask;
200*4882a593Smuzhiyun 	u32 valid_mask;
201*4882a593Smuzhiyun 	int parent_irq;
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	if (WARN_ON(!node))
204*4882a593Smuzhiyun 		return -ENODEV;
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 	base = of_iomap(node, 0);
207*4882a593Smuzhiyun 	WARN(!base, "unable to map fpga irq registers\n");
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 	if (of_property_read_u32(node, "clear-mask", &clear_mask))
210*4882a593Smuzhiyun 		clear_mask = 0;
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	if (of_property_read_u32(node, "valid-mask", &valid_mask))
213*4882a593Smuzhiyun 		valid_mask = 0;
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	writel(clear_mask, base + IRQ_ENABLE_CLEAR);
216*4882a593Smuzhiyun 	writel(clear_mask, base + FIQ_ENABLE_CLEAR);
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 	/* Some chips are cascaded from a parent IRQ */
219*4882a593Smuzhiyun 	parent_irq = irq_of_parse_and_map(node, 0);
220*4882a593Smuzhiyun 	if (!parent_irq) {
221*4882a593Smuzhiyun 		set_handle_irq(fpga_handle_irq);
222*4882a593Smuzhiyun 		parent_irq = -1;
223*4882a593Smuzhiyun 	}
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	fpga_irq_init(base, node->name, 0, parent_irq, valid_mask, node);
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	/*
228*4882a593Smuzhiyun 	 * On Versatile AB/PB, some secondary interrupts have a direct
229*4882a593Smuzhiyun 	 * pass-thru to the primary controller for IRQs 20 and 22-31 which need
230*4882a593Smuzhiyun 	 * to be enabled. See section 3.10 of the Versatile AB user guide.
231*4882a593Smuzhiyun 	 */
232*4882a593Smuzhiyun 	if (of_device_is_compatible(node, "arm,versatile-sic"))
233*4882a593Smuzhiyun 		writel(0xffd00000, base + PIC_ENABLES);
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	return 0;
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun IRQCHIP_DECLARE(arm_fpga, "arm,versatile-fpga-irq", fpga_irq_of_init);
238*4882a593Smuzhiyun IRQCHIP_DECLARE(arm_fpga_sic, "arm,versatile-sic", fpga_irq_of_init);
239*4882a593Smuzhiyun IRQCHIP_DECLARE(ox810se_rps, "oxsemi,ox810se-rps-irq", fpga_irq_of_init);
240*4882a593Smuzhiyun #endif
241