From: Jassi Brar <jaswinder.singh@xxxxxxxxxx> Respect the set_cs() request by actually flushing the FIFOs and start/stop the SPI instance. Fixes: b0823ee35cf9b ("spi: Add spi driver for Socionext SynQuacer platform") Signed-off-by: Masahisa Kojima <masahisa.kojima@xxxxxxxxxx> Signed-off-by: Jassi Brar <jaswinder.singh@xxxxxxxxxx> --- drivers/spi/spi-synquacer.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) -- 2.14.2 diff --git a/drivers/spi/spi-synquacer.c b/drivers/spi/spi-synquacer.c index f99abd85c50a..3905d1e1dea6 100644 --- a/drivers/spi/spi-synquacer.c +++ b/drivers/spi/spi-synquacer.c @@ -365,11 +365,6 @@ static int synquacer_spi_transfer_one(struct spi_master *master, val &= ~SYNQUACER_HSSPI_DMSTOP_STOP; writel(val, sspi->regs + SYNQUACER_HSSPI_REG_DMSTART); - val = readl(sspi->regs + SYNQUACER_HSSPI_REG_FIFOCFG); - val |= SYNQUACER_HSSPI_FIFOCFG_RX_FLUSH; - val |= SYNQUACER_HSSPI_FIFOCFG_TX_FLUSH; - writel(val, sspi->regs + SYNQUACER_HSSPI_REG_FIFOCFG); - /* * See if we can transfer 4-bytes as 1 word * to maximize the FIFO buffer efficiency. @@ -463,10 +458,6 @@ static int synquacer_spi_transfer_one(struct spi_master *master, msecs_to_jiffies(SYNQUACER_HSSPI_TRANSFER_TMOUT_MSEC)); writel(0, sspi->regs + SYNQUACER_HSSPI_REG_RXE); - /* stop RX and clean RXFIFO */ - val = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTART); - val |= SYNQUACER_HSSPI_DMSTOP_STOP; - writel(val, sspi->regs + SYNQUACER_HSSPI_REG_DMSTART); sspi->rx_buf = buf; sspi->rx_words = SYNQUACER_HSSPI_FIFO_DEPTH; read_fifo(sspi); @@ -486,11 +477,25 @@ static void synquacer_spi_set_cs(struct spi_device *spi, bool enable) struct synquacer_spi *sspi = spi_master_get_devdata(spi->master); u32 val; + if (!(spi->mode & SPI_CS_HIGH)) + enable = !enable; + val = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTART); val &= ~(SYNQUACER_HSSPI_DMPSEL_CS_MASK << SYNQUACER_HSSPI_DMPSEL_CS_SHIFT); val |= spi->chip_select << SYNQUACER_HSSPI_DMPSEL_CS_SHIFT; - writel(val, sspi->regs + SYNQUACER_HSSPI_REG_DMSTART); + + if (enable) + val &= ~SYNQUACER_HSSPI_DMSTOP_STOP; + else + val |= SYNQUACER_HSSPI_DMSTOP_STOP; + + writel_relaxed(val, sspi->regs + SYNQUACER_HSSPI_REG_DMSTART); + + val = readl(sspi->regs + SYNQUACER_HSSPI_REG_FIFOCFG); + val |= SYNQUACER_HSSPI_FIFOCFG_RX_FLUSH; + val |= SYNQUACER_HSSPI_FIFOCFG_TX_FLUSH; + writel(val, sspi->regs + SYNQUACER_HSSPI_REG_FIFOCFG); } static int synquacer_spi_wait_status_update(struct synquacer_spi *sspi,