xref: /linux/drivers/irqchip/irq-bcm7120-l2.c (revision c0c914eca7f251c70facc37dfebeaf176601918d)
1 /*
2  * Broadcom BCM7120 style Level 2 interrupt controller driver
3  *
4  * Copyright (C) 2014 Broadcom 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 
11 #define pr_fmt(fmt)	KBUILD_MODNAME	": " fmt
12 
13 #include <linux/init.h>
14 #include <linux/slab.h>
15 #include <linux/module.h>
16 #include <linux/kconfig.h>
17 #include <linux/kernel.h>
18 #include <linux/platform_device.h>
19 #include <linux/of.h>
20 #include <linux/of_irq.h>
21 #include <linux/of_address.h>
22 #include <linux/of_platform.h>
23 #include <linux/interrupt.h>
24 #include <linux/irq.h>
25 #include <linux/io.h>
26 #include <linux/irqdomain.h>
27 #include <linux/reboot.h>
28 #include <linux/bitops.h>
29 #include <linux/irqchip.h>
30 #include <linux/irqchip/chained_irq.h>
31 
32 /* Register offset in the L2 interrupt controller */
33 #define IRQEN		0x00
34 #define IRQSTAT		0x04
35 
36 #define MAX_WORDS	4
37 #define MAX_MAPPINGS	(MAX_WORDS * 2)
38 #define IRQS_PER_WORD	32
39 
40 struct bcm7120_l1_intc_data {
41 	struct bcm7120_l2_intc_data *b;
42 	u32 irq_map_mask[MAX_WORDS];
43 };
44 
45 struct bcm7120_l2_intc_data {
46 	unsigned int n_words;
47 	void __iomem *map_base[MAX_MAPPINGS];
48 	void __iomem *pair_base[MAX_WORDS];
49 	int en_offset[MAX_WORDS];
50 	int stat_offset[MAX_WORDS];
51 	struct irq_domain *domain;
52 	bool can_wake;
53 	u32 irq_fwd_mask[MAX_WORDS];
54 	struct bcm7120_l1_intc_data *l1_data;
55 	int num_parent_irqs;
56 	const __be32 *map_mask_prop;
57 };
58 
59 static void bcm7120_l2_intc_irq_handle(struct irq_desc *desc)
60 {
61 	struct bcm7120_l1_intc_data *data = irq_desc_get_handler_data(desc);
62 	struct bcm7120_l2_intc_data *b = data->b;
63 	struct irq_chip *chip = irq_desc_get_chip(desc);
64 	unsigned int idx;
65 
66 	chained_irq_enter(chip, desc);
67 
68 	for (idx = 0; idx < b->n_words; idx++) {
69 		int base = idx * IRQS_PER_WORD;
70 		struct irq_chip_generic *gc =
71 			irq_get_domain_generic_chip(b->domain, base);
72 		unsigned long pending;
73 		int hwirq;
74 
75 		irq_gc_lock(gc);
76 		pending = irq_reg_readl(gc, b->stat_offset[idx]) &
77 					    gc->mask_cache &
78 					    data->irq_map_mask[idx];
79 		irq_gc_unlock(gc);
80 
81 		for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) {
82 			generic_handle_irq(irq_find_mapping(b->domain,
83 					   base + hwirq));
84 		}
85 	}
86 
87 	chained_irq_exit(chip, desc);
88 }
89 
90 static void bcm7120_l2_intc_suspend(struct irq_chip_generic *gc)
91 {
92 	struct bcm7120_l2_intc_data *b = gc->private;
93 	struct irq_chip_type *ct = gc->chip_types;
94 
95 	irq_gc_lock(gc);
96 	if (b->can_wake)
97 		irq_reg_writel(gc, gc->mask_cache | gc->wake_active,
98 			       ct->regs.mask);
99 	irq_gc_unlock(gc);
100 }
101 
102 static void bcm7120_l2_intc_resume(struct irq_chip_generic *gc)
103 {
104 	struct irq_chip_type *ct = gc->chip_types;
105 
106 	/* Restore the saved mask */
107 	irq_gc_lock(gc);
108 	irq_reg_writel(gc, gc->mask_cache, ct->regs.mask);
109 	irq_gc_unlock(gc);
110 }
111 
112 static int bcm7120_l2_intc_init_one(struct device_node *dn,
113 					struct bcm7120_l2_intc_data *data,
114 					int irq, u32 *valid_mask)
115 {
116 	struct bcm7120_l1_intc_data *l1_data = &data->l1_data[irq];
117 	int parent_irq;
118 	unsigned int idx;
119 
120 	parent_irq = irq_of_parse_and_map(dn, irq);
121 	if (!parent_irq) {
122 		pr_err("failed to map interrupt %d\n", irq);
123 		return -EINVAL;
124 	}
125 
126 	/* For multiple parent IRQs with multiple words, this looks like:
127 	 * <irq0_w0 irq0_w1 irq1_w0 irq1_w1 ...>
128 	 *
129 	 * We need to associate a given parent interrupt with its corresponding
130 	 * map_mask in order to mask the status register with it because we
131 	 * have the same handler being called for multiple parent interrupts.
132 	 *
133 	 * This is typically something needed on BCM7xxx (STB chips).
134 	 */
135 	for (idx = 0; idx < data->n_words; idx++) {
136 		if (data->map_mask_prop) {
137 			l1_data->irq_map_mask[idx] |=
138 				be32_to_cpup(data->map_mask_prop +
139 					     irq * data->n_words + idx);
140 		} else {
141 			l1_data->irq_map_mask[idx] = 0xffffffff;
142 		}
143 		valid_mask[idx] |= l1_data->irq_map_mask[idx];
144 	}
145 
146 	l1_data->b = data;
147 
148 	irq_set_chained_handler_and_data(parent_irq,
149 					 bcm7120_l2_intc_irq_handle, l1_data);
150 	return 0;
151 }
152 
153 static int __init bcm7120_l2_intc_iomap_7120(struct device_node *dn,
154 					     struct bcm7120_l2_intc_data *data)
155 {
156 	int ret;
157 
158 	data->map_base[0] = of_iomap(dn, 0);
159 	if (!data->map_base[0]) {
160 		pr_err("unable to map registers\n");
161 		return -ENOMEM;
162 	}
163 
164 	data->pair_base[0] = data->map_base[0];
165 	data->en_offset[0] = IRQEN;
166 	data->stat_offset[0] = IRQSTAT;
167 	data->n_words = 1;
168 
169 	ret = of_property_read_u32_array(dn, "brcm,int-fwd-mask",
170 					 data->irq_fwd_mask, data->n_words);
171 	if (ret != 0 && ret != -EINVAL) {
172 		/* property exists but has the wrong number of words */
173 		pr_err("invalid brcm,int-fwd-mask property\n");
174 		return -EINVAL;
175 	}
176 
177 	data->map_mask_prop = of_get_property(dn, "brcm,int-map-mask", &ret);
178 	if (!data->map_mask_prop ||
179 	    (ret != (sizeof(__be32) * data->num_parent_irqs * data->n_words))) {
180 		pr_err("invalid brcm,int-map-mask property\n");
181 		return -EINVAL;
182 	}
183 
184 	return 0;
185 }
186 
187 static int __init bcm7120_l2_intc_iomap_3380(struct device_node *dn,
188 					     struct bcm7120_l2_intc_data *data)
189 {
190 	unsigned int gc_idx;
191 
192 	for (gc_idx = 0; gc_idx < MAX_WORDS; gc_idx++) {
193 		unsigned int map_idx = gc_idx * 2;
194 		void __iomem *en = of_iomap(dn, map_idx + 0);
195 		void __iomem *stat = of_iomap(dn, map_idx + 1);
196 		void __iomem *base = min(en, stat);
197 
198 		data->map_base[map_idx + 0] = en;
199 		data->map_base[map_idx + 1] = stat;
200 
201 		if (!base)
202 			break;
203 
204 		data->pair_base[gc_idx] = base;
205 		data->en_offset[gc_idx] = en - base;
206 		data->stat_offset[gc_idx] = stat - base;
207 	}
208 
209 	if (!gc_idx) {
210 		pr_err("unable to map registers\n");
211 		return -EINVAL;
212 	}
213 
214 	data->n_words = gc_idx;
215 	return 0;
216 }
217 
218 int __init bcm7120_l2_intc_probe(struct device_node *dn,
219 				 struct device_node *parent,
220 				 int (*iomap_regs_fn)(struct device_node *,
221 					struct bcm7120_l2_intc_data *),
222 				 const char *intc_name)
223 {
224 	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
225 	struct bcm7120_l2_intc_data *data;
226 	struct irq_chip_generic *gc;
227 	struct irq_chip_type *ct;
228 	int ret = 0;
229 	unsigned int idx, irq, flags;
230 	u32 valid_mask[MAX_WORDS] = { };
231 
232 	data = kzalloc(sizeof(*data), GFP_KERNEL);
233 	if (!data)
234 		return -ENOMEM;
235 
236 	data->num_parent_irqs = of_irq_count(dn);
237 	if (data->num_parent_irqs <= 0) {
238 		pr_err("invalid number of parent interrupts\n");
239 		ret = -ENOMEM;
240 		goto out_unmap;
241 	}
242 
243 	data->l1_data = kcalloc(data->num_parent_irqs, sizeof(*data->l1_data),
244 				GFP_KERNEL);
245 	if (!data->l1_data) {
246 		ret = -ENOMEM;
247 		goto out_free_l1_data;
248 	}
249 
250 	ret = iomap_regs_fn(dn, data);
251 	if (ret < 0)
252 		goto out_free_l1_data;
253 
254 	for (idx = 0; idx < data->n_words; idx++) {
255 		__raw_writel(data->irq_fwd_mask[idx],
256 			     data->pair_base[idx] +
257 			     data->en_offset[idx]);
258 	}
259 
260 	for (irq = 0; irq < data->num_parent_irqs; irq++) {
261 		ret = bcm7120_l2_intc_init_one(dn, data, irq, valid_mask);
262 		if (ret)
263 			goto out_free_l1_data;
264 	}
265 
266 	data->domain = irq_domain_add_linear(dn, IRQS_PER_WORD * data->n_words,
267 					     &irq_generic_chip_ops, NULL);
268 	if (!data->domain) {
269 		ret = -ENOMEM;
270 		goto out_free_l1_data;
271 	}
272 
273 	/* MIPS chips strapped for BE will automagically configure the
274 	 * peripheral registers for CPU-native byte order.
275 	 */
276 	flags = IRQ_GC_INIT_MASK_CACHE;
277 	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
278 		flags |= IRQ_GC_BE_IO;
279 
280 	ret = irq_alloc_domain_generic_chips(data->domain, IRQS_PER_WORD, 1,
281 				dn->full_name, handle_level_irq, clr, 0, flags);
282 	if (ret) {
283 		pr_err("failed to allocate generic irq chip\n");
284 		goto out_free_domain;
285 	}
286 
287 	if (of_property_read_bool(dn, "brcm,irq-can-wake"))
288 		data->can_wake = true;
289 
290 	for (idx = 0; idx < data->n_words; idx++) {
291 		irq = idx * IRQS_PER_WORD;
292 		gc = irq_get_domain_generic_chip(data->domain, irq);
293 
294 		gc->unused = 0xffffffff & ~valid_mask[idx];
295 		gc->private = data;
296 		ct = gc->chip_types;
297 
298 		gc->reg_base = data->pair_base[idx];
299 		ct->regs.mask = data->en_offset[idx];
300 
301 		ct->chip.irq_mask = irq_gc_mask_clr_bit;
302 		ct->chip.irq_unmask = irq_gc_mask_set_bit;
303 		ct->chip.irq_ack = irq_gc_noop;
304 		gc->suspend = bcm7120_l2_intc_suspend;
305 		gc->resume = bcm7120_l2_intc_resume;
306 
307 		/*
308 		 * Initialize mask-cache, in case we need it for
309 		 * saving/restoring fwd mask even w/o any child interrupts
310 		 * installed
311 		 */
312 		gc->mask_cache = irq_reg_readl(gc, ct->regs.mask);
313 
314 		if (data->can_wake) {
315 			/* This IRQ chip can wake the system, set all
316 			 * relevant child interupts in wake_enabled mask
317 			 */
318 			gc->wake_enabled = 0xffffffff;
319 			gc->wake_enabled &= ~gc->unused;
320 			ct->chip.irq_set_wake = irq_gc_set_wake;
321 		}
322 	}
323 
324 	pr_info("registered %s intc (mem: 0x%p, parent IRQ(s): %d)\n",
325 			intc_name, data->map_base[0], data->num_parent_irqs);
326 
327 	return 0;
328 
329 out_free_domain:
330 	irq_domain_remove(data->domain);
331 out_free_l1_data:
332 	kfree(data->l1_data);
333 out_unmap:
334 	for (idx = 0; idx < MAX_MAPPINGS; idx++) {
335 		if (data->map_base[idx])
336 			iounmap(data->map_base[idx]);
337 	}
338 	kfree(data);
339 	return ret;
340 }
341 
342 int __init bcm7120_l2_intc_probe_7120(struct device_node *dn,
343 				      struct device_node *parent)
344 {
345 	return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_7120,
346 				     "BCM7120 L2");
347 }
348 
349 int __init bcm7120_l2_intc_probe_3380(struct device_node *dn,
350 				      struct device_node *parent)
351 {
352 	return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_3380,
353 				     "BCM3380 L2");
354 }
355 
356 IRQCHIP_DECLARE(bcm7120_l2_intc, "brcm,bcm7120-l2-intc",
357 		bcm7120_l2_intc_probe_7120);
358 
359 IRQCHIP_DECLARE(bcm3380_l2_intc, "brcm,bcm3380-l2-intc",
360 		bcm7120_l2_intc_probe_3380);
361