From 8868c03f3ca584abec7bb53d6c3f7c5ab6b60949 Mon Sep 17 00:00:00 2001
From: Pratyush Yadav
Date: Wed, 20 Apr 2022 15:50:22 +0530
Subject: [PATCH 1/5] spi: spi-mem: check if data buffers are on stack
The buffers passed in the data phase must be DMA-able. Programmers often
don't realise this requirement and pass in buffers that reside on the
stack. This can be hard to spot when reviewing code. Reject ops if their
data buffer is on the stack to avoid this.
Signed-off-by: Pratyush Yadav
Link: https://lore.kernel.org/r/20220420102022.3310970-1-p.yadav@ti.com
Signed-off-by: Mark Brown
---
drivers/spi/spi-mem.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 0e8dafc62d94..60c968c1dc6e 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -10,6 +10,7 @@
#include
#include
#include
+#include
#include "internals.h"
@@ -211,6 +212,15 @@ static int spi_mem_check_op(const struct spi_mem_op *op)
!spi_mem_buswidth_is_valid(op->data.buswidth))
return -EINVAL;
+ /* Buffers must be DMA-able. */
+ if (WARN_ON_ONCE(op->data.dir == SPI_MEM_DATA_IN &&
+ object_is_on_stack(op->data.buf.in)))
+ return -EINVAL;
+
+ if (WARN_ON_ONCE(op->data.dir == SPI_MEM_DATA_OUT &&
+ object_is_on_stack(op->data.buf.out)))
+ return -EINVAL;
+
return 0;
}
From f724c296f2f2cc3f9342b0fc26239635cbed856e Mon Sep 17 00:00:00 2001
From: Ian Abbott
Date: Wed, 27 Apr 2022 16:34:46 +0100
Subject: [PATCH 2/5] spi: cadence-quadspi: fix Direct Access Mode disable for
SoCFPGA
The Cadence QSPI compatible string required for the SoCFPGA platform
changed from the default "cdns,qspi-nor" to "intel,socfpga-qspi" with
the introduction of an additional quirk in
commit 98d948eb8331 ("spi: cadence-quadspi: fix write completion support").
However, that change did not preserve the previously used
quirk for this platform. Reinstate the `CQSPI_DISABLE_DAC_MODE` quirk
for the SoCFPGA platform.
Fixes: 98d948eb8331 ("spi: cadence-quadspi: fix write completion support")
Cc: Dinh Nguyen
Signed-off-by: Ian Abbott
Link: https://lore.kernel.org/r/20220427153446.10113-1-abbotti@mev.co.uk
Signed-off-by: Mark Brown
---
drivers/spi/spi-cadence-quadspi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
index 19686fb47bb3..ec53b807909e 100644
--- a/drivers/spi/spi-cadence-quadspi.c
+++ b/drivers/spi/spi-cadence-quadspi.c
@@ -1865,7 +1865,7 @@ static const struct cqspi_driver_platdata intel_lgm_qspi = {
};
static const struct cqspi_driver_platdata socfpga_qspi = {
- .quirks = CQSPI_NO_SUPPORT_WR_COMPLETION,
+ .quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_NO_SUPPORT_WR_COMPLETION,
};
static const struct cqspi_driver_platdata versal_ospi = {
From d83d89ea68b4726700fa87b22db075e4217e691c Mon Sep 17 00:00:00 2001
From: Patrice Chotard
Date: Wed, 11 May 2022 09:46:42 +0200
Subject: [PATCH 3/5] spi: stm32-qspi: Fix wait_cmd timeout in APM mode
In APM mode, TCF and TEF flags are not set. To avoid timeout in
stm32_qspi_wait_cmd(), don't check if TCF/TEF are set.
Signed-off-by: Patrice Chotard
Reported-by: eberhard.stoll@kontron.de
Link: https://lore.kernel.org/r/20220511074644.558874-2-patrice.chotard@foss.st.com
Signed-off-by: Mark Brown
---
drivers/spi/spi-stm32-qspi.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c
index ffdc55f87e82..dd38cb8ffbc2 100644
--- a/drivers/spi/spi-stm32-qspi.c
+++ b/drivers/spi/spi-stm32-qspi.c
@@ -308,7 +308,8 @@ static int stm32_qspi_wait_cmd(struct stm32_qspi *qspi,
if (!op->data.nbytes)
goto wait_nobusy;
- if (readl_relaxed(qspi->io_base + QSPI_SR) & SR_TCF)
+ if ((readl_relaxed(qspi->io_base + QSPI_SR) & SR_TCF) ||
+ qspi->fmode == CCR_FMODE_APM)
goto out;
reinit_completion(&qspi->data_completion);
From 0cf8d32600cf5660ee45d421f1b6e3a129ca58b6 Mon Sep 17 00:00:00 2001
From: Patrice Chotard
Date: Wed, 11 May 2022 09:46:43 +0200
Subject: [PATCH 4/5] spi: stm32-qspi: Always check SR_TCF flags in
stm32_qspi_wait_cmd()
Currently, SR_TCF flag is checked in case there is data, this criteria
is not correct.
SR_TCF flags is set when programmed number of bytes has been transferred
to the memory device ("bytes" comprised command and data send to the
SPI device).
So even if there is no data, we must check SR_TCF flag.
Signed-off-by: Patrice Chotard
Link: https://lore.kernel.org/r/20220511074644.558874-3-patrice.chotard@foss.st.com
Signed-off-by: Mark Brown
---
drivers/spi/spi-stm32-qspi.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c
index dd38cb8ffbc2..f2b67c8842d4 100644
--- a/drivers/spi/spi-stm32-qspi.c
+++ b/drivers/spi/spi-stm32-qspi.c
@@ -305,9 +305,6 @@ static int stm32_qspi_wait_cmd(struct stm32_qspi *qspi,
u32 cr, sr;
int err = 0;
- if (!op->data.nbytes)
- goto wait_nobusy;
-
if ((readl_relaxed(qspi->io_base + QSPI_SR) & SR_TCF) ||
qspi->fmode == CCR_FMODE_APM)
goto out;
@@ -328,7 +325,6 @@ static int stm32_qspi_wait_cmd(struct stm32_qspi *qspi,
out:
/* clear flags */
writel_relaxed(FCR_CTCF | FCR_CTEF, qspi->io_base + QSPI_FCR);
-wait_nobusy:
if (!err)
err = stm32_qspi_wait_nobusy(qspi);
From ae16cc18f37bcdea7d4ef57a5e526a60b09a1506 Mon Sep 17 00:00:00 2001
From: Patrice Chotard
Date: Wed, 11 May 2022 09:46:44 +0200
Subject: [PATCH 5/5] spi: stm32-qspi: Remove SR_BUSY bit check before sending
command
Waiting for SR_BUSY bit when receiving a new command is not needed.
SR_BUSY bit is already managed in the previous command treatment.
Signed-off-by: Patrice Chotard
Link: https://lore.kernel.org/r/20220511074644.558874-4-patrice.chotard@foss.st.com
Signed-off-by: Mark Brown
---
drivers/spi/spi-stm32-qspi.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c
index f2b67c8842d4..1948a0090ae4 100644
--- a/drivers/spi/spi-stm32-qspi.c
+++ b/drivers/spi/spi-stm32-qspi.c
@@ -369,10 +369,6 @@ static int stm32_qspi_send(struct spi_mem *mem, const struct spi_mem_op *op)
op->dummy.buswidth, op->data.buswidth,
op->addr.val, op->data.nbytes);
- err = stm32_qspi_wait_nobusy(qspi);
- if (err)
- goto abort;
-
cr = readl_relaxed(qspi->io_base + QSPI_CR);
cr &= ~CR_PRESC_MASK & ~CR_FSEL;
cr |= FIELD_PREP(CR_PRESC_MASK, flash->presc);