1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | |
3 | #include <linux/gpio/driver.h> |
4 | #include <linux/cpumask.h> |
5 | #include <linux/irq.h> |
6 | #include <linux/minmax.h> |
7 | #include <linux/mod_devicetable.h> |
8 | #include <linux/module.h> |
9 | #include <linux/platform_device.h> |
10 | #include <linux/property.h> |
11 | |
12 | /* |
13 | * Total register block size is 0x1C for one bank of four ports (A, B, C, D). |
14 | * An optional second bank, with ports E, F, G, and H, may be present, starting |
15 | * at register offset 0x1C. |
16 | */ |
17 | |
18 | /* |
19 | * Pin select: (0) "normal", (1) "dedicate peripheral" |
20 | * Not used on RTL8380/RTL8390, peripheral selection is managed by control bits |
21 | * in the peripheral registers. |
22 | */ |
23 | #define REALTEK_GPIO_REG_CNR 0x00 |
24 | /* Clear bit (0) for input, set bit (1) for output */ |
25 | #define REALTEK_GPIO_REG_DIR 0x08 |
26 | #define REALTEK_GPIO_REG_DATA 0x0C |
27 | /* Read bit for IRQ status, write 1 to clear IRQ */ |
28 | #define REALTEK_GPIO_REG_ISR 0x10 |
29 | /* Two bits per GPIO in IMR registers */ |
30 | #define REALTEK_GPIO_REG_IMR 0x14 |
31 | #define REALTEK_GPIO_REG_IMR_AB 0x14 |
32 | #define REALTEK_GPIO_REG_IMR_CD 0x18 |
33 | #define REALTEK_GPIO_IMR_LINE_MASK GENMASK(1, 0) |
34 | #define REALTEK_GPIO_IRQ_EDGE_FALLING 1 |
35 | #define REALTEK_GPIO_IRQ_EDGE_RISING 2 |
36 | #define REALTEK_GPIO_IRQ_EDGE_BOTH 3 |
37 | |
38 | #define REALTEK_GPIO_MAX 32 |
39 | #define REALTEK_GPIO_PORTS_PER_BANK 4 |
40 | |
41 | /** |
42 | * realtek_gpio_ctrl - Realtek Otto GPIO driver data |
43 | * |
44 | * @gc: Associated gpio_chip instance |
45 | * @base: Base address of the register block for a GPIO bank |
46 | * @lock: Lock for accessing the IRQ registers and values |
47 | * @intr_mask: Mask for interrupts lines |
48 | * @intr_type: Interrupt type selection |
49 | * @bank_read: Read a bank setting as a single 32-bit value |
50 | * @bank_write: Write a bank setting as a single 32-bit value |
51 | * @imr_line_pos: Bit shift of an IRQ line's IMR value. |
52 | * |
53 | * The DIR, DATA, and ISR registers consist of four 8-bit port values, packed |
54 | * into a single 32-bit register. Use @bank_read (@bank_write) to get (assign) |
55 | * a value from (to) these registers. The IMR register consists of four 16-bit |
56 | * port values, packed into two 32-bit registers. Use @imr_line_pos to get the |
57 | * bit shift of the 2-bit field for a line's IMR settings. Shifts larger than |
58 | * 32 overflow into the second register. |
59 | * |
60 | * Because the interrupt mask register (IMR) combines the function of IRQ type |
61 | * selection and masking, two extra values are stored. @intr_mask is used to |
62 | * mask/unmask the interrupts for a GPIO line, and @intr_type is used to store |
63 | * the selected interrupt types. The logical AND of these values is written to |
64 | * IMR on changes. |
65 | */ |
66 | struct realtek_gpio_ctrl { |
67 | struct gpio_chip gc; |
68 | void __iomem *base; |
69 | void __iomem *cpumask_base; |
70 | struct cpumask cpu_irq_maskable; |
71 | raw_spinlock_t lock; |
72 | u8 intr_mask[REALTEK_GPIO_MAX]; |
73 | u8 intr_type[REALTEK_GPIO_MAX]; |
74 | u32 (*bank_read)(void __iomem *reg); |
75 | void (*bank_write)(void __iomem *reg, u32 value); |
76 | unsigned int (*line_imr_pos)(unsigned int line); |
77 | }; |
78 | |
79 | /* Expand with more flags as devices with other quirks are added */ |
80 | enum realtek_gpio_flags { |
81 | /* |
82 | * Allow disabling interrupts, for cases where the port order is |
83 | * unknown. This may result in a port mismatch between ISR and IMR. |
84 | * An interrupt would appear to come from a different line than the |
85 | * line the IRQ handler was assigned to, causing uncaught interrupts. |
86 | */ |
87 | GPIO_INTERRUPTS_DISABLED = BIT(0), |
88 | /* |
89 | * Port order is reversed, meaning DCBA register layout for 1-bit |
90 | * fields, and [BA, DC] for 2-bit fields. |
91 | */ |
92 | GPIO_PORTS_REVERSED = BIT(1), |
93 | /* |
94 | * Interrupts can be enabled per cpu. This requires a secondary IO |
95 | * range, where the per-cpu enable masks are located. |
96 | */ |
97 | GPIO_INTERRUPTS_PER_CPU = BIT(2), |
98 | }; |
99 | |
100 | static struct realtek_gpio_ctrl *irq_data_to_ctrl(struct irq_data *data) |
101 | { |
102 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d: data); |
103 | |
104 | return container_of(gc, struct realtek_gpio_ctrl, gc); |
105 | } |
106 | |
107 | /* |
108 | * Normal port order register access |
109 | * |
110 | * Port information is stored with the first port at offset 0, followed by the |
111 | * second, etc. Most registers store one bit per GPIO and use a u8 value per |
112 | * port. The two interrupt mask registers store two bits per GPIO, so use u16 |
113 | * values. |
114 | */ |
115 | static u32 realtek_gpio_bank_read_swapped(void __iomem *reg) |
116 | { |
117 | return ioread32be(reg); |
118 | } |
119 | |
120 | static void realtek_gpio_bank_write_swapped(void __iomem *reg, u32 value) |
121 | { |
122 | iowrite32be(value, reg); |
123 | } |
124 | |
125 | static unsigned int realtek_gpio_line_imr_pos_swapped(unsigned int line) |
126 | { |
127 | unsigned int port_pin = line % 8; |
128 | unsigned int port = line / 8; |
129 | |
130 | return 2 * (8 * (port ^ 1) + port_pin); |
131 | } |
132 | |
133 | /* |
134 | * Reversed port order register access |
135 | * |
136 | * For registers with one bit per GPIO, all ports are stored as u8-s in one |
137 | * register in reversed order. The two interrupt mask registers store two bits |
138 | * per GPIO, so use u16 values. The first register contains ports 1 and 0, the |
139 | * second ports 3 and 2. |
140 | */ |
141 | static u32 realtek_gpio_bank_read(void __iomem *reg) |
142 | { |
143 | return ioread32(reg); |
144 | } |
145 | |
146 | static void realtek_gpio_bank_write(void __iomem *reg, u32 value) |
147 | { |
148 | iowrite32(value, reg); |
149 | } |
150 | |
151 | static unsigned int realtek_gpio_line_imr_pos(unsigned int line) |
152 | { |
153 | return 2 * line; |
154 | } |
155 | |
156 | static void realtek_gpio_clear_isr(struct realtek_gpio_ctrl *ctrl, u32 mask) |
157 | { |
158 | ctrl->bank_write(ctrl->base + REALTEK_GPIO_REG_ISR, mask); |
159 | } |
160 | |
161 | static u32 realtek_gpio_read_isr(struct realtek_gpio_ctrl *ctrl) |
162 | { |
163 | return ctrl->bank_read(ctrl->base + REALTEK_GPIO_REG_ISR); |
164 | } |
165 | |
166 | /* Set the rising and falling edge mask bits for a GPIO pin */ |
167 | static void realtek_gpio_update_line_imr(struct realtek_gpio_ctrl *ctrl, unsigned int line) |
168 | { |
169 | void __iomem *reg = ctrl->base + REALTEK_GPIO_REG_IMR; |
170 | unsigned int line_shift = ctrl->line_imr_pos(line); |
171 | unsigned int shift = line_shift % 32; |
172 | u32 irq_type = ctrl->intr_type[line]; |
173 | u32 irq_mask = ctrl->intr_mask[line]; |
174 | u32 reg_val; |
175 | |
176 | reg += 4 * (line_shift / 32); |
177 | reg_val = ioread32(reg); |
178 | reg_val &= ~(REALTEK_GPIO_IMR_LINE_MASK << shift); |
179 | reg_val |= (irq_type & irq_mask & REALTEK_GPIO_IMR_LINE_MASK) << shift; |
180 | iowrite32(reg_val, reg); |
181 | } |
182 | |
183 | static void realtek_gpio_irq_ack(struct irq_data *data) |
184 | { |
185 | struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data); |
186 | irq_hw_number_t line = irqd_to_hwirq(d: data); |
187 | |
188 | realtek_gpio_clear_isr(ctrl, BIT(line)); |
189 | } |
190 | |
191 | static void realtek_gpio_irq_unmask(struct irq_data *data) |
192 | { |
193 | struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data); |
194 | unsigned int line = irqd_to_hwirq(d: data); |
195 | unsigned long flags; |
196 | |
197 | gpiochip_enable_irq(gc: &ctrl->gc, offset: line); |
198 | |
199 | raw_spin_lock_irqsave(&ctrl->lock, flags); |
200 | ctrl->intr_mask[line] = REALTEK_GPIO_IMR_LINE_MASK; |
201 | realtek_gpio_update_line_imr(ctrl, line); |
202 | raw_spin_unlock_irqrestore(&ctrl->lock, flags); |
203 | } |
204 | |
205 | static void realtek_gpio_irq_mask(struct irq_data *data) |
206 | { |
207 | struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data); |
208 | unsigned int line = irqd_to_hwirq(d: data); |
209 | unsigned long flags; |
210 | |
211 | raw_spin_lock_irqsave(&ctrl->lock, flags); |
212 | ctrl->intr_mask[line] = 0; |
213 | realtek_gpio_update_line_imr(ctrl, line); |
214 | raw_spin_unlock_irqrestore(&ctrl->lock, flags); |
215 | |
216 | gpiochip_disable_irq(gc: &ctrl->gc, offset: line); |
217 | } |
218 | |
219 | static int realtek_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type) |
220 | { |
221 | struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data); |
222 | unsigned int line = irqd_to_hwirq(d: data); |
223 | unsigned long flags; |
224 | u8 type; |
225 | |
226 | switch (flow_type & IRQ_TYPE_SENSE_MASK) { |
227 | case IRQ_TYPE_EDGE_FALLING: |
228 | type = REALTEK_GPIO_IRQ_EDGE_FALLING; |
229 | break; |
230 | case IRQ_TYPE_EDGE_RISING: |
231 | type = REALTEK_GPIO_IRQ_EDGE_RISING; |
232 | break; |
233 | case IRQ_TYPE_EDGE_BOTH: |
234 | type = REALTEK_GPIO_IRQ_EDGE_BOTH; |
235 | break; |
236 | default: |
237 | return -EINVAL; |
238 | } |
239 | |
240 | irq_set_handler_locked(data, handler: handle_edge_irq); |
241 | |
242 | raw_spin_lock_irqsave(&ctrl->lock, flags); |
243 | ctrl->intr_type[line] = type; |
244 | realtek_gpio_update_line_imr(ctrl, line); |
245 | raw_spin_unlock_irqrestore(&ctrl->lock, flags); |
246 | |
247 | return 0; |
248 | } |
249 | |
250 | static void realtek_gpio_irq_handler(struct irq_desc *desc) |
251 | { |
252 | struct gpio_chip *gc = irq_desc_get_handler_data(desc); |
253 | struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc); |
254 | struct irq_chip *irq_chip = irq_desc_get_chip(desc); |
255 | unsigned long status; |
256 | int offset; |
257 | |
258 | chained_irq_enter(chip: irq_chip, desc); |
259 | |
260 | status = realtek_gpio_read_isr(ctrl); |
261 | for_each_set_bit(offset, &status, gc->ngpio) |
262 | generic_handle_domain_irq(domain: gc->irq.domain, hwirq: offset); |
263 | |
264 | chained_irq_exit(chip: irq_chip, desc); |
265 | } |
266 | |
267 | static inline void __iomem *realtek_gpio_irq_cpu_mask(struct realtek_gpio_ctrl *ctrl, int cpu) |
268 | { |
269 | return ctrl->cpumask_base + REALTEK_GPIO_PORTS_PER_BANK * cpu; |
270 | } |
271 | |
272 | static int realtek_gpio_irq_set_affinity(struct irq_data *data, |
273 | const struct cpumask *dest, bool force) |
274 | { |
275 | struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data); |
276 | unsigned int line = irqd_to_hwirq(d: data); |
277 | void __iomem *irq_cpu_mask; |
278 | unsigned long flags; |
279 | int cpu; |
280 | u32 v; |
281 | |
282 | if (!ctrl->cpumask_base) |
283 | return -ENXIO; |
284 | |
285 | raw_spin_lock_irqsave(&ctrl->lock, flags); |
286 | |
287 | for_each_cpu(cpu, &ctrl->cpu_irq_maskable) { |
288 | irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, cpu); |
289 | v = ctrl->bank_read(irq_cpu_mask); |
290 | |
291 | if (cpumask_test_cpu(cpu, cpumask: dest)) |
292 | v |= BIT(line); |
293 | else |
294 | v &= ~BIT(line); |
295 | |
296 | ctrl->bank_write(irq_cpu_mask, v); |
297 | } |
298 | |
299 | raw_spin_unlock_irqrestore(&ctrl->lock, flags); |
300 | |
301 | irq_data_update_effective_affinity(d: data, m: dest); |
302 | |
303 | return 0; |
304 | } |
305 | |
306 | static int realtek_gpio_irq_init(struct gpio_chip *gc) |
307 | { |
308 | struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc); |
309 | u32 mask_all = GENMASK(gc->ngpio - 1, 0); |
310 | unsigned int line; |
311 | int cpu; |
312 | |
313 | for (line = 0; line < gc->ngpio; line++) |
314 | realtek_gpio_update_line_imr(ctrl, line); |
315 | |
316 | realtek_gpio_clear_isr(ctrl, mask: mask_all); |
317 | |
318 | for_each_cpu(cpu, &ctrl->cpu_irq_maskable) |
319 | ctrl->bank_write(realtek_gpio_irq_cpu_mask(ctrl, cpu), mask_all); |
320 | |
321 | return 0; |
322 | } |
323 | |
324 | static const struct irq_chip realtek_gpio_irq_chip = { |
325 | .name = "realtek-otto-gpio" , |
326 | .irq_ack = realtek_gpio_irq_ack, |
327 | .irq_mask = realtek_gpio_irq_mask, |
328 | .irq_unmask = realtek_gpio_irq_unmask, |
329 | .irq_set_type = realtek_gpio_irq_set_type, |
330 | .irq_set_affinity = realtek_gpio_irq_set_affinity, |
331 | .flags = IRQCHIP_IMMUTABLE, |
332 | GPIOCHIP_IRQ_RESOURCE_HELPERS, |
333 | }; |
334 | |
335 | static const struct of_device_id realtek_gpio_of_match[] = { |
336 | { |
337 | .compatible = "realtek,otto-gpio" , |
338 | .data = (void *)GPIO_INTERRUPTS_DISABLED, |
339 | }, |
340 | { |
341 | .compatible = "realtek,rtl8380-gpio" , |
342 | }, |
343 | { |
344 | .compatible = "realtek,rtl8390-gpio" , |
345 | }, |
346 | { |
347 | .compatible = "realtek,rtl9300-gpio" , |
348 | .data = (void *)(GPIO_PORTS_REVERSED | GPIO_INTERRUPTS_PER_CPU) |
349 | }, |
350 | { |
351 | .compatible = "realtek,rtl9310-gpio" , |
352 | }, |
353 | {} |
354 | }; |
355 | MODULE_DEVICE_TABLE(of, realtek_gpio_of_match); |
356 | |
357 | static int realtek_gpio_probe(struct platform_device *pdev) |
358 | { |
359 | struct device *dev = &pdev->dev; |
360 | unsigned long bgpio_flags; |
361 | unsigned int dev_flags; |
362 | struct gpio_irq_chip *girq; |
363 | struct realtek_gpio_ctrl *ctrl; |
364 | struct resource *res; |
365 | u32 ngpios; |
366 | unsigned int nr_cpus; |
367 | int cpu, err, irq; |
368 | |
369 | ctrl = devm_kzalloc(dev, size: sizeof(*ctrl), GFP_KERNEL); |
370 | if (!ctrl) |
371 | return -ENOMEM; |
372 | |
373 | dev_flags = (unsigned int) device_get_match_data(dev); |
374 | |
375 | ngpios = REALTEK_GPIO_MAX; |
376 | device_property_read_u32(dev, propname: "ngpios" , val: &ngpios); |
377 | |
378 | if (ngpios > REALTEK_GPIO_MAX) { |
379 | dev_err(&pdev->dev, "invalid ngpios (max. %d)\n" , |
380 | REALTEK_GPIO_MAX); |
381 | return -EINVAL; |
382 | } |
383 | |
384 | ctrl->base = devm_platform_ioremap_resource(pdev, index: 0); |
385 | if (IS_ERR(ptr: ctrl->base)) |
386 | return PTR_ERR(ptr: ctrl->base); |
387 | |
388 | raw_spin_lock_init(&ctrl->lock); |
389 | |
390 | if (dev_flags & GPIO_PORTS_REVERSED) { |
391 | bgpio_flags = 0; |
392 | ctrl->bank_read = realtek_gpio_bank_read; |
393 | ctrl->bank_write = realtek_gpio_bank_write; |
394 | ctrl->line_imr_pos = realtek_gpio_line_imr_pos; |
395 | } else { |
396 | bgpio_flags = BGPIOF_BIG_ENDIAN_BYTE_ORDER; |
397 | ctrl->bank_read = realtek_gpio_bank_read_swapped; |
398 | ctrl->bank_write = realtek_gpio_bank_write_swapped; |
399 | ctrl->line_imr_pos = realtek_gpio_line_imr_pos_swapped; |
400 | } |
401 | |
402 | err = bgpio_init(gc: &ctrl->gc, dev, sz: 4, |
403 | dat: ctrl->base + REALTEK_GPIO_REG_DATA, NULL, NULL, |
404 | dirout: ctrl->base + REALTEK_GPIO_REG_DIR, NULL, |
405 | flags: bgpio_flags); |
406 | if (err) { |
407 | dev_err(dev, "unable to init generic GPIO" ); |
408 | return err; |
409 | } |
410 | |
411 | ctrl->gc.ngpio = ngpios; |
412 | ctrl->gc.owner = THIS_MODULE; |
413 | |
414 | irq = platform_get_irq_optional(pdev, 0); |
415 | if (!(dev_flags & GPIO_INTERRUPTS_DISABLED) && irq > 0) { |
416 | girq = &ctrl->gc.irq; |
417 | gpio_irq_chip_set_chip(girq, chip: &realtek_gpio_irq_chip); |
418 | girq->default_type = IRQ_TYPE_NONE; |
419 | girq->handler = handle_bad_irq; |
420 | girq->parent_handler = realtek_gpio_irq_handler; |
421 | girq->num_parents = 1; |
422 | girq->parents = devm_kcalloc(dev, n: girq->num_parents, |
423 | size: sizeof(*girq->parents), GFP_KERNEL); |
424 | if (!girq->parents) |
425 | return -ENOMEM; |
426 | girq->parents[0] = irq; |
427 | girq->init_hw = realtek_gpio_irq_init; |
428 | } |
429 | |
430 | cpumask_clear(dstp: &ctrl->cpu_irq_maskable); |
431 | |
432 | if ((dev_flags & GPIO_INTERRUPTS_PER_CPU) && irq > 0) { |
433 | ctrl->cpumask_base = devm_platform_get_and_ioremap_resource(pdev, index: 1, res: &res); |
434 | if (IS_ERR(ptr: ctrl->cpumask_base)) |
435 | return dev_err_probe(dev, err: PTR_ERR(ptr: ctrl->cpumask_base), |
436 | fmt: "missing CPU IRQ mask registers" ); |
437 | |
438 | nr_cpus = resource_size(res) / REALTEK_GPIO_PORTS_PER_BANK; |
439 | nr_cpus = min(nr_cpus, num_present_cpus()); |
440 | |
441 | for (cpu = 0; cpu < nr_cpus; cpu++) |
442 | cpumask_set_cpu(cpu, dstp: &ctrl->cpu_irq_maskable); |
443 | } |
444 | |
445 | return devm_gpiochip_add_data(dev, &ctrl->gc, ctrl); |
446 | } |
447 | |
448 | static struct platform_driver realtek_gpio_driver = { |
449 | .driver = { |
450 | .name = "realtek-otto-gpio" , |
451 | .of_match_table = realtek_gpio_of_match, |
452 | }, |
453 | .probe = realtek_gpio_probe, |
454 | }; |
455 | module_platform_driver(realtek_gpio_driver); |
456 | |
457 | MODULE_DESCRIPTION("Realtek Otto GPIO support" ); |
458 | MODULE_AUTHOR("Sander Vanheule <sander@svanheule.net>" ); |
459 | MODULE_LICENSE("GPL v2" ); |
460 | |