Skip to content

Commit 933174a

Browse files
committed
Merge tag 'spi-fix-v6.4-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi fixes from Mark Brown: "A collection of fixes that came in since the merge window, plus an update to MAINTAINERS. The Cadence fixes are coming from the addition of device mode support, they required a couple of incremental updates in order to get something that works robustly for both device and controller modes" * tag 'spi-fix-v6.4-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: spi: spi-cadence: Interleave write of TX and read of RX FIFO spi: dw: Replace spi->chip_select references with function calls spi: MAINTAINERS: drop Krzysztof Kozlowski from Samsung SPI spi: spi-cadence: Only overlap FIFO transactions in slave mode spi: spi-cadence: Avoid read of RX FIFO before its ready spi: spi-geni-qcom: Select FIFO mode for chip select
2 parents f767b33 + 6afe2ae commit 933174a

File tree

4 files changed

+51
-65
lines changed

4 files changed

+51
-65
lines changed

MAINTAINERS

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18703,7 +18703,6 @@ F: include/dt-bindings/clock/samsung,*.h
1870318703
F: include/linux/clk/samsung.h
1870418704

1870518705
SAMSUNG SPI DRIVERS
18706-
M: Krzysztof Kozlowski <[email protected]>
1870718706
M: Andi Shyti <[email protected]>
1870818707
1870918708

drivers/spi/spi-cadence.c

Lines changed: 45 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/gpio/consumer.h>
1313
#include <linux/interrupt.h>
1414
#include <linux/io.h>
15+
#include <linux/kernel.h>
1516
#include <linux/module.h>
1617
#include <linux/of_irq.h>
1718
#include <linux/of_address.h>
@@ -301,49 +302,43 @@ static int cdns_spi_setup_transfer(struct spi_device *spi,
301302
}
302303

303304
/**
304-
* cdns_spi_fill_tx_fifo - Fills the TX FIFO with as many bytes as possible
305+
* cdns_spi_process_fifo - Fills the TX FIFO, and drain the RX FIFO
305306
* @xspi: Pointer to the cdns_spi structure
307+
* @ntx: Number of bytes to pack into the TX FIFO
308+
* @nrx: Number of bytes to drain from the RX FIFO
306309
*/
307-
static void cdns_spi_fill_tx_fifo(struct cdns_spi *xspi)
310+
static void cdns_spi_process_fifo(struct cdns_spi *xspi, int ntx, int nrx)
308311
{
309-
unsigned long trans_cnt = 0;
312+
ntx = clamp(ntx, 0, xspi->tx_bytes);
313+
nrx = clamp(nrx, 0, xspi->rx_bytes);
310314

311-
while ((trans_cnt < xspi->tx_fifo_depth) &&
312-
(xspi->tx_bytes > 0)) {
315+
xspi->tx_bytes -= ntx;
316+
xspi->rx_bytes -= nrx;
313317

318+
while (ntx || nrx) {
314319
/* When xspi in busy condition, bytes may send failed,
315320
* then spi control did't work thoroughly, add one byte delay
316321
*/
317-
if (cdns_spi_read(xspi, CDNS_SPI_ISR) &
318-
CDNS_SPI_IXR_TXFULL)
322+
if (cdns_spi_read(xspi, CDNS_SPI_ISR) & CDNS_SPI_IXR_TXFULL)
319323
udelay(10);
320324

321-
if (xspi->txbuf)
322-
cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++);
323-
else
324-
cdns_spi_write(xspi, CDNS_SPI_TXD, 0);
325+
if (ntx) {
326+
if (xspi->txbuf)
327+
cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++);
328+
else
329+
cdns_spi_write(xspi, CDNS_SPI_TXD, 0);
325330

326-
xspi->tx_bytes--;
327-
trans_cnt++;
328-
}
329-
}
331+
ntx--;
332+
}
330333

331-
/**
332-
* cdns_spi_read_rx_fifo - Reads the RX FIFO with as many bytes as possible
333-
* @xspi: Pointer to the cdns_spi structure
334-
* @count: Read byte count
335-
*/
336-
static void cdns_spi_read_rx_fifo(struct cdns_spi *xspi, unsigned long count)
337-
{
338-
u8 data;
339-
340-
/* Read out the data from the RX FIFO */
341-
while (count > 0) {
342-
data = cdns_spi_read(xspi, CDNS_SPI_RXD);
343-
if (xspi->rxbuf)
344-
*xspi->rxbuf++ = data;
345-
xspi->rx_bytes--;
346-
count--;
334+
if (nrx) {
335+
u8 data = cdns_spi_read(xspi, CDNS_SPI_RXD);
336+
337+
if (xspi->rxbuf)
338+
*xspi->rxbuf++ = data;
339+
340+
nrx--;
341+
}
347342
}
348343
}
349344

