diff options
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi-dw-mid.c | 8 | ||||
-rw-r--r-- | drivers/spi/spi-dw-mmio.c | 5 | ||||
-rw-r--r-- | drivers/spi/spi-dw.c | 10 |
3 files changed, 21 insertions, 2 deletions
diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index 177e1f5ec62b..f9757a370699 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -106,6 +106,8 @@ static void mid_spi_dma_exit(struct dw_spi *dws) dmaengine_terminate_sync(dws->rxchan); dma_release_channel(dws->rxchan); } + + dw_writel(dws, DW_SPI_DMACR, 0); } static irqreturn_t dma_transfer(struct dw_spi *dws) @@ -152,6 +154,8 @@ static void dw_spi_dma_tx_done(void *arg) clear_bit(TX_BUSY, &dws->dma_chan_busy); if (test_bit(RX_BUSY, &dws->dma_chan_busy)) return; + + dw_writel(dws, DW_SPI_DMACR, 0); spi_finalize_current_transfer(dws->master); } @@ -199,6 +203,8 @@ static void dw_spi_dma_rx_done(void *arg) clear_bit(RX_BUSY, &dws->dma_chan_busy); if (test_bit(TX_BUSY, &dws->dma_chan_busy)) return; + + dw_writel(dws, DW_SPI_DMACR, 0); spi_finalize_current_transfer(dws->master); } @@ -292,6 +298,8 @@ static void mid_spi_dma_stop(struct dw_spi *dws) dmaengine_terminate_sync(dws->rxchan); clear_bit(RX_BUSY, &dws->dma_chan_busy); } + + dw_writel(dws, DW_SPI_DMACR, 0); } static const struct dw_spi_dma_ops mfld_dma_ops = { diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index 398f7926cf92..0894b4c09496 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c @@ -184,6 +184,7 @@ static int dw_spi_mmio_probe(struct platform_device *pdev) int (*init_func)(struct platform_device *pdev, struct dw_spi_mmio *dwsmmio); struct dw_spi_mmio *dwsmmio; + struct resource *mem; struct dw_spi *dws; int ret; int num_cs; @@ -196,10 +197,12 @@ static int dw_spi_mmio_probe(struct platform_device *pdev) dws = &dwsmmio->dws; /* Get basic io resource and map it */ - dws->regs = devm_platform_ioremap_resource(pdev, 0); + dws->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem); if (IS_ERR(dws->regs)) return PTR_ERR(dws->regs); + dws->paddr = mem->start; + dws->irq = platform_get_irq(pdev, 0); if (dws->irq < 0) return dws->irq; /* -ENXIO */ diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 6de196df9c96..450c8218caeb 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -124,8 +124,16 @@ static inline void dw_spi_debugfs_remove(struct dw_spi *dws) void dw_spi_set_cs(struct spi_device *spi, bool enable) { struct dw_spi *dws = spi_controller_get_devdata(spi->controller); + bool cs_high = !!(spi->mode & SPI_CS_HIGH); - if (!enable) + /* + * DW SPI controller demands any native CS being set in order to + * proceed with data transfer. So in order to activate the SPI + * communications we must set a corresponding bit in the Slave + * Enable register no matter whether the SPI core is configured to + * support active-high or active-low CS level. + */ + if (cs_high == enable) dw_writel(dws, DW_SPI_SER, BIT(spi->chip_select)); else if (dws->cs_override) dw_writel(dws, DW_SPI_SER, 0); |