aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/spi-mt65xx.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 899d7a8f0889..278867a31950 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -73,7 +73,7 @@
73#define MTK_SPI_IDLE 0 73#define MTK_SPI_IDLE 0
74#define MTK_SPI_PAUSED 1 74#define MTK_SPI_PAUSED 1
75 75
76#define MTK_SPI_MAX_FIFO_SIZE 32 76#define MTK_SPI_MAX_FIFO_SIZE 32U
77#define MTK_SPI_PACKET_SIZE 1024 77#define MTK_SPI_PACKET_SIZE 1024
78 78
79struct mtk_spi_compatible { 79struct mtk_spi_compatible {
@@ -333,7 +333,7 @@ static int mtk_spi_fifo_transfer(struct spi_master *master,
333 struct mtk_spi *mdata = spi_master_get_devdata(master); 333 struct mtk_spi *mdata = spi_master_get_devdata(master);
334 334
335 mdata->cur_transfer = xfer; 335 mdata->cur_transfer = xfer;
336 mdata->xfer_len = xfer->len; 336 mdata->xfer_len = min(MTK_SPI_MAX_FIFO_SIZE, xfer->len);
337 mtk_spi_prepare_transfer(master, xfer); 337 mtk_spi_prepare_transfer(master, xfer);
338 mtk_spi_setup_packet(master); 338 mtk_spi_setup_packet(master);
339 339
@@ -410,7 +410,10 @@ static bool mtk_spi_can_dma(struct spi_master *master,
410 struct spi_device *spi, 410 struct spi_device *spi,
411 struct spi_transfer *xfer) 411 struct spi_transfer *xfer)
412{ 412{
413 return xfer->len > MTK_SPI_MAX_FIFO_SIZE; 413 /* Buffers for DMA transactions must be 4-byte aligned */
414 return (xfer->len > MTK_SPI_MAX_FIFO_SIZE &&
415 (unsigned long)xfer->tx_buf % 4 == 0 &&
416 (unsigned long)xfer->rx_buf % 4 == 0);
414} 417}
415 418
416static int mtk_spi_setup(struct spi_device *spi) 419static int mtk_spi_setup(struct spi_device *spi)
@@ -451,7 +454,33 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
451 &reg_val, remainder); 454 &reg_val, remainder);
452 } 455 }
453 } 456 }
454 spi_finalize_current_transfer(master); 457
458 trans->len -= mdata->xfer_len;
459 if (!trans->len) {
460 spi_finalize_current_transfer(master);
461 return IRQ_HANDLED;
462 }
463
464 if (trans->tx_buf)
465 trans->tx_buf += mdata->xfer_len;
466 if (trans->rx_buf)
467 trans->rx_buf += mdata->xfer_len;
468
469 mdata->xfer_len = min(MTK_SPI_MAX_FIFO_SIZE, trans->len);
470 mtk_spi_setup_packet(master);
471
472 cnt = trans->len / 4;
473 iowrite32_rep(mdata->base + SPI_TX_DATA_REG, trans->tx_buf, cnt);
474
475 remainder = trans->len % 4;
476 if (remainder > 0) {
477 reg_val = 0;
478 memcpy(&reg_val, trans->tx_buf + (cnt * 4), remainder);
479 writel(reg_val, mdata->base + SPI_TX_DATA_REG);
480 }
481
482 mtk_spi_enable_transfer(master);
483
455 return IRQ_HANDLED; 484 return IRQ_HANDLED;
456 } 485 }
457 486