@@ -381,33 +376,22 @@ static irqreturn_t cdns_spi_irq(int irq, void *dev_id)
381376
spi_finalize_current_transfer(ctlr);
382377
status = IRQ_HANDLED;
383378
} else if (intr_status & CDNS_SPI_IXR_TXOW) {
384-
int trans_cnt = cdns_spi_read(xspi, CDNS_SPI_THLD);
379+
int threshold = cdns_spi_read(xspi, CDNS_SPI_THLD);
380+
int trans_cnt = xspi->rx_bytes - xspi->tx_bytes;
381+
382+
if (threshold > 1)
383+
trans_cnt -= threshold;
384+
385385
/* Set threshold to one if number of pending are
386386
* less than half fifo
387387
*/
388388
if (xspi->tx_bytes < xspi->tx_fifo_depth >> 1)
389389
cdns_spi_write(xspi, CDNS_SPI_THLD, 1);
390390

391-
while (trans_cnt) {
392-
cdns_spi_read_rx_fifo(xspi, 1);
393-
394-
if (xspi->tx_bytes) {
395-
if (xspi->txbuf)
396-
cdns_spi_write(xspi, CDNS_SPI_TXD,
397-
*xspi->txbuf++);
398-
else
399-
cdns_spi_write(xspi, CDNS_SPI_TXD, 0);
400-
xspi->tx_bytes--;
401-
}
402-
trans_cnt--;
403-
}
404-
if (!xspi->tx_bytes) {
405-
/* Fixed delay due to controller limitation with
406-
* RX_NEMPTY incorrect status
407-
* Xilinx AR:65885 contains more details
408-
*/
409-
udelay(10);
410-
cdns_spi_read_rx_fifo(xspi, xspi->rx_bytes);
391+
if (xspi->tx_bytes) {
392+
cdns_spi_process_fifo(xspi, trans_cnt, trans_cnt);
393+
} else {
394+
cdns_spi_process_fifo(xspi, 0, trans_cnt);
411395
cdns_spi_write(xspi, CDNS_SPI_IDR,
412396
CDNS_SPI_IXR_DEFAULT);
413397
spi_finalize_current_transfer(ctlr);
@@ -450,16 +434,17 @@ static int cdns_transfer_one(struct spi_controller *ctlr,
450434
xspi->tx_bytes = transfer->len;
451435
xspi->rx_bytes = transfer->len;
452436

453-
if (!spi_controller_is_slave(ctlr))
437+
if (!spi_controller_is_slave(ctlr)) {
454438
cdns_spi_setup_transfer(spi, transfer);
439+
} else {
440+
/* Set TX empty threshold to half of FIFO depth
441+
* only if TX bytes are more than half FIFO depth.
442+
*/
443+
if (xspi->tx_bytes > xspi->tx_fifo_depth)
444+
cdns_spi_write(xspi, CDNS_SPI_THLD, xspi->tx_fifo_depth >> 1);
445+
}
455446

456-
/* Set TX empty threshold to half of FIFO depth
457-
* only if TX bytes are more than half FIFO depth.
458-
*/
459-
if (xspi->tx_bytes > (xspi->tx_fifo_depth >> 1))
460-
cdns_spi_write(xspi, CDNS_SPI_THLD, xspi->tx_fifo_depth >> 1);
461-
462-
cdns_spi_fill_tx_fifo(xspi);
447+
cdns_spi_process_fifo(xspi, xspi->tx_fifo_depth, 0);
463448
spi_transfer_delay_exec(transfer);
464449

465450
cdns_spi_write(xspi, CDNS_SPI_IER, CDNS_SPI_IXR_DEFAULT);

drivers/spi/spi-dw-mmio.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,17 +264,17 @@ static void dw_spi_elba_set_cs(struct spi_device *spi, bool enable)
264264
struct regmap *syscon = dwsmmio->priv;
265265
u8 cs;
266266

267-
cs = spi->chip_select;
267+
cs = spi_get_chipselect(spi, 0);
268268
if (cs < 2)
269-
dw_spi_elba_override_cs(syscon, spi->chip_select, enable);
269+
dw_spi_elba_override_cs(syscon, spi_get_chipselect(spi, 0), enable);
270270

271271
/*
272272
* The DW SPI controller needs a native CS bit selected to start
273273
* the serial engine.
274274
*/
275-
spi->chip_select = 0;
275+
spi_set_chipselect(spi, 0, 0);
276276
dw_spi_set_cs(spi, enable);
277-
spi->chip_select = cs;
277+
spi_get_chipselect(spi, cs);
278278
}
279279

280280
static int dw_spi_elba_init(struct platform_device *pdev,

drivers/spi/spi-geni-qcom.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,8 @@ static void spi_geni_set_cs(struct spi_device *slv, bool set_flag)
294294
mas->cs_flag = set_flag;
295295
/* set xfer_mode to FIFO to complete cs_done in isr */
296296
mas->cur_xfer_mode = GENI_SE_FIFO;
297+
geni_se_select_mode(se, mas->cur_xfer_mode);
298+
297299
reinit_completion(&mas->cs_done);
298300
if (set_flag)
299301
geni_se_setup_m_cmd(se, SPI_CS_ASSERT, 0);

0 commit comments

Comments
 (0)