diff mbox series

[v2,07/17] spi: mpc8xx: Fix transfert when input or output buffer is NULL

Message ID 42dff816b493d4edd8a1fe5e6ab3c4071b447121.1713160866.git.christophe.leroy@csgroup.eu
State Accepted
Commit ea208201a12913e7a5b7b4b38624942effa44c05
Delegated to: Tom Rini
Headers show
Series Misc changes for CSSI boards | expand

Commit Message

Christophe Leroy April 15, 2024, 6:07 a.m. UTC
xfer ops can be passed a NULL input or output buffer. At the
time being the driver ignores it and overwrites memory at 0.

Define a dummy buffer and use it when either input or output
buffer is NULL. Bail out when both are NULL as it shouldn't.

Also increase MAX_BUFFER len to 32k as the current is pretty
low.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 drivers/spi/mpc8xx_spi.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/drivers/spi/mpc8xx_spi.c b/drivers/spi/mpc8xx_spi.c
index 5c8d760935..2aa9c7d5df 100644
--- a/drivers/spi/mpc8xx_spi.c
+++ b/drivers/spi/mpc8xx_spi.c
@@ -29,7 +29,7 @@ 
 #define CPM_SPI_BASE_RX	CPM_SPI_BASE
 #define CPM_SPI_BASE_TX	(CPM_SPI_BASE + sizeof(cbd_t))
 
-#define MAX_BUFFER	0x104
+#define MAX_BUFFER	0x8000 /* Max possible is 0xffff. We want power of 2 */
 
 struct mpc8xx_priv {
 	spi_t __iomem *spi;
@@ -37,6 +37,8 @@  struct mpc8xx_priv {
 	int max_cs;
 };
 
+static char dummy_buffer[MAX_BUFFER];
+
 static int mpc8xx_spi_set_mode(struct udevice *dev, uint mod)
 {
 	return 0;
@@ -154,6 +156,8 @@  static int mpc8xx_spi_xfer(struct udevice *dev, unsigned int bitlen,
 	int tm;
 	size_t count = (bitlen + 7) / 8;
 
+	if (!din && !dout)
+		return -EINVAL;
 	if (count > MAX_BUFFER)
 		return -EINVAL;
 
@@ -165,12 +169,12 @@  static int mpc8xx_spi_xfer(struct udevice *dev, unsigned int bitlen,
 		mpc8xx_spi_cs_activate(dev);
 
 	/* Setting tx bd status and data length */
-	out_be32(&tbdf->cbd_bufaddr, (ulong)dout);
+	out_be32(&tbdf->cbd_bufaddr, dout ? (ulong)dout : (ulong)dummy_buffer);
 	out_be16(&tbdf->cbd_sc, BD_SC_READY | BD_SC_LAST | BD_SC_WRAP);
 	out_be16(&tbdf->cbd_datlen, count);
 
 	/* Setting rx bd status and data length */
-	out_be32(&rbdf->cbd_bufaddr, (ulong)din);
+	out_be32(&rbdf->cbd_bufaddr, din ? (ulong)din : (ulong)dummy_buffer);
 	out_be16(&rbdf->cbd_sc, BD_SC_EMPTY | BD_SC_WRAP);
 	out_be16(&rbdf->cbd_datlen, 0);	 /* rx length has no significance */