[PATCH 05/32] spi: dw: Introduce DW_SPI_CAP_POLL_NODELAY

Damien Le Moal
2020-11-07T08:14:53Z

On slow systems, i.e. systems with a slow CPU resulting in slow context
switches, calling spi_delay_exec() when executing polled transfers
using dw_spi_poll_transfer() can lead to RX FIFO overflows. Allow
platforms to opt out of delayed polling by introducing the
DW_SPI_CAP_POLL_NODELAY DW SPI capability flag to disable
the execution of spi_delay_exec() in dw_spi_poll_transfer().

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
drivers/spi/spi-dw-core.c | 12 ++++++++----
drivers/spi/spi-dw.h | 1 +
2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c
index c2ef1d8d46d5..16a6fd569145 100644
--- a/drivers/spi/spi-dw-core.c
+++ b/drivers/spi/spi-dw-core.c
@@ -385,14 +385,18 @@ static int dw_spi_poll_transfer(struct dw_spi *dws,
u16 nbits;
int ret;

- delay.unit = SPI_DELAY_UNIT_SCK;
- nbits = dws->n_bytes * BITS_PER_BYTE;
+ if (!(dws->caps & DW_SPI_CAP_POLL_NODELAY)) {
+ delay.unit = SPI_DELAY_UNIT_SCK;
+ nbits = dws->n_bytes * BITS_PER_BYTE;
+ }

do {
dw_writer(dws);

- delay.value = nbits * (dws->rx_len - dws->tx_len);
- spi_delay_exec(&delay, transfer);
+ if (!(dws->caps & DW_SPI_CAP_POLL_NODELAY)) {
+ delay.value = nbits * (dws->rx_len - dws->tx_len);
+ spi_delay_exec(&delay, transfer);
+ }

dw_reader(dws);

diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h
index 48a11a51a407..25f6372b993a 100644
--- a/drivers/spi/spi-dw.h
+++ b/drivers/spi/spi-dw.h
@@ -130,6 +130,7 @@ enum dw_ssi_type {
#define DW_SPI_CAP_KEEMBAY_MST BIT(1)
#define DW_SPI_CAP_DWC_SSI BIT(2)
#define DW_SPI_CAP_DFS_32 BIT(3)
+#define DW_SPI_CAP_POLL_NODELAY BIT(4)

/* Slave spi_transfer/spi_mem_op related */
struct dw_spi_cfg {
--
2.28.0