Pull spi fixes from Mark Brown: "A few small driver-specific fixes for SPI, all in the normal important if you hit them category especially the rockchip driver fix which addresses a race which has been exposed more frequently with some recent performance improvements" * tag 'spi-fix-v4.7-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: spi: sunxi: fix transfer timeout spi: sun4i: fix FIFO limit spi: rockchip: Signal unfinished DMA transfers spi: spi-ti-qspi: Suspend the queue before removing the device
Unified · Split
| @@ -578,7 +578,7 @@ static int rockchip_spi_transfer_one( · 577 unmodified lines | |||
| 578 | struct spi_device *spi, | 578 | struct spi_device *spi, |
| 579 | struct spi_transfer *xfer) | 579 | struct spi_transfer *xfer) |
| 580 | { | 580 | { |
| 581 | int ret = 1; | 581 | int ret = 0; |
| 582 | struct rockchip_spi *rs = spi_master_get_devdata(master); | 582 | struct rockchip_spi *rs = spi_master_get_devdata(master); |
| 583 | 583 | ||
| 584 | WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) && | 584 | WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) && |
| @@ -627,6 +627,8 @@ static int rockchip_spi_transfer_one( · 42 unmodified lines | |||
| 627 | spi_enable_chip(rs, 1); | 627 | spi_enable_chip(rs, 1); |
| 628 | ret = rockchip_spi_prepare_dma(rs); | 628 | ret = rockchip_spi_prepare_dma(rs); |
| 629 | } | 629 | } |
| 630 | /* successful DMA prepare means the transfer is in progress */ | ||
| 631 | ret = ret ? ret : 1; | ||
| 630 | } else { | 632 | } else { |
| 631 | spi_enable_chip(rs, 1); | 633 | spi_enable_chip(rs, 1); |
| 632 | ret = rockchip_spi_pio_transfer(rs); | 634 | ret = rockchip_spi_pio_transfer(rs); |
| @@ -173,13 +173,17 @@ static int sun4i_spi_transfer_one(struct spi_master *master, · 172 unmodified lines | |||
| 173 | { | 173 | { |
| 174 | struct sun4i_spi *sspi = spi_master_get_devdata(master); | 174 | struct sun4i_spi *sspi = spi_master_get_devdata(master); |
| 175 | unsigned int mclk_rate, div, timeout; | 175 | unsigned int mclk_rate, div, timeout; |
| 176 | unsigned int start, end, tx_time; | ||
| 176 | unsigned int tx_len = 0; | 177 | unsigned int tx_len = 0; |
| 177 | int ret = 0; | 178 | int ret = 0; |
| 178 | u32 reg; | 179 | u32 reg; |
| 179 | 180 | ||
| 180 | /* We don't support transfer larger than the FIFO */ | 181 | /* We don't support transfer larger than the FIFO */ |
| 181 | if (tfr->len > SUN4I_FIFO_DEPTH) | 182 | if (tfr->len > SUN4I_FIFO_DEPTH) |
| 182 | return -EINVAL; | 183 | return -EMSGSIZE; |
| 184 | |||
| 185 | if (tfr->tx_buf && tfr->len >= SUN4I_FIFO_DEPTH) | ||
| 186 | return -EMSGSIZE; | ||
| 183 | 187 | ||
| 184 | reinit_completion(&sspi->done); | 188 | reinit_completion(&sspi->done); |
| 185 | sspi->tx_buf = tfr->tx_buf; | 189 | sspi->tx_buf = tfr->tx_buf; |
| @@ -269,8 +273,12 @@ static int sun4i_spi_transfer_one(struct spi_master *master, · 83 unmodified lines | |||
| 269 | sun4i_spi_write(sspi, SUN4I_BURST_CNT_REG, SUN4I_BURST_CNT(tfr->len)); | 273 | sun4i_spi_write(sspi, SUN4I_BURST_CNT_REG, SUN4I_BURST_CNT(tfr->len)); |
| 270 | sun4i_spi_write(sspi, SUN4I_XMIT_CNT_REG, SUN4I_XMIT_CNT(tx_len)); | 274 | sun4i_spi_write(sspi, SUN4I_XMIT_CNT_REG, SUN4I_XMIT_CNT(tx_len)); |
| 271 | 275 | ||
| 272 | /* Fill the TX FIFO */ | 276 | /* |
| 273 | sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH); | 277 | * Fill the TX FIFO |
| 278 | * Filling the FIFO fully causes timeout for some reason | ||
| 279 | * at least on spi2 on A10s | ||
| 280 | */ | ||
| 281 | sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH - 1); | ||
| 274 | 282 | ||
| 275 | /* Enable the interrupts */ | 283 | /* Enable the interrupts */ |
| 276 | sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, SUN4I_INT_CTL_TC); | 284 | sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, SUN4I_INT_CTL_TC); |
| @@ -279,9 +287,16 @@ static int sun4i_spi_transfer_one(struct spi_master *master, · 2 unmodified lines | |||
| 279 | reg = sun4i_spi_read(sspi, SUN4I_CTL_REG); | 287 | reg = sun4i_spi_read(sspi, SUN4I_CTL_REG); |
| 280 | sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH); | 288 | sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH); |
| 281 | 289 | ||
| 290 | tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U); | ||
| 291 | start = jiffies; | ||
| 282 | timeout = wait_for_completion_timeout(&sspi->done, | 292 | timeout = wait_for_completion_timeout(&sspi->done, |
| 283 | msecs_to_jiffies(1000)); | 293 | msecs_to_jiffies(tx_time)); |
| 294 | end = jiffies; | ||
| 284 | if (!timeout) { | 295 | if (!timeout) { |
| 296 | dev_warn(&master->dev, | ||
| 297 | "%s: timeout transferring %u bytes@%iHz for %i(%i)ms", | ||
| 298 | dev_name(&spi->dev), tfr->len, tfr->speed_hz, | ||
| 299 | jiffies_to_msecs(end - start), tx_time); | ||
| 285 | ret = -ETIMEDOUT; | 300 | ret = -ETIMEDOUT; |
| 286 | goto out; | 301 | goto out; |
| 287 | } | 302 | } |
| @@ -160,6 +160,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master, · 159 unmodified lines | |||
| 160 | { | 160 | { |
| 161 | struct sun6i_spi *sspi = spi_master_get_devdata(master); | 161 | struct sun6i_spi *sspi = spi_master_get_devdata(master); |
| 162 | unsigned int mclk_rate, div, timeout; | 162 | unsigned int mclk_rate, div, timeout; |
| 163 | unsigned int start, end, tx_time; | ||
| 163 | unsigned int tx_len = 0; | 164 | unsigned int tx_len = 0; |
| 164 | int ret = 0; | 165 | int ret = 0; |
| 165 | u32 reg; | 166 | u32 reg; |
| @@ -269,9 +270,16 @@ static int sun6i_spi_transfer_one(struct spi_master *master, · 103 unmodified lines | |||
| 269 | reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); | 270 | reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); |
| 270 | sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg | SUN6I_TFR_CTL_XCH); | 271 | sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg | SUN6I_TFR_CTL_XCH); |
| 271 | 272 | ||
| 273 | tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U); | ||
| 274 | start = jiffies; | ||
| 272 | timeout = wait_for_completion_timeout(&sspi->done, | 275 | timeout = wait_for_completion_timeout(&sspi->done, |
| 273 | msecs_to_jiffies(1000)); | 276 | msecs_to_jiffies(tx_time)); |
| 277 | end = jiffies; | ||
| 274 | if (!timeout) { | 278 | if (!timeout) { |
| 279 | dev_warn(&master->dev, | ||
| 280 | "%s: timeout transferring %u bytes@%iHz for %i(%i)ms", | ||
| 281 | dev_name(&spi->dev), tfr->len, tfr->speed_hz, | ||
| 282 | jiffies_to_msecs(end - start), tx_time); | ||
| 275 | ret = -ETIMEDOUT; | 283 | ret = -ETIMEDOUT; |
| 276 | goto out; | 284 | goto out; |
| 277 | } | 285 | } |
| @@ -646,6 +646,13 @@ free_master: · 645 unmodified lines | |||
| 646 | 646 | ||
| 647 | static int ti_qspi_remove(struct platform_device *pdev) | 647 | static int ti_qspi_remove(struct platform_device *pdev) |
| 648 | { | 648 | { |
| 649 | struct ti_qspi *qspi = platform_get_drvdata(pdev); | ||
| 650 | int rc; | ||
| 651 | |||
| 652 | rc = spi_master_suspend(qspi->master); | ||
| 653 | if (rc) | ||
| 654 | return rc; | ||
| 655 | |||
| 649 | pm_runtime_put_sync(&pdev->dev); | 656 | pm_runtime_put_sync(&pdev->dev); |
| 650 | pm_runtime_disable(&pdev->dev); | 657 | pm_runtime_disable(&pdev->dev); |
| 651 | 658 | ||