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 | 578 | struct spi_device *spi, |
| 579 | 579 | struct spi_transfer *xfer) |
| 580 | 580 | { |
| 581 | − int ret = 1; | |
| 581 | + int ret = 0; | |
| 582 | 582 | struct rockchip_spi *rs = spi_master_get_devdata(master); |
| 583 | 583 | |
| 584 | 584 | WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) && |
| @@ -627,6 +627,8 @@ static int rockchip_spi_transfer_one( · 42 unmodified lines | ||
| 627 | 627 | spi_enable_chip(rs, 1); |
| 628 | 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 | 632 | } else { |
| 631 | 633 | spi_enable_chip(rs, 1); |
| 632 | 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 | 174 | struct sun4i_spi *sspi = spi_master_get_devdata(master); |
| 175 | 175 | unsigned int mclk_rate, div, timeout; |
| 176 | + unsigned int start, end, tx_time; | |
| 176 | 177 | unsigned int tx_len = 0; |
| 177 | 178 | int ret = 0; |
| 178 | 179 | u32 reg; |
| 179 | 180 | |
| 180 | 181 | /* We don't support transfer larger than the FIFO */ |
| 181 | 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 | 188 | reinit_completion(&sspi->done); |
| 185 | 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 | 273 | sun4i_spi_write(sspi, SUN4I_BURST_CNT_REG, SUN4I_BURST_CNT(tfr->len)); |
| 270 | 274 | sun4i_spi_write(sspi, SUN4I_XMIT_CNT_REG, SUN4I_XMIT_CNT(tx_len)); |
| 271 | 275 | |
| 272 | − /* Fill the TX FIFO */ | |
| 273 | − sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH); | |
| 276 | + /* | |
| 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 | 283 | /* Enable the interrupts */ |
| 276 | 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 | 287 | reg = sun4i_spi_read(sspi, SUN4I_CTL_REG); |
| 280 | 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 | 292 | timeout = wait_for_completion_timeout(&sspi->done, |
| 283 | − msecs_to_jiffies(1000)); | |
| 293 | + msecs_to_jiffies(tx_time)); | |
| 294 | + end = jiffies; | |
| 284 | 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 | 300 | ret = -ETIMEDOUT; |
| 286 | 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 | 161 | struct sun6i_spi *sspi = spi_master_get_devdata(master); |
| 162 | 162 | unsigned int mclk_rate, div, timeout; |
| 163 | + unsigned int start, end, tx_time; | |
| 163 | 164 | unsigned int tx_len = 0; |
| 164 | 165 | int ret = 0; |
| 165 | 166 | u32 reg; |
| @@ -269,9 +270,16 @@ static int sun6i_spi_transfer_one(struct spi_master *master, · 103 unmodified lines | ||
| 269 | 270 | reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); |
| 270 | 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 | 275 | timeout = wait_for_completion_timeout(&sspi->done, |
| 273 | − msecs_to_jiffies(1000)); | |
| 276 | + msecs_to_jiffies(tx_time)); | |
| 277 | + end = jiffies; | |
| 274 | 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 | 283 | ret = -ETIMEDOUT; |
| 276 | 284 | goto out; |
| 277 | 285 | } |
| @@ -646,6 +646,13 @@ free_master: · 645 unmodified lines | ||
| 646 | 646 | |
| 647 | 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 | 656 | pm_runtime_put_sync(&pdev->dev); |
| 650 | 657 | pm_runtime_disable(&pdev->dev); |
| 651 | 658 | |