diff options
Diffstat (limited to 'drivers/spi/spi-davinci.c')
-rw-r--r-- | drivers/spi/spi-davinci.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 5688be245c68..a29934422356 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -459,7 +459,7 @@ static bool davinci_spi_can_dma(struct spi_controller *host, static int davinci_spi_check_error(struct davinci_spi *dspi, int int_status) { - struct device *sdev = dspi->bitbang.master->dev.parent; + struct device *sdev = dspi->bitbang.ctlr->dev.parent; if (int_status & SPIFLG_TIMEOUT_MASK) { dev_err(sdev, "SPI Time-out Error\n"); @@ -570,6 +570,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) u32 errors = 0; struct davinci_spi_config *spicfg; struct davinci_spi_platform_data *pdata; + unsigned long timeout; dspi = spi_controller_get_devdata(spi->controller); pdata = &dspi->pdata; @@ -661,7 +662,12 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) /* Wait for the transfer to complete */ if (spicfg->io_type != SPI_IO_TYPE_POLL) { - if (wait_for_completion_timeout(&dspi->done, HZ) == 0) + timeout = DIV_ROUND_UP(t->speed_hz, MSEC_PER_SEC); + timeout = DIV_ROUND_UP(t->len * 8, timeout); + /* Assume we are at most 2x slower than the nominal bus speed */ + timeout = 2 * msecs_to_jiffies(timeout); + + if (wait_for_completion_timeout(&dspi->done, timeout) == 0) errors = SPIFLG_TIMEOUT_MASK; } else { while (dspi->rcount > 0 || dspi->wcount > 0) { @@ -742,7 +748,7 @@ static irqreturn_t davinci_spi_irq(s32 irq, void *data) static int davinci_spi_request_dma(struct davinci_spi *dspi) { - struct device *sdev = dspi->bitbang.master->dev.parent; + struct device *sdev = dspi->bitbang.ctlr->dev.parent; dspi->dma_rx = dma_request_chan(sdev, "rx"); if (IS_ERR(dspi->dma_rx)) @@ -913,7 +919,7 @@ static int davinci_spi_probe(struct platform_device *pdev) if (ret) goto free_host; - dspi->bitbang.master = host; + dspi->bitbang.ctlr = host; dspi->clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(dspi->clk)) { @@ -984,6 +990,9 @@ static int davinci_spi_probe(struct platform_device *pdev) return ret; free_dma: + /* This bit needs to be cleared to disable dpsi->clk */ + clear_io_bits(dspi->base + SPIGCR1, SPIGCR1_POWERDOWN_MASK); + if (dspi->dma_rx) { dma_release_channel(dspi->dma_rx); dma_release_channel(dspi->dma_tx); @@ -1013,6 +1022,9 @@ static void davinci_spi_remove(struct platform_device *pdev) spi_bitbang_stop(&dspi->bitbang); + /* This bit needs to be cleared to disable dpsi->clk */ + clear_io_bits(dspi->base + SPIGCR1, SPIGCR1_POWERDOWN_MASK); + if (dspi->dma_rx) { dma_release_channel(dspi->dma_rx); dma_release_channel(dspi->dma_tx); @@ -1027,7 +1039,7 @@ static struct platform_driver davinci_spi_driver = { .of_match_table = of_match_ptr(davinci_spi_of_match), }, .probe = davinci_spi_probe, - .remove_new = davinci_spi_remove, + .remove = davinci_spi_remove, }; module_platform_driver(davinci_spi_driver); |