Commit 7c30b859 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'spi-fix-v5.8-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

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
...@@ -1109,6 +1109,8 @@ static int dspi_suspend(struct device *dev) ...@@ -1109,6 +1109,8 @@ static int dspi_suspend(struct device *dev)
struct spi_controller *ctlr = dev_get_drvdata(dev); struct spi_controller *ctlr = dev_get_drvdata(dev);
struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr); struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr);
if (dspi->irq)
disable_irq(dspi->irq);
spi_controller_suspend(ctlr); spi_controller_suspend(ctlr);
clk_disable_unprepare(dspi->clk); clk_disable_unprepare(dspi->clk);
...@@ -1129,6 +1131,8 @@ static int dspi_resume(struct device *dev) ...@@ -1129,6 +1131,8 @@ static int dspi_resume(struct device *dev)
if (ret) if (ret)
return ret; return ret;
spi_controller_resume(ctlr); spi_controller_resume(ctlr);
if (dspi->irq)
enable_irq(dspi->irq);
return 0; return 0;
} }
...@@ -1385,22 +1389,22 @@ static int dspi_probe(struct platform_device *pdev) ...@@ -1385,22 +1389,22 @@ static int dspi_probe(struct platform_device *pdev)
goto poll_mode; goto poll_mode;
} }
ret = devm_request_irq(&pdev->dev, dspi->irq, dspi_interrupt, init_completion(&dspi->xfer_done);
IRQF_SHARED, pdev->name, dspi);
ret = request_threaded_irq(dspi->irq, dspi_interrupt, NULL,
IRQF_SHARED, pdev->name, dspi);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "Unable to attach DSPI interrupt\n"); dev_err(&pdev->dev, "Unable to attach DSPI interrupt\n");
goto out_clk_put; goto out_clk_put;
} }
init_completion(&dspi->xfer_done);
poll_mode: poll_mode:
if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) { if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) {
ret = dspi_request_dma(dspi, res->start); ret = dspi_request_dma(dspi, res->start);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "can't get dma channels\n"); dev_err(&pdev->dev, "can't get dma channels\n");
goto out_clk_put; goto out_free_irq;
} }
} }
...@@ -1415,11 +1419,14 @@ static int dspi_probe(struct platform_device *pdev) ...@@ -1415,11 +1419,14 @@ static int dspi_probe(struct platform_device *pdev)
ret = spi_register_controller(ctlr); ret = spi_register_controller(ctlr);
if (ret != 0) { if (ret != 0) {
dev_err(&pdev->dev, "Problem registering DSPI ctlr\n"); dev_err(&pdev->dev, "Problem registering DSPI ctlr\n");
goto out_clk_put; goto out_free_irq;
} }
return ret; return ret;
out_free_irq:
if (dspi->irq)
free_irq(dspi->irq, dspi);
out_clk_put: out_clk_put:
clk_disable_unprepare(dspi->clk); clk_disable_unprepare(dspi->clk);
out_ctlr_put: out_ctlr_put:
...@@ -1434,18 +1441,8 @@ static int dspi_remove(struct platform_device *pdev) ...@@ -1434,18 +1441,8 @@ static int dspi_remove(struct platform_device *pdev)
struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr); struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr);
/* Disconnect from the SPI framework */ /* Disconnect from the SPI framework */
dspi_release_dma(dspi);
clk_disable_unprepare(dspi->clk);
spi_unregister_controller(dspi->ctlr); 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 */ /* Disable RX and TX */
regmap_update_bits(dspi->regmap, SPI_MCR, regmap_update_bits(dspi->regmap, SPI_MCR,
SPI_MCR_DIS_TXF | SPI_MCR_DIS_RXF, SPI_MCR_DIS_TXF | SPI_MCR_DIS_RXF,
...@@ -1455,8 +1452,16 @@ static void dspi_shutdown(struct platform_device *pdev) ...@@ -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); regmap_update_bits(dspi->regmap, SPI_MCR, SPI_MCR_HALT, SPI_MCR_HALT);
dspi_release_dma(dspi); dspi_release_dma(dspi);
if (dspi->irq)
free_irq(dspi->irq, dspi);
clk_disable_unprepare(dspi->clk); 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 = { static struct platform_driver fsl_dspi_driver = {
......
...@@ -1485,6 +1485,11 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = { ...@@ -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, 0x4daa), LPSS_CNL_SSP },
{ PCI_VDEVICE(INTEL, 0x4dab), LPSS_CNL_SSP }, { PCI_VDEVICE(INTEL, 0x4dab), LPSS_CNL_SSP },
{ PCI_VDEVICE(INTEL, 0x4dfb), 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 */ /* APL */
{ PCI_VDEVICE(INTEL, 0x5ac2), LPSS_BXT_SSP }, { PCI_VDEVICE(INTEL, 0x5ac2), LPSS_BXT_SSP },
{ PCI_VDEVICE(INTEL, 0x5ac4), LPSS_BXT_SSP }, { PCI_VDEVICE(INTEL, 0x5ac4), LPSS_BXT_SSP },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment