diff options
Diffstat (limited to 'drivers/spi/spi-mt65xx.c')
| -rw-r--r-- | drivers/spi/spi-mt65xx.c | 37 | 
1 files changed, 21 insertions, 16 deletions
| diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index 86bf45667a04..3dc31627c655 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c @@ -98,6 +98,7 @@ struct mtk_spi {  	struct clk *parent_clk, *sel_clk, *spi_clk;  	struct spi_transfer *cur_transfer;  	u32 xfer_len; +	u32 num_xfered;  	struct scatterlist *tx_sgl, *rx_sgl;  	u32 tx_sgl_len, rx_sgl_len;  	const struct mtk_spi_compatible *dev_comp; @@ -385,6 +386,7 @@ static int mtk_spi_fifo_transfer(struct spi_master *master,  	mdata->cur_transfer = xfer;  	mdata->xfer_len = min(MTK_SPI_MAX_FIFO_SIZE, xfer->len); +	mdata->num_xfered = 0;  	mtk_spi_prepare_transfer(master, xfer);  	mtk_spi_setup_packet(master); @@ -415,6 +417,7 @@ static int mtk_spi_dma_transfer(struct spi_master *master,  	mdata->tx_sgl_len = 0;  	mdata->rx_sgl_len = 0;  	mdata->cur_transfer = xfer; +	mdata->num_xfered = 0;  	mtk_spi_prepare_transfer(master, xfer); @@ -482,7 +485,7 @@ static int mtk_spi_setup(struct spi_device *spi)  static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)  { -	u32 cmd, reg_val, cnt, remainder; +	u32 cmd, reg_val, cnt, remainder, len;  	struct spi_master *master = dev_id;  	struct mtk_spi *mdata = spi_master_get_devdata(master);  	struct spi_transfer *trans = mdata->cur_transfer; @@ -497,36 +500,38 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)  		if (trans->rx_buf) {  			cnt = mdata->xfer_len / 4;  			ioread32_rep(mdata->base + SPI_RX_DATA_REG, -				     trans->rx_buf, cnt); +				     trans->rx_buf + mdata->num_xfered, cnt);  			remainder = mdata->xfer_len % 4;  			if (remainder > 0) {  				reg_val = readl(mdata->base + SPI_RX_DATA_REG); -				memcpy(trans->rx_buf + (cnt * 4), -					®_val, remainder); +				memcpy(trans->rx_buf + +					mdata->num_xfered + +					(cnt * 4), +					®_val, +					remainder);  			}  		} -		trans->len -= mdata->xfer_len; -		if (!trans->len) { +		mdata->num_xfered += mdata->xfer_len; +		if (mdata->num_xfered == trans->len) {  			spi_finalize_current_transfer(master);  			return IRQ_HANDLED;  		} -		if (trans->tx_buf) -			trans->tx_buf += mdata->xfer_len; -		if (trans->rx_buf) -			trans->rx_buf += mdata->xfer_len; - -		mdata->xfer_len = min(MTK_SPI_MAX_FIFO_SIZE, trans->len); +		len = trans->len - mdata->num_xfered; +		mdata->xfer_len = min(MTK_SPI_MAX_FIFO_SIZE, len);  		mtk_spi_setup_packet(master); -		cnt = trans->len / 4; -		iowrite32_rep(mdata->base + SPI_TX_DATA_REG, trans->tx_buf, cnt); +		cnt = len / 4; +		iowrite32_rep(mdata->base + SPI_TX_DATA_REG, +				trans->tx_buf + mdata->num_xfered, cnt); -		remainder = trans->len % 4; +		remainder = len % 4;  		if (remainder > 0) {  			reg_val = 0; -			memcpy(®_val, trans->tx_buf + (cnt * 4), remainder); +			memcpy(®_val, +				trans->tx_buf + (cnt * 4) + mdata->num_xfered, +				remainder);  			writel(reg_val, mdata->base + SPI_TX_DATA_REG);  		} |