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