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
578578 struct spi_device *spi,
579579 struct spi_transfer *xfer)
580580 {
581− int ret = 1;
581+ int ret = 0;
582582 struct rockchip_spi *rs = spi_master_get_devdata(master);
583583
584584 WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) &&
@@ -627,6 +627,8 @@ static int rockchip_spi_transfer_one( · 42 unmodified lines
627627 spi_enable_chip(rs, 1);
628628 ret = rockchip_spi_prepare_dma(rs);
629629 }
630+ /* successful DMA prepare means the transfer is in progress */
631+ ret = ret ? ret : 1;
630632 } else {
631633 spi_enable_chip(rs, 1);
632634 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
173173 {
174174 struct sun4i_spi *sspi = spi_master_get_devdata(master);
175175 unsigned int mclk_rate, div, timeout;
176+ unsigned int start, end, tx_time;
176177 unsigned int tx_len = 0;
177178 int ret = 0;
178179 u32 reg;
179180
180181 /* We don't support transfer larger than the FIFO */
181182 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;
183187
184188 reinit_completion(&sspi->done);
185189 sspi->tx_buf = tfr->tx_buf;
@@ -269,8 +273,12 @@ static int sun4i_spi_transfer_one(struct spi_master *master, · 83 unmodified lines
269273 sun4i_spi_write(sspi, SUN4I_BURST_CNT_REG, SUN4I_BURST_CNT(tfr->len));
270274 sun4i_spi_write(sspi, SUN4I_XMIT_CNT_REG, SUN4I_XMIT_CNT(tx_len));
271275
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);
274282
275283 /* Enable the interrupts */
276284 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
279287 reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
280288 sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH);
281289
290+ tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U);
291+ start = jiffies;
282292 timeout = wait_for_completion_timeout(&sspi->done,
283− msecs_to_jiffies(1000));
293+ msecs_to_jiffies(tx_time));
294+ end = jiffies;
284295 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);
285300 ret = -ETIMEDOUT;
286301 goto out;
287302 }
drivers/spi/spi-sun6i.c+9−1
@@ -160,6 +160,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master, · 159 unmodified lines
160160 {
161161 struct sun6i_spi *sspi = spi_master_get_devdata(master);
162162 unsigned int mclk_rate, div, timeout;
163+ unsigned int start, end, tx_time;
163164 unsigned int tx_len = 0;
164165 int ret = 0;
165166 u32 reg;
@@ -269,9 +270,16 @@ static int sun6i_spi_transfer_one(struct spi_master *master, · 103 unmodified lines
269270 reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG);
270271 sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg | SUN6I_TFR_CTL_XCH);
271272
273+ tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U);
274+ start = jiffies;
272275 timeout = wait_for_completion_timeout(&sspi->done,
273− msecs_to_jiffies(1000));
276+ msecs_to_jiffies(tx_time));
277+ end = jiffies;
274278 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);
275283 ret = -ETIMEDOUT;
276284 goto out;
277285 }
drivers/spi/spi-ti-qspi.c+7−0
@@ -646,6 +646,13 @@ free_master: · 645 unmodified lines
646646
647647 static int ti_qspi_remove(struct platform_device *pdev)
648648 {
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+
649656 pm_runtime_put_sync(&pdev->dev);
650657 pm_runtime_disable(&pdev->dev);
651658