Commit 33d0c9c5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull spi fixes from Mark Brown:
 "There are a couple of nasty issues fixed here in the axiado and
  rockchip drivers. We've also got more of the fixes from Johan here,
  this time for the two Cadence drivers, plus a couple of other similar
  fixes from John and Felix"

* tag 'spi-fix-v7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: amlogic-spisg: initialize completion before requesting IRQ
  spi: axiado: replace usleep_range() with udelay() in IRQ path
  spi: cadence-quadspi: fix runtime pm and clock imbalance on unbind
  spi: cadence-quadspi: fix unclocked access on unbind
  spi: cadence-quadspi: fix clock imbalance on probe failure
  spi: cadence-quadspi: fix runtime pm disable imbalance on probe failure
  spi: cadence: fix clock imbalance on probe failure
  spi: cadence: fix unclocked access on unbind
  spi: rockchip: Drop unused and broken CR0 macros
  spi: rockchip: Read ISR, not IMR, to detect cs-inactive IRQ
  spi: rzv2h-rspi: Fix silent failure in clock setup error path
parents d8b0e2ef 8c0f9cd1
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -794,6 +794,7 @@ static int aml_spisg_probe(struct platform_device *pdev)

	dma_set_max_seg_size(&pdev->dev, SPISG_BLOCK_MAX);

	init_completion(&spisg->completion);
	ret = devm_request_irq(&pdev->dev, irq, aml_spisg_irq, 0, NULL, spisg);
	if (ret) {
		dev_err(&pdev->dev, "irq request failed\n");
@@ -806,8 +807,6 @@ static int aml_spisg_probe(struct platform_device *pdev)
		goto out_clk;
	}

	init_completion(&spisg->completion);

	pm_runtime_put(&spisg->pdev->dev);

	return 0;
+1 −1
Original line number Diff line number Diff line
@@ -201,7 +201,7 @@ static void ax_spi_fill_tx_fifo(struct ax_spi *xspi)
		 * then spi control did't work thoroughly, add one byte delay
		 */
		if (ax_spi_read(xspi, AX_SPI_IVR) & AX_SPI_IVR_TFOV)
			usleep_range(10, 10);
			udelay(10);
		if (xspi->tx_buf)
			ax_spi_write_b(xspi, AX_SPI_TXFIFO, *xspi->tx_buf++);
		else
+18 −18
Original line number Diff line number Diff line
@@ -1860,14 +1860,10 @@ static int cqspi_probe(struct platform_device *pdev)
	if (irq < 0)
		return -ENXIO;

	ret = pm_runtime_set_active(dev);
	if (ret)
		return ret;

	ret = clk_bulk_prepare_enable(CLK_QSPI_NUM, cqspi->clks);
	if (ret) {
		dev_err(dev, "Cannot enable QSPI clocks.\n");
		goto disable_rpm;
		return ret;
	}

	/* Obtain QSPI reset control */
@@ -1962,10 +1958,11 @@ static int cqspi_probe(struct platform_device *pdev)
	cqspi->sclk = 0;

	if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) {
		pm_runtime_enable(dev);
		pm_runtime_set_autosuspend_delay(dev, CQSPI_AUTOSUSPEND_TIMEOUT);
		pm_runtime_use_autosuspend(dev);
		pm_runtime_get_noresume(dev);
		pm_runtime_set_active(dev);
		pm_runtime_enable(dev);
	}

	host->num_chipselect = cqspi->num_chipselect;
@@ -1977,7 +1974,7 @@ static int cqspi_probe(struct platform_device *pdev)
		ret = cqspi_request_mmap_dma(cqspi);
		if (ret == -EPROBE_DEFER) {
			dev_err_probe(&pdev->dev, ret, "Failed to request mmap DMA\n");
			goto disable_controller;
			goto disable_rpm;
		}
	}

@@ -1995,14 +1992,16 @@ static int cqspi_probe(struct platform_device *pdev)
release_dma_chan:
	if (cqspi->rx_chan)
		dma_release_channel(cqspi->rx_chan);
disable_controller:
disable_rpm:
	if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) {
		pm_runtime_disable(dev);
		pm_runtime_set_suspended(dev);
		pm_runtime_put_noidle(dev);
		pm_runtime_dont_use_autosuspend(dev);
	}
	cqspi_controller_enable(cqspi, 0);
