diff options
author | Leilk Liu <leilk.liu@mediatek.com> | 2015-08-20 12:19:06 +0300 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-08-20 21:09:47 +0300 |
commit | 44f636da4e71e0c73d6e29d0319a8954ce3f247a (patch) | |
tree | 0218e366c0d4109e5ab92b4a94be75ea9bc2d5b7 /drivers/spi | |
parent | c5e5cd28d7c5a18d6da6575957dd0c5243ac3e7b (diff) | |
download | linux-44f636da4e71e0c73d6e29d0319a8954ce3f247a.tar.xz |
spi: mediatek: fix spi incorrect endian usage
TX_ENDIAN/RX_ENDIAN bits define whether to reverse the endian
order of the data DMA from/to memory. The endian order should
keep the same with cpu endian.
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi-mt65xx.c | 38 |
1 files changed, 16 insertions, 22 deletions
diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index 546d70cc1e21..2eda2d1782f3 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c @@ -122,8 +122,6 @@ static const struct mtk_spi_compatible mt8173_compat = { static const struct mtk_chip_config mtk_default_chip_info = { .rx_mlsb = 1, .tx_mlsb = 1, - .tx_endian = 0, - .rx_endian = 0, }; static const struct of_device_id mtk_spi_of_match[] = { @@ -161,9 +159,13 @@ static void mtk_spi_config(struct mtk_spi *mdata, reg_val |= (chip_config->rx_mlsb << SPI_CMD_RXMSBF_OFFSET); /* set the tx/rx endian */ - reg_val &= ~(SPI_CMD_TX_ENDIAN | SPI_CMD_RX_ENDIAN); - reg_val |= (chip_config->tx_endian << SPI_CMD_TX_ENDIAN_OFFSET); - reg_val |= (chip_config->rx_endian << SPI_CMD_RX_ENDIAN_OFFSET); +#ifdef __LITTLE_ENDIAN + reg_val &= ~SPI_CMD_TX_ENDIAN; + reg_val &= ~SPI_CMD_RX_ENDIAN; +#else + reg_val |= SPI_CMD_TX_ENDIAN; + reg_val |= SPI_CMD_RX_ENDIAN; +#endif /* set finish and pause interrupt always enable */ reg_val |= SPI_CMD_FINISH_IE | SPI_CMD_PAUSE_EN; @@ -352,7 +354,7 @@ static int mtk_spi_fifo_transfer(struct spi_master *master, struct spi_device *spi, struct spi_transfer *xfer) { - int cnt, i; + int cnt; struct mtk_spi *mdata = spi_master_get_devdata(master); mdata->cur_transfer = xfer; @@ -364,10 +366,7 @@ static int mtk_spi_fifo_transfer(struct spi_master *master, cnt = xfer->len / 4 + 1; else cnt = xfer->len / 4; - - for (i = 0; i < cnt; i++) - writel(*((u32 *)xfer->tx_buf + i), - mdata->base + SPI_TX_DATA_REG); + iowrite32_rep(mdata->base + SPI_TX_DATA_REG, xfer->tx_buf, cnt); mtk_spi_enable_transfer(master); @@ -437,7 +436,7 @@ static bool mtk_spi_can_dma(struct spi_master *master, static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id) { - u32 cmd, reg_val, i; + u32 cmd, reg_val, cnt; struct spi_master *master = dev_id; struct mtk_spi *mdata = spi_master_get_devdata(master); struct spi_transfer *trans = mdata->cur_transfer; @@ -449,18 +448,13 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id) mdata->state = MTK_SPI_IDLE; if (!master->can_dma(master, master->cur_msg->spi, trans)) { - /* xfer len is not N*4 bytes every time in a transfer, - * but SPI_RX_DATA_REG must reads 4 bytes once, - * so rx buffer byte by byte. - */ if (trans->rx_buf) { - for (i = 0; i < mdata->xfer_len; i++) { - if (i % 4 == 0) - reg_val = - readl(mdata->base + SPI_RX_DATA_REG); - *((u8 *)(trans->rx_buf + i)) = - (reg_val >> ((i % 4) * 8)) & 0xff; - } + if (mdata->xfer_len % 4) + cnt = mdata->xfer_len / 4 + 1; + else + cnt = mdata->xfer_len / 4; + ioread32_rep(mdata->base + SPI_RX_DATA_REG, + trans->rx_buf, cnt); } spi_finalize_current_transfer(master); return IRQ_HANDLED; |