[PATCH v1 2/2] gpio: 74x164: support 'registers-default' DT property for initial state

Chanhong Jung
2026-04-22T16:05:16Z

74HC595 and 74LVC594 chains retain their output state from the first
serial write onwards. Today the driver always kicks that first write
from a zero-initialised buffer, so every output comes up low until user
space issues a write. Boards that rely on the chain to drive signals
whose power-on state matters (active-low indicators, reset lines, etc.)
have no way to express the desired initial pattern via DT, and must
reinvent it from user space each time after probe.

Read the new optional 'registers-default' u8 array into chip->buffer
after the buffer's size becomes known (so __counted_by() is satisfied)
and before the first __gen_74x164_write_config(). Absence of the
property keeps the current zeroing behaviour; an invalid size is
rejected with dev_err_probe() so that dtbs_check violations surface
loudly at probe time.

The matching binding change documents the property's layout. The
corresponding U-Boot driver (drivers/gpio/74x164_gpio.c) has honoured
the same property for years, so the two bootstages can now agree on
the initial state without user-space involvement.

Signed-off-by: Chanhong Jung <happycpu@gmail.com>
---
drivers/gpio/gpio-74x164.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c
index c226524ef..b433a4a61 100644
--- a/drivers/gpio/gpio-74x164.c
+++ b/drivers/gpio/gpio-74x164.c
@@ -134,6 +134,20 @@ static int gen_74x164_probe(struct spi_device *spi)

chip->registers = nregs;

+ /*
+ * Optionally seed the chain with a board-specified pattern so that
+ * the outputs come up in a known state on the first SPI write. When
+ * the property is absent, the buffer stays zeroed by devm_kzalloc()
+ * and the existing behaviour is preserved.
+ */
+ if (device_property_present(dev, "registers-default")) {
+ ret = device_property_read_u8_array(dev, "registers-default",
+ chip->buffer, nregs);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Invalid 'registers-default'\n");
+ }
+
chip->gpiod_oe = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
if (IS_ERR(chip->gpiod_oe))
return PTR_ERR(chip->gpiod_oe);
--
2.34.1