diff options
Diffstat (limited to 'drivers/spi/spi-bcm63xx.c')
| -rw-r--r-- | drivers/spi/spi-bcm63xx.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index b56210734caa..4c549f166b0f 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -247,6 +247,20 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first, if (t->rx_buf) { do_rx = true; + + /* + * In certain hardware implementations, there appears to be a + * hidden accumulator that tracks the number of bytes written into + * the hardware FIFO, and this accumulator overrides the length in + * the SPI_MSG_CTL register. + * + * Therefore, for read-only transfers, we need to write some dummy + * value into the FIFO to keep the accumulator tracking the correct + * length. + */ + if (!t->tx_buf) + memset_io(bs->tx_io + len, 0xFF, t->len); + /* prepend is half-duplex write only */ if (t == first) prepend_len = 0; @@ -568,8 +582,8 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) host->auto_runtime_pm = true; bs->msg_type_shift = bs->reg_offsets[SPI_MSG_TYPE_SHIFT]; bs->msg_ctl_width = bs->reg_offsets[SPI_MSG_CTL_WIDTH]; - bs->tx_io = (u8 *)(bs->regs + bs->reg_offsets[SPI_MSG_DATA]); - bs->rx_io = (const u8 *)(bs->regs + bs->reg_offsets[SPI_RX_DATA]); + bs->tx_io = bs->regs + bs->reg_offsets[SPI_MSG_DATA]; + bs->rx_io = bs->regs + bs->reg_offsets[SPI_RX_DATA]; /* Initialize hardware */ ret = clk_prepare_enable(bs->clk); |
