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