1  // SPDX-License-Identifier: GPL-2.0-only
2  /*
3   * Copyright (C) 2020 Birger Koblitz <mail@birger-koblitz.de>
4   * Copyright (C) 2020 Bert Vermeulen <bert@biot.com>
5   * Copyright (C) 2020 John Crispin <john@phrozen.org>
6   */
7  
8  #include <linux/of_irq.h>
9  #include <linux/irqchip.h>
10  #include <linux/spinlock.h>
11  #include <linux/of_address.h>
12  #include <linux/irqchip/chained_irq.h>
13  
14  /* Global Interrupt Mask Register */
15  #define RTL_ICTL_GIMR		0x00
16  /* Global Interrupt Status Register */
17  #define RTL_ICTL_GISR		0x04
18  /* Interrupt Routing Registers */
19  #define RTL_ICTL_IRR0		0x08
20  #define RTL_ICTL_IRR1		0x0c
21  #define RTL_ICTL_IRR2		0x10
22  #define RTL_ICTL_IRR3		0x14
23  
24  #define RTL_ICTL_NUM_INPUTS	32
25  
26  #define REG(x)		(realtek_ictl_base + x)
27  
28  static DEFINE_RAW_SPINLOCK(irq_lock);
29  static void __iomem *realtek_ictl_base;
30  
31  /*
32   * IRR0-IRR3 store 4 bits per interrupt, but Realtek uses inverted numbering,
33   * placing IRQ 31 in the first four bits. A routing value of '0' means the
34   * interrupt is left disconnected. Routing values {1..15} connect to output
35   * lines {0..14}.
36   */
37  #define IRR_OFFSET(idx)		(4 * (3 - (idx * 4) / 32))
38  #define IRR_SHIFT(idx)		((idx * 4) % 32)
39  
write_irr(void __iomem * irr0,int idx,u32 value)40  static void write_irr(void __iomem *irr0, int idx, u32 value)
41  {
42  	unsigned int offset = IRR_OFFSET(idx);
43  	unsigned int shift = IRR_SHIFT(idx);
44  	u32 irr;
45  
46  	irr = readl(irr0 + offset) & ~(0xf << shift);
47  	irr |= (value & 0xf) << shift;
48  	writel(irr, irr0 + offset);
49  }
50  
realtek_ictl_unmask_irq(struct irq_data * i)51  static void realtek_ictl_unmask_irq(struct irq_data *i)
52  {
53  	unsigned long flags;
54  	u32 value;
55  
56  	raw_spin_lock_irqsave(&irq_lock, flags);
57  
58  	value = readl(REG(RTL_ICTL_GIMR));
59  	value |= BIT(i->hwirq);
60  	writel(value, REG(RTL_ICTL_GIMR));
61  
62  	raw_spin_unlock_irqrestore(&irq_lock, flags);
63  }
64  
realtek_ictl_mask_irq(struct irq_data * i)65  static void realtek_ictl_mask_irq(struct irq_data *i)
66  {
67  	unsigned long flags;
68  	u32 value;
69  
70  	raw_spin_lock_irqsave(&irq_lock, flags);
71  
72  	value = readl(REG(RTL_ICTL_GIMR));
73  	value &= ~BIT(i->hwirq);
74  	writel(value, REG(RTL_ICTL_GIMR));
75  
76  	raw_spin_unlock_irqrestore(&irq_lock, flags);
77  }
78  
79  static struct irq_chip realtek_ictl_irq = {
80  	.name = "realtek-rtl-intc",
81  	.irq_mask = realtek_ictl_mask_irq,
82  	.irq_unmask = realtek_ictl_unmask_irq,
83  };
84  
intc_map(struct irq_domain * d,unsigned int irq,irq_hw_number_t hw)85  static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
86  {
87  	unsigned long flags;
88  
89  	irq_set_chip_and_handler(irq, &realtek_ictl_irq, handle_level_irq);
90  
91  	raw_spin_lock_irqsave(&irq_lock, flags);
92  	write_irr(REG(RTL_ICTL_IRR0), hw, 1);
93  	raw_spin_unlock_irqrestore(&irq_lock, flags);
94  
95  	return 0;
96  }
97  
98  static const struct irq_domain_ops irq_domain_ops = {
99  	.map = intc_map,
100  	.xlate = irq_domain_xlate_onecell,
101  };
102  
realtek_irq_dispatch(struct irq_desc * desc)103  static void realtek_irq_dispatch(struct irq_desc *desc)
104  {
105  	struct irq_chip *chip = irq_desc_get_chip(desc);
106  	struct irq_domain *domain;
107  	unsigned long pending;
108  	unsigned int soc_int;
109  
110  	chained_irq_enter(chip, desc);
111  	pending = readl(REG(RTL_ICTL_GIMR)) & readl(REG(RTL_ICTL_GISR));
112  
113  	if (unlikely(!pending)) {
114  		spurious_interrupt();
115  		goto out;
116  	}
117  
118  	domain = irq_desc_get_handler_data(desc);
119  	for_each_set_bit(soc_int, &pending, 32)
120  		generic_handle_domain_irq(domain, soc_int);
121  
122  out:
123  	chained_irq_exit(chip, desc);
124  }
125  
realtek_rtl_of_init(struct device_node * node,struct device_node * parent)126  static int __init realtek_rtl_of_init(struct device_node *node, struct device_node *parent)
127  {
128  	struct of_phandle_args oirq;
129  	struct irq_domain *domain;
130  	unsigned int soc_irq;
131  	int parent_irq;
132  
133  	realtek_ictl_base = of_iomap(node, 0);
134  	if (!realtek_ictl_base)
135  		return -ENXIO;
136  
137  	/* Disable all cascaded interrupts and clear routing */
138  	writel(0, REG(RTL_ICTL_GIMR));
139  	for (soc_irq = 0; soc_irq < RTL_ICTL_NUM_INPUTS; soc_irq++)
140  		write_irr(REG(RTL_ICTL_IRR0), soc_irq, 0);
141  
142  	if (WARN_ON(!of_irq_count(node))) {
143  		/*
144  		 * If DT contains no parent interrupts, assume MIPS CPU IRQ 2
145  		 * (HW0) is connected to the first output. This is the case for
146  		 * all known hardware anyway. "interrupt-map" is deprecated, so
147  		 * don't bother trying to parse that.
148  		 */
149  		oirq.np = of_find_compatible_node(NULL, NULL, "mti,cpu-interrupt-controller");
150  		oirq.args_count = 1;
151  		oirq.args[0] = 2;
152  
153  		parent_irq = irq_create_of_mapping(&oirq);
154  
155  		of_node_put(oirq.np);
156  	} else {
157  		parent_irq = of_irq_get(node, 0);
158  	}
159  
160  	if (parent_irq < 0)
161  		return parent_irq;
162  	else if (!parent_irq)
163  		return -ENODEV;
164  
165  	domain = irq_domain_add_linear(node, RTL_ICTL_NUM_INPUTS, &irq_domain_ops, NULL);
166  	if (!domain)
167  		return -ENOMEM;
168  
169  	irq_set_chained_handler_and_data(parent_irq, realtek_irq_dispatch, domain);
170  
171  	return 0;
172  }
173  
174  IRQCHIP_DECLARE(realtek_rtl_intc, "realtek,rtl-intc", realtek_rtl_of_init);
175