History

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

Linus Torvalds committed 10 years ago

Commit 467ce762 parents a2b0db5 2a9b27b4 files · +38 −6Browse files

Unified · Split

4 files
  1. drivers/spi/spi-rockchip.c +3 −1
  2. drivers/spi/spi-sun4i.c +19 −4
  3. drivers/spi/spi-sun6i.c +9 −1
  4. drivers/spi/spi-ti-qspi.c +7 −0
drivers/spi/spi-rockchip.c+3−1
@@ -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);
drivers/spi/spi-sun4i.c+19−4
@@ -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 }
drivers/spi/spi-sun6i.c+9−1
@@ -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 }
drivers/spi/spi-ti-qspi.c+7−0
@@ -646,6 +646,13 @@ free_master: · 645 unmodified lines
646 646
647static int ti_qspi_remove(struct platform_device *pdev)647static 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