Hi Cole,

On 8/18/26 3:15 AM, Cole Munz wrote:
The spi-peripheral-props binding shipped in dts/upstream allows a bus
width of 0, meaning no RX or TX is possible on this device. The
switches in spi_slave_of_to_plat() only handle 1/2/4/8, so a width of
0 falls through to the default case and warns "spi-rx-bus-width 0 not
supported" on every boot, even though the devicetree is valid per the
binding. The fact that the wire is missing is then dropped from
plat->mode.

Map 0 to new SPI_NO_TX/SPI_NO_RX mode bits, as Linux has done since
v5.12 ("spi: Add SPI_NO_TX/RX support", mainline d962608ce218).
Bits 16 and 17 are the first free mode bits.

This comes up on devices with no MISO line at all, such as a
write-only SPI display described with spi-rx-bus-width = <0>.

Signed-off-by: Cole Munz <[email protected]>
---
Raised as a boot-log warning on Flipper One, whose display has no MISO
line at all: that pin is reused as the end-of-frame GPIO. Reported at
flipperdevices/u-boot#33, and sent here rather than to the fork as

Please provide a full link next time, not everything is hosted on GitHub so we wouldn't necessarily know where to look. I knew because I had at a look at Flipper One's repos a few weeks ago and remembered. For reference: https://github.com/flipperdevices/u-boot/issues/33

suggested on that issue.

Verified on sandbox at 527115ef6783, with spi-rx-bus-width = <0> added
to spi.bin@0 in arch/sandbox/dts/test.dts and CONFIG_LOG disabled, so
warn_non_xpl() reaches the console the way it does on the board.

Before:
  $ ./u-boot -T -c "sf probe"
  spi-rx-bus-width 0 not supported
  spi-rx-bus-width 0 not supported
  SF: Detected m25p16 with page size 256 Bytes, erase size 64 KiB, 2 MiB

After:
  $ ./u-boot -T -c "sf probe"
  SF: Detected m25p16 with page size 256 Bytes, erase size 64 KiB, 2 MiB

It warns twice in sandbox because both the pre- and post-reloc DM scans
run there; the board logs it once.

ut dm spi_flash, spi_xfer, spi_find, spi_claim_bus, spi_set_wordlen and
spi_flash_func all pass with the property in place. Nothing consumes the
new bits yet, matching d962608ce218 in Linux, where the consumers landed
later.

  drivers/spi/spi-uclass.c | 6 ++++++
  include/spi.h            | 2 ++
  2 files changed, 8 insertions(+)

diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 120565df1497..0f0d4b1384f2 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -229,6 +229,9 @@ static int spi_child_post_bind(struct udevice *dev)
        /* Device DUAL/QUAD mode */
        value = dev_read_u32_default(dev, "spi-tx-bus-width", 1);
        switch (value) {
+       case 0:
+               mode |= SPI_NO_TX;
+               break;
        case 1:
                break;
        case 2:
@@ -247,6 +250,9 @@ static int spi_child_post_bind(struct udevice *dev)
value = dev_read_u32_default(dev, "spi-rx-bus-width", 1);
        switch (value) {
+       case 0:
+               mode |= SPI_NO_RX;
+               break;
        case 1:
                break;
        case 2:
diff --git a/include/spi.h b/include/spi.h
index 97096a775262..f477763bdc60 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -34,6 +34,8 @@ struct spinand_info;
  #define SPI_RX_QUAD   BIT(13)                 /* receive with 4 wires */
  #define SPI_TX_OCTAL  BIT(14)                 /* transmit with 8 wires */
  #define SPI_RX_OCTAL  BIT(15)                 /* receive with 8 wires */
+#define SPI_NO_TX      BIT(16)                 /* no transmit wire */
+#define SPI_NO_RX      BIT(17)                 /* no receive wire */
/* Header byte that marks the start of the message */
  #define SPI_PREAMBLE_END_BYTE 0xec

So this is fine, but incomplete. We should really do:

[...]
struct dm_spi_slave_plat *plat = dev_get_parent_plat(dev);

if (din && (plat->mode & SPI_NO_RX))
    return -EINVAL;
if (dout && (plat->mode & SPI_NO_TX))
    return -EINVAL;

return ops->xfer(dev, bitlen, dout, din, flags);

in dm_spi_xfer(). To avoid calling xfer() with an invalid configuration. This would then match the Linux kernel behavior (c.f. __spi_validate) and avoid all SPI controller drivers having to implement logic to avoid reading/writing on NO_RX/NO_TX devices.

It'd be nice to add tests to make sure this is handled properly (the function returns -EINAL on invalid configuration).

Please send the spi-uclass.c and rk_spi.c in the same series (in separate commits still, like you've done here), with a joined cover-letter (the info you added to this patch and the Rockchip one is good enough IMO).

Cheers,
Quentin

Reply via email to