From 862da3f67937d30d7df71877631b3463e5550ca9 Mon Sep 17 00:00:00 2001 From: Michael Field Date: Wed, 3 Jun 2026 14:50:51 -0700 Subject: [PATCH] spi: aspeed: Respect transfer-specific bit width The ASPEED SPI driver previously configured the controller's transfer mode (dual, quad, or single) based globally on the target device's capability flags (spi->mode & SPI_TX_DUAL/QUAD), ignoring the requested width of individual transfers in the message sequence. This deviates from the Linux SPI subsystem design, which expects command, address, and dummy phases of a transaction to default to single-bit transmission, with multi-bit mode restricted strictly to the data payload transfers that request it via tx_nbits or rx_nbits. Fix this by dynamically adjusting the controller's IO mode for each transfer segment. The dual or quad IO mode is activated only if both the individual transfer requests the multi-bit width (tx_nbits/rx_nbits) and the device globally supports that mode (spi->mode). All other transfers remain in the default single-bit mode. --- drivers/spi/spi-aspeed-txrx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-aspeed-txrx.c b/drivers/spi/spi-aspeed-txrx.c index e0c8eef2a6a06b..9f95020c122a94 100644 --- a/drivers/spi/spi-aspeed-txrx.c +++ b/drivers/spi/spi-aspeed-txrx.c @@ -390,9 +390,9 @@ static int aspeed_spi_transfer(struct spi_controller *ctlr, if (tx_buf) { ctrl_val &= ~SPI_IO_MASK; - if (spi->mode & SPI_TX_DUAL) + if (spi->mode & SPI_TX_DUAL && xfer->tx_nbits == SPI_NBITS_DUAL) ctrl_val |= SPI_DUAL_IO_MODE; - else if (spi->mode & SPI_TX_QUAD) + else if (spi->mode & SPI_TX_QUAD && xfer->tx_nbits == SPI_NBITS_QUAD) ctrl_val |= SPI_QUAD_IO_MODE; writel(ctrl_val, ctrl_reg); @@ -408,9 +408,9 @@ static int aspeed_spi_transfer(struct spi_controller *ctlr, if (rx_buf && rx_buf != tx_buf) { ctrl_val &= ~SPI_IO_MASK; - if (spi->mode & SPI_RX_DUAL) + if (spi->mode & SPI_RX_DUAL && xfer->rx_nbits == SPI_NBITS_DUAL) ctrl_val |= SPI_DUAL_IO_MODE; - else if (spi->mode & SPI_RX_QUAD) + else if (spi->mode & SPI_RX_QUAD && xfer->rx_nbits == SPI_NBITS_QUAD) ctrl_val |= SPI_QUAD_IO_MODE; writel(ctrl_val, ctrl_reg);