Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'spi-fix-v4.7-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

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

+38 -6
+3 -1
drivers/spi/spi-rockchip.c
··· 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 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);
+19 -4
drivers/spi/spi-sun4i.c
··· 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; ··· 273 269 sun4i_spi_write(sspi, SUN4I_BURST_CNT_REG, SUN4I_BURST_CNT(tfr->len)); 274 270 sun4i_spi_write(sspi, SUN4I_XMIT_CNT_REG, SUN4I_XMIT_CNT(tx_len)); 275 271 276 - /* Fill the TX FIFO */ 277 - sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH); 272 + /* 273 + * Fill the TX FIFO 274 + * Filling the FIFO fully causes timeout for some reason 275 + * at least on spi2 on A10s 276 + */ 277 + sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH - 1); 278 278 279 279 /* Enable the interrupts */ 280 280 sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, SUN4I_INT_CTL_TC); ··· 287 279 reg = sun4i_spi_read(sspi, SUN4I_CTL_REG); 288 280 sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH); 289 281 282 + tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U); 283 + start = jiffies; 290 284 timeout = wait_for_completion_timeout(&sspi->done, 291 - msecs_to_jiffies(1000)); 285 + msecs_to_jiffies(tx_time)); 286 + end = jiffies; 292 287 if (!timeout) { 288 + dev_warn(&master->dev, 289 + "%s: timeout transferring %u bytes@%iHz for %i(%i)ms", 290 + dev_name(&spi->dev), tfr->len, tfr->speed_hz, 291 + jiffies_to_msecs(end - start), tx_time); 293 292 ret = -ETIMEDOUT; 294 293 goto out; 295 294 }
+9 -1
drivers/spi/spi-sun6i.c
··· 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; ··· 270 269 reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); 271 270 sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg | SUN6I_TFR_CTL_XCH); 272 271 272 + tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U); 273 + start = jiffies; 273 274 timeout = wait_for_completion_timeout(&sspi->done, 274 - msecs_to_jiffies(1000)); 275 + msecs_to_jiffies(tx_time)); 276 + end = jiffies; 275 277 if (!timeout) { 278 + dev_warn(&master->dev, 279 + "%s: timeout transferring %u bytes@%iHz for %i(%i)ms", 280 + dev_name(&spi->dev), tfr->len, tfr->speed_hz, 281 + jiffies_to_msecs(end - start), tx_time); 276 282 ret = -ETIMEDOUT; 277 283 goto out; 278 284 }
+7
drivers/spi/spi-ti-qspi.c
··· 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