OSDN Git Service

can: mcp251x: fix support for half duplex SPI host controllers
authorMarc Kleine-Budde <mkl@pengutronix.de>
Tue, 30 Mar 2021 09:46:07 +0000 (11:46 +0200)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Tue, 6 Apr 2021 10:31:21 +0000 (12:31 +0200)
Some SPI host controllers do not support full-duplex SPI transfers.

The function mcp251x_spi_trans() does a full duplex transfer. It is
used in several places in the driver, where a TX half duplex transfer
is sufficient.

To fix support for half duplex SPI host controllers, this patch
introduces a new function mcp251x_spi_write() and changes all callers
that do a TX half duplex transfer to use mcp251x_spi_write().

Fixes: e0e25001d088 ("can: mcp251x: add support for half duplex controllers")
Link: https://lore.kernel.org/r/20210330100246.1074375-1-mkl@pengutronix.de
Cc: Tim Harvey <tharvey@gateworks.com>
Tested-By: Tim Harvey <tharvey@gateworks.com>
Reported-by: Gerhard Bertelsmann <info@gerhard-bertelsmann.de>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
drivers/net/can/spi/mcp251x.c

index f69fb42..a57da43 100644 (file)
@@ -314,6 +314,18 @@ static int mcp251x_spi_trans(struct spi_device *spi, int len)
        return ret;
 }
 
+static int mcp251x_spi_write(struct spi_device *spi, int len)
+{
+       struct mcp251x_priv *priv = spi_get_drvdata(spi);
+       int ret;
+
+       ret = spi_write(spi, priv->spi_tx_buf, len);
+       if (ret)
+               dev_err(&spi->dev, "spi write failed: ret = %d\n", ret);
+
+       return ret;
+}
+
 static u8 mcp251x_read_reg(struct spi_device *spi, u8 reg)
 {
        struct mcp251x_priv *priv = spi_get_drvdata(spi);
@@ -361,7 +373,7 @@ static void mcp251x_write_reg(struct spi_device *spi, u8 reg, u8 val)
        priv->spi_tx_buf[1] = reg;
        priv->spi_tx_buf[2] = val;
 
-       mcp251x_spi_trans(spi, 3);
+       mcp251x_spi_write(spi, 3);
 }
 
 static void mcp251x_write_2regs(struct spi_device *spi, u8 reg, u8 v1, u8 v2)
@@ -373,7 +385,7 @@ static void mcp251x_write_2regs(struct spi_device *spi, u8 reg, u8 v1, u8 v2)
        priv->spi_tx_buf[2] = v1;
        priv->spi_tx_buf[3] = v2;
 
-       mcp251x_spi_trans(spi, 4);
+       mcp251x_spi_write(spi, 4);
 }
 
 static void mcp251x_write_bits(struct spi_device *spi, u8 reg,
@@ -386,7 +398,7 @@ static void mcp251x_write_bits(struct spi_device *spi, u8 reg,
        priv->spi_tx_buf[2] = mask;
        priv->spi_tx_buf[3] = val;
 
-       mcp251x_spi_trans(spi, 4);
+       mcp251x_spi_write(spi, 4);
 }
 
 static u8 mcp251x_read_stat(struct spi_device *spi)
@@ -618,7 +630,7 @@ static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf,
                                          buf[i]);
        } else {
                memcpy(priv->spi_tx_buf, buf, TXBDAT_OFF + len);
-               mcp251x_spi_trans(spi, TXBDAT_OFF + len);
+               mcp251x_spi_write(spi, TXBDAT_OFF + len);
        }
 }
 
@@ -650,7 +662,7 @@ static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame,
 
        /* use INSTRUCTION_RTS, to avoid "repeated frame problem" */
        priv->spi_tx_buf[0] = INSTRUCTION_RTS(1 << tx_buf_idx);
-       mcp251x_spi_trans(priv->spi, 1);
+       mcp251x_spi_write(priv->spi, 1);
 }
 
 static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf,
@@ -888,7 +900,7 @@ static int mcp251x_hw_reset(struct spi_device *spi)
        mdelay(MCP251X_OST_DELAY_MS);
 
        priv->spi_tx_buf[0] = INSTRUCTION_RESET;
-       ret = mcp251x_spi_trans(spi, 1);
+       ret = mcp251x_spi_write(spi, 1);
        if (ret)
                return ret;