realtek: refresh patches in 5.15
[openwrt/staging/jow.git] / target / linux / realtek / patches-5.15 / 317-gpio-realtek-otto-switch-to-32-bit-I-O.patch
1 From ee0175b3b44288c74d5292c2a9c2c154f6c0317e Mon Sep 17 00:00:00 2001
2 From: Sander Vanheule <sander@svanheule.net>
3 Date: Sun, 7 Aug 2022 21:21:15 +0200
4 Subject: [PATCH] gpio: realtek-otto: switch to 32-bit I/O
5
6 By using 16-bit I/O on the GPIO peripheral, which is apparently not safe
7 on MIPS, the IMR can end up containing garbage. This then results in
8 interrupt triggers for lines that don't have an interrupt handler
9 associated. The irq_desc lookup fails, and the ISR will not be cleared,
10 keeping the CPU busy until reboot, or until another IMR operation
11 restores the correct value. This situation appears to happen very
12 rarely, for < 0.5% of IMR writes.
13
14 Instead of using 8-bit or 16-bit I/O operations on the 32-bit memory
15 mapped peripheral registers, switch to using 32-bit I/O only, operating
16 on the entire bank for all single bit line settings. For 2-bit line
17 settings, with 16-bit port values, stick to manual (un)packing.
18
19 This issue has been seen on RTL8382M (HPE 1920-16G), RTL8391M (Netgear
20 GS728TP v2), and RTL8393M (D-Link DGS-1210-52 F3, Zyxel GS1900-48).
21
22 Reported-by: Luiz Angelo Daros de Luca <luizluca@gmail.com> # DGS-1210-52
23 Reported-by: Birger Koblitz <mail@birger-koblitz.de> # GS728TP
24 Reported-by: Jan Hoffmann <jan@3e8.eu> # 1920-16G
25 Fixes: 0d82fb1127fb ("gpio: Add Realtek Otto GPIO support")
26 Signed-off-by: Sander Vanheule <sander@svanheule.net>
27 Cc: Paul Cercueil <paul@crapouillou.net>
28 Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
29 Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
30
31 Update patch for missing upstream changes:
32 - commit a01a40e33499 ("gpio: realtek-otto: Make the irqchip immutable")
33 Signed-off-by: Sander Vanheule <sander@svanheule.net>
34
35 ---
36 drivers/gpio/gpio-realtek-otto.c | 166 ++++++++++++++++---------------
37 1 file changed, 85 insertions(+), 81 deletions(-)
38
39 --- a/drivers/gpio/gpio-realtek-otto.c
40 +++ b/drivers/gpio/gpio-realtek-otto.c
41 @@ -46,10 +46,20 @@
42 * @lock: Lock for accessing the IRQ registers and values
43 * @intr_mask: Mask for interrupts lines
44 * @intr_type: Interrupt type selection
45 + * @bank_read: Read a bank setting as a single 32-bit value
46 + * @bank_write: Write a bank setting as a single 32-bit value
47 + * @imr_line_pos: Bit shift of an IRQ line's IMR value.
48 + *
49 + * The DIR, DATA, and ISR registers consist of four 8-bit port values, packed
50 + * into a single 32-bit register. Use @bank_read (@bank_write) to get (assign)
51 + * a value from (to) these registers. The IMR register consists of four 16-bit
52 + * port values, packed into two 32-bit registers. Use @imr_line_pos to get the
53 + * bit shift of the 2-bit field for a line's IMR settings. Shifts larger than
54 + * 32 overflow into the second register.
55 *
56 * Because the interrupt mask register (IMR) combines the function of IRQ type
57 * selection and masking, two extra values are stored. @intr_mask is used to
58 - * mask/unmask the interrupts for a GPIO port, and @intr_type is used to store
59 + * mask/unmask the interrupts for a GPIO line, and @intr_type is used to store
60 * the selected interrupt types. The logical AND of these values is written to
61 * IMR on changes.
62 */
63 @@ -59,10 +69,11 @@ struct realtek_gpio_ctrl {
64 void __iomem *cpumask_base;
65 struct cpumask cpu_irq_maskable;
66 raw_spinlock_t lock;
67 - u16 intr_mask[REALTEK_GPIO_PORTS_PER_BANK];
68 - u16 intr_type[REALTEK_GPIO_PORTS_PER_BANK];
69 - unsigned int (*port_offset_u8)(unsigned int port);
70 - unsigned int (*port_offset_u16)(unsigned int port);
71 + u8 intr_mask[REALTEK_GPIO_MAX];
72 + u8 intr_type[REALTEK_GPIO_MAX];
73 + u32 (*bank_read)(void __iomem *reg);
74 + void (*bank_write)(void __iomem *reg, u32 value);
75 + unsigned int (*line_imr_pos)(unsigned int line);
76 };
77
78 /* Expand with more flags as devices with other quirks are added */
79 @@ -101,14 +112,22 @@ static struct realtek_gpio_ctrl *irq_dat
80 * port. The two interrupt mask registers store two bits per GPIO, so use u16
81 * values.
82 */
83 -static unsigned int realtek_gpio_port_offset_u8(unsigned int port)
84 +static u32 realtek_gpio_bank_read_swapped(void __iomem *reg)
85 +{
86 + return ioread32be(reg);
87 +}
88 +
89 +static void realtek_gpio_bank_write_swapped(void __iomem *reg, u32 value)
90 {
91 - return port;
92 + iowrite32be(value, reg);
93 }
94
95 -static unsigned int realtek_gpio_port_offset_u16(unsigned int port)
96 +static unsigned int realtek_gpio_line_imr_pos_swapped(unsigned int line)
97 {
98 - return 2 * port;
99 + unsigned int port_pin = line % 8;
100 + unsigned int port = line / 8;
101 +
102 + return 2 * (8 * (port ^ 1) + port_pin);
103 }
104
105 /*
106 @@ -119,64 +138,65 @@ static unsigned int realtek_gpio_port_of
107 * per GPIO, so use u16 values. The first register contains ports 1 and 0, the
108 * second ports 3 and 2.
109 */
110 -static unsigned int realtek_gpio_port_offset_u8_rev(unsigned int port)
111 +static u32 realtek_gpio_bank_read(void __iomem *reg)
112 {
113 - return 3 - port;
114 + return ioread32(reg);
115 }
116
117 -static unsigned int realtek_gpio_port_offset_u16_rev(unsigned int port)
118 +static void realtek_gpio_bank_write(void __iomem *reg, u32 value)
119 {
120 - return 2 * (port ^ 1);
121 + iowrite32(value, reg);
122 }
123
124 -static void realtek_gpio_write_imr(struct realtek_gpio_ctrl *ctrl,
125 - unsigned int port, u16 irq_type, u16 irq_mask)
126 +static unsigned int realtek_gpio_line_imr_pos(unsigned int line)
127 {
128 - iowrite16(irq_type & irq_mask,
129 - ctrl->base + REALTEK_GPIO_REG_IMR + ctrl->port_offset_u16(port));
130 + return 2 * line;
131 }
132
133 -static void realtek_gpio_clear_isr(struct realtek_gpio_ctrl *ctrl,
134 - unsigned int port, u8 mask)
135 +static void realtek_gpio_clear_isr(struct realtek_gpio_ctrl *ctrl, u32 mask)
136 {
137 - iowrite8(mask, ctrl->base + REALTEK_GPIO_REG_ISR + ctrl->port_offset_u8(port));
138 + ctrl->bank_write(ctrl->base + REALTEK_GPIO_REG_ISR, mask);
139 }
140
141 -static u8 realtek_gpio_read_isr(struct realtek_gpio_ctrl *ctrl, unsigned int port)
142 +static u32 realtek_gpio_read_isr(struct realtek_gpio_ctrl *ctrl)
143 {
144 - return ioread8(ctrl->base + REALTEK_GPIO_REG_ISR + ctrl->port_offset_u8(port));
145 + return ctrl->bank_read(ctrl->base + REALTEK_GPIO_REG_ISR);
146 }
147
148 -/* Set the rising and falling edge mask bits for a GPIO port pin */
149 -static u16 realtek_gpio_imr_bits(unsigned int pin, u16 value)
150 +/* Set the rising and falling edge mask bits for a GPIO pin */
151 +static void realtek_gpio_update_line_imr(struct realtek_gpio_ctrl *ctrl, unsigned int line)
152 {
153 - return (value & REALTEK_GPIO_IMR_LINE_MASK) << 2 * pin;
154 + void __iomem *reg = ctrl->base + REALTEK_GPIO_REG_IMR;
155 + unsigned int line_shift = ctrl->line_imr_pos(line);
156 + unsigned int shift = line_shift % 32;
157 + u32 irq_type = ctrl->intr_type[line];
158 + u32 irq_mask = ctrl->intr_mask[line];
159 + u32 reg_val;
160 +
161 + reg += 4 * (line_shift / 32);
162 + reg_val = ioread32(reg);
163 + reg_val &= ~(REALTEK_GPIO_IMR_LINE_MASK << shift);
164 + reg_val |= (irq_type & irq_mask & REALTEK_GPIO_IMR_LINE_MASK) << shift;
165 + iowrite32(reg_val, reg);
166 }
167
168 static void realtek_gpio_irq_ack(struct irq_data *data)
169 {
170 struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);
171 irq_hw_number_t line = irqd_to_hwirq(data);
172 - unsigned int port = line / 8;
173 - unsigned int port_pin = line % 8;
174
175 - realtek_gpio_clear_isr(ctrl, port, BIT(port_pin));
176 + realtek_gpio_clear_isr(ctrl, BIT(line));
177 }
178
179 static void realtek_gpio_irq_unmask(struct irq_data *data)
180 {
181 struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);
182 unsigned int line = irqd_to_hwirq(data);
183 - unsigned int port = line / 8;
184 - unsigned int port_pin = line % 8;
185 unsigned long flags;
186 - u16 m;
187
188 raw_spin_lock_irqsave(&ctrl->lock, flags);
189 - m = ctrl->intr_mask[port];
190 - m |= realtek_gpio_imr_bits(port_pin, REALTEK_GPIO_IMR_LINE_MASK);
191 - ctrl->intr_mask[port] = m;
192 - realtek_gpio_write_imr(ctrl, port, ctrl->intr_type[port], m);
193 + ctrl->intr_mask[line] = REALTEK_GPIO_IMR_LINE_MASK;
194 + realtek_gpio_update_line_imr(ctrl, line);
195 raw_spin_unlock_irqrestore(&ctrl->lock, flags);
196 }
197
198 @@ -184,16 +204,11 @@ static void realtek_gpio_irq_mask(struct
199 {
200 struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);
201 unsigned int line = irqd_to_hwirq(data);
202 - unsigned int port = line / 8;
203 - unsigned int port_pin = line % 8;
204 unsigned long flags;
205 - u16 m;
206
207 raw_spin_lock_irqsave(&ctrl->lock, flags);
208 - m = ctrl->intr_mask[port];
209 - m &= ~realtek_gpio_imr_bits(port_pin, REALTEK_GPIO_IMR_LINE_MASK);
210 - ctrl->intr_mask[port] = m;
211 - realtek_gpio_write_imr(ctrl, port, ctrl->intr_type[port], m);
212 + ctrl->intr_mask[line] = 0;
213 + realtek_gpio_update_line_imr(ctrl, line);
214 raw_spin_unlock_irqrestore(&ctrl->lock, flags);
215 }
216
217 @@ -201,10 +216,8 @@ static int realtek_gpio_irq_set_type(str
218 {
219 struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);
220 unsigned int line = irqd_to_hwirq(data);
221 - unsigned int port = line / 8;
222 - unsigned int port_pin = line % 8;
223 unsigned long flags;
224 - u16 type, t;
225 + u8 type;
226
227 switch (flow_type & IRQ_TYPE_SENSE_MASK) {
228 case IRQ_TYPE_EDGE_FALLING:
229 @@ -223,11 +236,8 @@ static int realtek_gpio_irq_set_type(str
230 irq_set_handler_locked(data, handle_edge_irq);
231
232 raw_spin_lock_irqsave(&ctrl->lock, flags);
233 - t = ctrl->intr_type[port];
234 - t &= ~realtek_gpio_imr_bits(port_pin, REALTEK_GPIO_IMR_LINE_MASK);
235 - t |= realtek_gpio_imr_bits(port_pin, type);
236 - ctrl->intr_type[port] = t;
237 - realtek_gpio_write_imr(ctrl, port, t, ctrl->intr_mask[port]);
238 + ctrl->intr_type[line] = type;
239 + realtek_gpio_update_line_imr(ctrl, line);
240 raw_spin_unlock_irqrestore(&ctrl->lock, flags);
241
242 return 0;
243 @@ -238,28 +248,21 @@ static void realtek_gpio_irq_handler(str
244 struct gpio_chip *gc = irq_desc_get_handler_data(desc);
245 struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc);
246 struct irq_chip *irq_chip = irq_desc_get_chip(desc);
247 - unsigned int lines_done;
248 - unsigned int port_pin_count;
249 unsigned long status;
250 int offset;
251
252 chained_irq_enter(irq_chip, desc);
253
254 - for (lines_done = 0; lines_done < gc->ngpio; lines_done += 8) {
255 - status = realtek_gpio_read_isr(ctrl, lines_done / 8);
256 - port_pin_count = min(gc->ngpio - lines_done, 8U);
257 - for_each_set_bit(offset, &status, port_pin_count)
258 - generic_handle_domain_irq(gc->irq.domain, offset + lines_done);
259 - }
260 + status = realtek_gpio_read_isr(ctrl);
261 + for_each_set_bit(offset, &status, gc->ngpio)
262 + generic_handle_domain_irq(gc->irq.domain, offset);
263
264 chained_irq_exit(irq_chip, desc);
265 }
266
267 -static inline void __iomem *realtek_gpio_irq_cpu_mask(struct realtek_gpio_ctrl *ctrl,
268 - unsigned int port, int cpu)
269 +static inline void __iomem *realtek_gpio_irq_cpu_mask(struct realtek_gpio_ctrl *ctrl, int cpu)
270 {
271 - return ctrl->cpumask_base + ctrl->port_offset_u8(port) +
272 - REALTEK_GPIO_PORTS_PER_BANK * cpu;
273 + return ctrl->cpumask_base + REALTEK_GPIO_PORTS_PER_BANK * cpu;
274 }
275
276 static int realtek_gpio_irq_set_affinity(struct irq_data *data,
277 @@ -267,12 +270,10 @@ static int realtek_gpio_irq_set_affinity
278 {
279 struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);
280 unsigned int line = irqd_to_hwirq(data);
281 - unsigned int port = line / 8;
282 - unsigned int port_pin = line % 8;
283 void __iomem *irq_cpu_mask;
284 unsigned long flags;
285 int cpu;
286 - u8 v;
287 + u32 v;
288
289 if (!ctrl->cpumask_base)
290 return -ENXIO;
291 @@ -280,15 +281,15 @@ static int realtek_gpio_irq_set_affinity
292 raw_spin_lock_irqsave(&ctrl->lock, flags);
293
294 for_each_cpu(cpu, &ctrl->cpu_irq_maskable) {
295 - irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, port, cpu);
296 - v = ioread8(irq_cpu_mask);
297 + irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, cpu);
298 + v = ctrl->bank_read(irq_cpu_mask);
299
300 if (cpumask_test_cpu(cpu, dest))
301 - v |= BIT(port_pin);
302 + v |= BIT(line);
303 else
304 - v &= ~BIT(port_pin);
305 + v &= ~BIT(line);
306
307 - iowrite8(v, irq_cpu_mask);
308 + ctrl->bank_write(irq_cpu_mask, v);
309 }
310
311 raw_spin_unlock_irqrestore(&ctrl->lock, flags);
312 @@ -302,22 +303,23 @@ static int realtek_gpio_irq_init(struct
313 {
314 struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc);
315 void __iomem *irq_cpu_mask;
316 - unsigned int port;
317 + u32 mask_all = GENMASK(gc->ngpio - 1, 0);
318 + unsigned int line;
319 int cpu;
320
321 - for (port = 0; (port * 8) < gc->ngpio; port++) {
322 - realtek_gpio_write_imr(ctrl, port, 0, 0);
323 - realtek_gpio_clear_isr(ctrl, port, GENMASK(7, 0));
324 -
325 - /*
326 - * Uniprocessor builds assume a mask always contains one CPU,
327 - * so only start the loop if we have at least one maskable CPU.
328 - */
329 - if(!cpumask_empty(&ctrl->cpu_irq_maskable)) {
330 - for_each_cpu(cpu, &ctrl->cpu_irq_maskable) {
331 - irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, port, cpu);
332 - iowrite8(GENMASK(7, 0), irq_cpu_mask);
333 - }
334 + for (line = 0; line < gc->ngpio; line++)
335 + realtek_gpio_update_line_imr(ctrl, line);
336 +
337 + realtek_gpio_clear_isr(ctrl, mask_all);
338 +
339 + /*
340 + * Uniprocessor builds assume a mask always contains one CPU,
341 + * so only start the loop if we have at least one maskable CPU.
342 + */
343 + if(!cpumask_empty(&ctrl->cpu_irq_maskable)) {
344 + for_each_cpu(cpu, &ctrl->cpu_irq_maskable) {
345 + irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, cpu);
346 + ctrl->bank_write(irq_cpu_mask, mask_all);
347 }
348 }
349
350 @@ -390,12 +392,14 @@ static int realtek_gpio_probe(struct pla
351
352 if (dev_flags & GPIO_PORTS_REVERSED) {
353 bgpio_flags = 0;
354 - ctrl->port_offset_u8 = realtek_gpio_port_offset_u8_rev;
355 - ctrl->port_offset_u16 = realtek_gpio_port_offset_u16_rev;
356 + ctrl->bank_read = realtek_gpio_bank_read;
357 + ctrl->bank_write = realtek_gpio_bank_write;
358 + ctrl->line_imr_pos = realtek_gpio_line_imr_pos;
359 } else {
360 bgpio_flags = BGPIOF_BIG_ENDIAN_BYTE_ORDER;
361 - ctrl->port_offset_u8 = realtek_gpio_port_offset_u8;
362 - ctrl->port_offset_u16 = realtek_gpio_port_offset_u16;
363 + ctrl->bank_read = realtek_gpio_bank_read_swapped;
364 + ctrl->bank_write = realtek_gpio_bank_write_swapped;
365 + ctrl->line_imr_pos = realtek_gpio_line_imr_pos_swapped;
366 }
367
368 err = bgpio_init(&ctrl->gc, dev, 4,