disable_clks:
	if (pm_runtime_get_sync(&pdev->dev) >= 0)
	clk_bulk_disable_unprepare(CLK_QSPI_NUM, cqspi->clks);
disable_rpm:
	if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM)))
		pm_runtime_disable(dev);

	return ret;
}
@@ -2026,18 +2025,19 @@ static void cqspi_remove(struct platform_device *pdev)
	if (cqspi->rx_chan)
		dma_release_channel(cqspi->rx_chan);

	cqspi_controller_enable(cqspi, 0);


	if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM)))
		ret = pm_runtime_get_sync(&pdev->dev);

	if (ret >= 0)
	if (ret >= 0) {
		cqspi_controller_enable(cqspi, 0);
		clk_bulk_disable_unprepare(CLK_QSPI_NUM, cqspi->clks);
	}

	if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) {
		pm_runtime_put_sync(&pdev->dev);
		pm_runtime_disable(&pdev->dev);
		pm_runtime_set_suspended(&pdev->dev);
		pm_runtime_put_noidle(&pdev->dev);
		pm_runtime_dont_use_autosuspend(&pdev->dev);
	}
}

+13 −2
Original line number Diff line number Diff line
@@ -741,7 +741,6 @@ static int cdns_spi_probe(struct platform_device *pdev)
		/* Set to default valid value */
		ctlr->max_speed_hz = xspi->clk_rate / 4;
		xspi->speed_hz = ctlr->max_speed_hz;
		pm_runtime_put_autosuspend(&pdev->dev);
	} else {
		ctlr->mode_bits |= SPI_NO_CS;
		ctlr->target_abort = cdns_target_abort;
@@ -752,12 +751,17 @@ static int cdns_spi_probe(struct platform_device *pdev)
		goto clk_dis_all;
	}

	if (!spi_controller_is_target(ctlr))
		pm_runtime_put_autosuspend(&pdev->dev);

	return ret;

clk_dis_all:
	if (!spi_controller_is_target(ctlr)) {
		pm_runtime_disable(&pdev->dev);
		pm_runtime_set_suspended(&pdev->dev);
		pm_runtime_put_noidle(&pdev->dev);
		pm_runtime_dont_use_autosuspend(&pdev->dev);
	}
remove_ctlr:
	spi_controller_put(ctlr);
@@ -776,16 +780,23 @@ static void cdns_spi_remove(struct platform_device *pdev)
{
	struct spi_controller *ctlr = platform_get_drvdata(pdev);
	struct cdns_spi *xspi = spi_controller_get_devdata(ctlr);
	int ret = 0;

	if (!spi_controller_is_target(ctlr))
		ret = pm_runtime_get_sync(&pdev->dev);

	spi_controller_get(ctlr);

	spi_unregister_controller(ctlr);

	if (ret >= 0)
		cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE);

	if (!spi_controller_is_target(ctlr)) {
		pm_runtime_disable(&pdev->dev);
		pm_runtime_set_suspended(&pdev->dev);
		pm_runtime_put_noidle(&pdev->dev);
		pm_runtime_dont_use_autosuspend(&pdev->dev);
	}

	spi_controller_put(ctlr);
+2 −4
Original line number Diff line number Diff line
@@ -98,7 +98,6 @@
#define CR0_FRF_MICROWIRE			0x2

#define CR0_XFM_OFFSET				18
#define CR0_XFM_MASK				(0x03 << SPI_XFM_OFFSET)
#define CR0_XFM_TR					0x0
#define CR0_XFM_TO					0x1
#define CR0_XFM_RO					0x2
@@ -109,8 +108,6 @@

#define CR0_SOI_OFFSET				23

#define CR0_MTM_OFFSET				0x21

/* Bit fields in SER, 2bit */
#define SER_MASK					0x3

@@ -357,7 +354,8 @@ static irqreturn_t rockchip_spi_isr(int irq, void *dev_id)
	struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);

	/* When int_cs_inactive comes, spi target abort */
	if (rs->cs_inactive && readl_relaxed(rs->regs + ROCKCHIP_SPI_IMR) & INT_CS_INACTIVE) {
	if (rs->cs_inactive &&
	    (readl_relaxed(rs->regs + ROCKCHIP_SPI_ISR) & INT_CS_INACTIVE)) {
		ctlr->target_abort(ctlr);
		writel_relaxed(0, rs->regs + ROCKCHIP_SPI_IMR);
		writel_relaxed(0xffffffff, rs->regs + ROCKCHIP_SPI_ICR);
Loading