diff options
| -rw-r--r-- | drivers/spi/spi-mt65xx.c | 37 |
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 | ||
| 79 | struct mtk_spi_compatible { | 79 | struct 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 | ||
| 416 | static int mtk_spi_setup(struct spi_device *spi) | 419 | static int mtk_spi_setup(struct spi_device *spi) |
| @@ -451,7 +454,33 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id) | |||
| 451 | ®_val, remainder); | 454 | ®_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(®_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 | ||
