Skip to content

Commit d9e37da

Browse files
Nicolas Ferrealexandrebelloni
authored andcommitted
spi: atmel: Use core SPI_MASTER_MUST_[RT]X handling
We need both RX and TX data for each transfer in any case (PIO, PDC, DMA). So convert the driver to the core dummy buffer handling with the SPI_MASTER_MUST_RX/SPI_MASTER_MUST_TX infrastructure. This move changes the maximum PDC/DMA buffer handling to 65535 bytes instead of a single page and sets master->max_dma_len to this value. All dummy buffer management is removed from the driver. Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 936528d commit d9e37da

1 file changed

Lines changed: 35 additions & 96 deletions

File tree

drivers/spi/spi-atmel.c

Lines changed: 35 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -304,10 +304,6 @@ struct atmel_spi {
304304

305305
struct completion xfer_completion;
306306

307-
/* scratch buffer */
308-
void *buffer;
309-
dma_addr_t buffer_dma;
310-
311307
struct atmel_spi_caps caps;
312308

313309
bool use_dma;
@@ -328,7 +324,7 @@ struct atmel_spi_device {
328324
u32 csr;
329325
};
330326

331-
#define BUFFER_SIZE PAGE_SIZE
327+
#define SPI_MAX_DMA_XFER 65535 /* true for both PDC and DMA */
332328
#define INVALID_DMA_ADDRESS 0xffffffff
333329

334330
/*
@@ -613,14 +609,10 @@ static void atmel_spi_next_xfer_single(struct spi_master *master,
613609
cpu_relax();
614610
}
615611

616-
if (xfer->tx_buf) {
617-
if (xfer->bits_per_word > 8)
618-
spi_writel(as, TDR, *(u16 *)(xfer->tx_buf + xfer_pos));
619-
else
620-
spi_writel(as, TDR, *(u8 *)(xfer->tx_buf + xfer_pos));
621-
} else {
622-
spi_writel(as, TDR, 0);
623-
}
612+
if (xfer->bits_per_word > 8)
613+
spi_writel(as, TDR, *(u16 *)(xfer->tx_buf + xfer_pos));
614+
else
615+
spi_writel(as, TDR, *(u8 *)(xfer->tx_buf + xfer_pos));
624616

625617
dev_dbg(master->dev.parent,
626618
" start pio xfer %p: len %u tx %p rx %p bitpw %d\n",
@@ -667,32 +659,23 @@ static void atmel_spi_next_xfer_fifo(struct spi_master *master,
667659

668660
/* Fill TX FIFO */
669661
while (num_data >= 2) {
670-
if (xfer->tx_buf) {
671-
if (xfer->bits_per_word > 8) {
672-
td0 = *words++;
673-
td1 = *words++;
674-
} else {
675-
td0 = *bytes++;
676-
td1 = *bytes++;
677-
}
662+
if (xfer->bits_per_word > 8) {
663+
td0 = *words++;
664+
td1 = *words++;
678665
} else {
679-
td0 = 0;
680-
td1 = 0;
666+
td0 = *bytes++;
667+
td1 = *bytes++;
681668
}
682669

683670
spi_writel(as, TDR, (td1 << 16) | td0);
684671
num_data -= 2;
685672
}
686673

687674
if (num_data) {
688-
if (xfer->tx_buf) {
689-
if (xfer->bits_per_word > 8)
690-
td0 = *words++;
691-
else
692-
td0 = *bytes++;
693-
} else {
694-
td0 = 0;
695-
}
675+
if (xfer->bits_per_word > 8)
676+
td0 = *words++;
677+
else
678+
td0 = *bytes++;
696679

697680
spi_writew(as, TDR, td0);
698681
num_data--;
@@ -751,24 +734,14 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master,
751734

752735
/* prepare the RX dma transfer */
753736
sg_init_table(&as->dma.sgrx, 1);
754-
if (xfer->rx_buf) {
755-
as->dma.sgrx.dma_address = xfer->rx_dma + xfer->len - *plen;
756-
} else {
757-
as->dma.sgrx.dma_address = as->buffer_dma;
758-
if (len > BUFFER_SIZE)
759-
len = BUFFER_SIZE;
760-
}
737+
as->dma.sgrx.dma_address = xfer->rx_dma + xfer->len - *plen;
761738

762739
/* prepare the TX dma transfer */
763740
sg_init_table(&as->dma.sgtx, 1);
764-
if (xfer->tx_buf) {
765-
as->dma.sgtx.dma_address = xfer->tx_dma + xfer->len - *plen;
766-
} else {
767-
as->dma.sgtx.dma_address = as->buffer_dma;
768-
if (len > BUFFER_SIZE)
769-
len = BUFFER_SIZE;
770-
memset(as->buffer, 0, len);
771-
}
741+
as->dma.sgtx.dma_address = xfer->tx_dma + xfer->len - *plen;
742+
743+
if (len > master->max_dma_len)
744+
len = master->max_dma_len;
772745

773746
sg_dma_len(&as->dma.sgtx) = len;
774747
sg_dma_len(&as->dma.sgrx) = len;
@@ -835,25 +808,10 @@ static void atmel_spi_next_xfer_data(struct spi_master *master,
835808
struct atmel_spi *as = spi_master_get_devdata(master);
836809
u32 len = *plen;
837810

838-
/* use scratch buffer only when rx or tx data is unspecified */
839-
if (xfer->rx_buf)
840-
*rx_dma = xfer->rx_dma + xfer->len - *plen;
841-
else {
842-
*rx_dma = as->buffer_dma;
843-
if (len > BUFFER_SIZE)
844-
len = BUFFER_SIZE;
845-
}
846-
847-
if (xfer->tx_buf)
848-
*tx_dma = xfer->tx_dma + xfer->len - *plen;
849-
else {
850-
*tx_dma = as->buffer_dma;
851-
if (len > BUFFER_SIZE)
852-
len = BUFFER_SIZE;
853-
memset(as->buffer, 0, len);
854-
dma_sync_single_for_device(&as->pdev->dev,
855-
as->buffer_dma, len, DMA_TO_DEVICE);
856-
}
811+
*rx_dma = xfer->rx_dma + xfer->len - *plen;
812+
*tx_dma = xfer->tx_dma + xfer->len - *plen;
813+
if (len > master->max_dma_len)
814+
len = master->max_dma_len;
857815

858816
*plen = len;
859817
}
@@ -1027,16 +985,12 @@ atmel_spi_pump_single_data(struct atmel_spi *as, struct spi_transfer *xfer)
1027985
u16 *rxp16;
1028986
unsigned long xfer_pos = xfer->len - as->current_remaining_bytes;
1029987

1030-
if (xfer->rx_buf) {
1031-
if (xfer->bits_per_word > 8) {
1032-
rxp16 = (u16 *)(((u8 *)xfer->rx_buf) + xfer_pos);
1033-
*rxp16 = spi_readl(as, RDR);
1034-
} else {
1035-
rxp = ((u8 *)xfer->rx_buf) + xfer_pos;
1036-
*rxp = spi_readl(as, RDR);
1037-
}
988+
if (xfer->bits_per_word > 8) {
989+
rxp16 = (u16 *)(((u8 *)xfer->rx_buf) + xfer_pos);
990+
*rxp16 = spi_readl(as, RDR);
1038991
} else {
1039-
spi_readl(as, RDR);
992+
rxp = ((u8 *)xfer->rx_buf) + xfer_pos;
993+
*rxp = spi_readl(as, RDR);
1040994
}
1041995
if (xfer->bits_per_word > 8) {
1042996
if (as->current_remaining_bytes > 2)
@@ -1075,12 +1029,10 @@ atmel_spi_pump_fifo_data(struct atmel_spi *as, struct spi_transfer *xfer)
10751029
/* Read data */
10761030
while (num_data) {
10771031
rd = spi_readl(as, RDR);
1078-
if (xfer->rx_buf) {
1079-
if (xfer->bits_per_word > 8)
1080-
*words++ = rd;
1081-
else
1082-
*bytes++ = rd;
1083-
}
1032+
if (xfer->bits_per_word > 8)
1033+
*words++ = rd;
1034+
else
1035+
*bytes++ = rd;
10841036
num_data--;
10851037
}
10861038
}
@@ -1562,29 +1514,22 @@ static int atmel_spi_probe(struct platform_device *pdev)
15621514
master->bus_num = pdev->id;
15631515
master->num_chipselect = master->dev.of_node ? 0 : 4;
15641516
master->setup = atmel_spi_setup;
1517+
master->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX);
15651518
master->transfer_one_message = atmel_spi_transfer_one_message;
15661519
master->cleanup = atmel_spi_cleanup;
15671520
master->auto_runtime_pm = true;
1521+
master->max_dma_len = SPI_MAX_DMA_XFER;
15681522
platform_set_drvdata(pdev, master);
15691523

15701524
as = spi_master_get_devdata(master);
15711525

1572-
/*
1573-
* Scratch buffer is used for throwaway rx and tx data.
1574-
* It's coherent to minimize dcache pollution.
1575-
*/
1576-
as->buffer = dma_alloc_coherent(&pdev->dev, BUFFER_SIZE,
1577-
&as->buffer_dma, GFP_KERNEL);
1578-
if (!as->buffer)
1579-
goto out_free;
1580-
15811526
spin_lock_init(&as->lock);
15821527

15831528
as->pdev = pdev;
15841529
as->regs = devm_ioremap_resource(&pdev->dev, regs);
15851530
if (IS_ERR(as->regs)) {
15861531
ret = PTR_ERR(as->regs);
1587-
goto out_free_buffer;
1532+
goto out_unmap_regs;
15881533
}
15891534
as->phybase = regs->start;
15901535
as->irq = irq;
@@ -1685,9 +1630,6 @@ static int atmel_spi_probe(struct platform_device *pdev)
16851630
clk_disable_unprepare(clk);
16861631
out_free_irq:
16871632
out_unmap_regs:
1688-
out_free_buffer:
1689-
dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer,
1690-
as->buffer_dma);
16911633
out_free:
16921634
spi_master_put(master);
16931635
return ret;
@@ -1712,9 +1654,6 @@ static int atmel_spi_remove(struct platform_device *pdev)
17121654
spi_readl(as, SR);
17131655
spin_unlock_irq(&as->lock);
17141656

1715-
dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer,
1716-
as->buffer_dma);
1717-
17181657
clk_disable_unprepare(as->clk);
17191658

17201659
pm_runtime_put_noidle(&pdev->dev);

0 commit comments

Comments
 (0)