Commit 7c30b859 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull spi fixes from Mark Brown:
 "A batch of fixes for the Freescale DSPI driver fixing some serious
  issues with removal of active devices and one resume case, plus a few
  new PCI IDs for Intel platforms"

* tag 'spi-fix-v5.8-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: pxa2xx: Add support for Intel Tiger Lake PCH-H
  spi: spi-fsl-dspi: Initialize completion before possible interrupt
  spi: spi-fsl-dspi: Fix external abort on interrupt in resume or exit paths
  spi: spi-fsl-dspi: Fix lockup if device is shutdown during SPI transfer
  spi: spi-fsl-dspi: Fix lockup if device is removed during SPI transfer
parents be88fef3 cf961fce
Loading
Loading
Loading
Loading
+22 −17
Original line number Diff line number Diff line
@@ -1109,6 +1109,8 @@ static int dspi_suspend(struct device *dev)
	struct spi_controller *ctlr = dev_get_drvdata(dev);
	struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr);

	if (dspi->irq)
		disable_irq(dspi->irq);
	spi_controller_suspend(ctlr);
	clk_disable_unprepare(dspi->clk);

@@ -1129,6 +1131,8 @@ static int dspi_resume(struct device *dev)
	if (ret)
		return ret;
	spi_controller_resume(ctlr);
	if (dspi->irq)
		enable_irq(dspi->irq);

	return 0;
}
@@ -1385,22 +1389,22 @@ static int dspi_probe(struct platform_device *pdev)
		goto poll_mode;
	}

	ret = devm_request_irq(&pdev->dev, dspi->irq, dspi_interrupt,
	init_completion(&dspi->xfer_done);

	ret = request_threaded_irq(dspi->irq, dspi_interrupt, NULL,
				   IRQF_SHARED, pdev->name, dspi);
	if (ret < 0) {
		dev_err(&pdev->dev, "Unable to attach DSPI interrupt\n");
		goto out_clk_put;
	}

	init_completion(&dspi->xfer_done);

poll_mode:

	if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) {
		ret = dspi_request_dma(dspi, res->start);
		if (ret < 0) {
			dev_err(&pdev->dev, "can't get dma channels\n");
			goto out_clk_put;
			goto out_free_irq;
		}
	}

@@ -1415,11 +1419,14 @@ poll_mode:
	ret = spi_register_controller(ctlr);
	if (ret != 0) {
		dev_err(&pdev->dev, "Problem registering DSPI ctlr\n");
		goto out_clk_put;
		goto out_free_irq;
	}

	return ret;

out_free_irq:
	if (dspi->irq)
		free_irq(dspi->irq, dspi);
out_clk_put:
	clk_disable_unprepare(dspi->clk);
out_ctlr_put:
@@ -1434,18 +1441,8 @@ static int dspi_remove(struct platform_device *pdev)
	struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr);

	/* Disconnect from the SPI framework */
	dspi_release_dma(dspi);
	clk_disable_unprepare(dspi->clk);
	spi_unregister_controller(dspi->ctlr);

	return 0;
}

static void dspi_shutdown(struct platform_device *pdev)
{
	struct spi_controller *ctlr = platform_get_drvdata(pdev);
	struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr);

	/* Disable RX and TX */
	regmap_update_bits(dspi->regmap, SPI_MCR,
			   SPI_MCR_DIS_TXF | SPI_MCR_DIS_RXF,
@@ -1455,8 +1452,16 @@ static void dspi_shutdown(struct platform_device *pdev)
	regmap_update_bits(dspi->regmap, SPI_MCR, SPI_MCR_HALT, SPI_MCR_HALT);

	dspi_release_dma(dspi);
	if (dspi->irq)
		free_irq(dspi->irq, dspi);
	clk_disable_unprepare(dspi->clk);
	spi_unregister_controller(dspi->ctlr);

	return 0;
}

static void dspi_shutdown(struct platform_device *pdev)
{
	dspi_remove(pdev);
}

static struct platform_driver fsl_dspi_driver = {
+5 −0
Original line number Diff line number Diff line
@@ -1485,6 +1485,11 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = {
	{ PCI_VDEVICE(INTEL, 0x4daa), LPSS_CNL_SSP },
	{ PCI_VDEVICE(INTEL, 0x4dab), LPSS_CNL_SSP },
	{ PCI_VDEVICE(INTEL, 0x4dfb), LPSS_CNL_SSP },
	/* TGL-H */
	{ PCI_VDEVICE(INTEL, 0x43aa), LPSS_CNL_SSP },
	{ PCI_VDEVICE(INTEL, 0x43ab), LPSS_CNL_SSP },
	{ PCI_VDEVICE(INTEL, 0x43fb), LPSS_CNL_SSP },
	{ PCI_VDEVICE(INTEL, 0x43fd), LPSS_CNL_SSP },
	/* APL */
	{ PCI_VDEVICE(INTEL, 0x5ac2), LPSS_BXT_SSP },
	{ PCI_VDEVICE(INTEL, 0x5ac4), LPSS_BXT_SSP },