mirror of
https://github.com/openwrt/openwrt.git
synced 2025-02-19 08:56:44 +00:00
Add pending patches to add RTL8231 support as a MDIO-bus attached multi-functional device. This includes subdrivers for the pincontrol and GPIO features, as well as the LED matrix support. Leave the drivers disabled until required by a device. Signed-off-by: Sander Vanheule <sander@svanheule.net>
57 lines
2.1 KiB
Diff
57 lines
2.1 KiB
Diff
From b3f79468c90d8770f007d628a1e32b2d5d44a5c2 Mon Sep 17 00:00:00 2001
|
|
From: Sander Vanheule <sander@svanheule.net>
|
|
Date: Sat, 15 May 2021 11:57:32 +0200
|
|
Subject: [PATCH] gpio: regmap: Bypass cache for shadowed outputs
|
|
|
|
Some chips have the read-only input and write-only output data registers
|
|
aliased to the same offset, but do not perform direction multiplexing on
|
|
writes. Upon writing the register, this then always updates the output
|
|
value, even when the pin is configured as input. As a result it is not
|
|
safe to perform read-modify-writes on output pins, when other pins are
|
|
still configured as input.
|
|
|
|
For example, on a bit-banged I2C bus, where the lines are switched
|
|
between out-low and in (with external pull-up)
|
|
|
|
OUT(L) IN OUT(H)
|
|
SCK ....../''''''|''''''
|
|
|
|
SDA '''''''''\..........
|
|
^ ^- SCK switches to direction to OUT, but now has a high
|
|
| value, breaking the clock.
|
|
|
|
|
\- Perform RMW to update SDA. This reads the current input
|
|
value for SCK, updates the SDA value and writes back a 1
|
|
for SCK as well.
|
|
|
|
If a register is used for both the data input and data output (and is
|
|
not marked as volatile) the driver should ensure the cache is not
|
|
updated on register reads. This ensures proper functioning of writing
|
|
the output register with regmap_update_bits(), which will then use and
|
|
update the cache only on register writes.
|
|
|
|
Signed-off-by: Sander Vanheule <sander@svanheule.net>
|
|
---
|
|
drivers/gpio/gpio-regmap.c | 10 +++++++++-
|
|
1 file changed, 9 insertions(+), 1 deletion(-)
|
|
|
|
--- a/drivers/gpio/gpio-regmap.c
|
|
+++ b/drivers/gpio/gpio-regmap.c
|
|
@@ -74,7 +74,15 @@ static int gpio_regmap_get(struct gpio_c
|
|
if (ret)
|
|
return ret;
|
|
|
|
- ret = regmap_read(gpio->regmap, reg, &val);
|
|
+ /*
|
|
+ * Ensure we don't spoil the register cache with pin input values and
|
|
+ * perform a bypassed read. This way the cache (if any) is only used and
|
|
+ * updated on register writes.
|
|
+ */
|
|
+ if (gpio->reg_dat_base == gpio->reg_set_base)
|
|
+ ret = regmap_read_bypassed(gpio->regmap, reg, &val);
|
|
+ else
|
|
+ ret = regmap_read(gpio->regmap, reg, &val);
|
|
if (ret)
|
|
return ret;
|
|
|