summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-11-27 22:29:53 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2020-11-27 22:29:53 +0300
commit87c301ca911a3bee68900ee475fe536eebd9bc41 (patch)
tree2026c9c61a4f57a958ae6175eba44957bfa0e2bd /drivers
parentf594139d68ccdd64fe9c546b17189b298fa7ecd3 (diff)
parent0abdb0fba07322ce960d32a92a64847b3009b2e2 (diff)
downloadlinux-87c301ca911a3bee68900ee475fe536eebd9bc41.tar.xz
Merge tag 'spi-fix-v5.10-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi fixes from Mark Brown: "A few fixes for v5.10, one for the core which fixes some potential races for controllers with multiple chip selects when configuration of the chip select for one client device races with the addition and initial setup of an additional client" * tag 'spi-fix-v5.10-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: spi: dw: Fix spi registration for controllers overriding CS spi: imx: fix the unbalanced spi runtime pm management spi: spi-nxp-fspi: fix fspi panic by unexpected interrupts spi: Take the SPI IO-mutex in the spi_setup() method
Diffstat (limited to 'drivers')
-rw-r--r--drivers/spi/spi-dw-core.c3
-rw-r--r--drivers/spi/spi-imx.c1
-rw-r--r--drivers/spi/spi-nxp-fspi.c7
-rw-r--r--drivers/spi/spi.c5
4 files changed, 15 insertions, 1 deletions
diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c
index 0b2236ade412..c33866f747db 100644
--- a/drivers/spi/spi-dw-core.c
+++ b/drivers/spi/spi-dw-core.c
@@ -875,7 +875,8 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
master->set_cs = dw_spi_set_cs;
master->transfer_one = dw_spi_transfer_one;
master->handle_err = dw_spi_handle_err;
- master->mem_ops = &dws->mem_ops;
+ if (dws->mem_ops.exec_op)
+ master->mem_ops = &dws->mem_ops;
master->max_speed_hz = dws->max_freq;
master->dev.of_node = dev->of_node;
master->dev.fwnode = dev->fwnode;
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 4b80e27ecdbf..0b597905ee72 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -1686,6 +1686,7 @@ static int spi_imx_probe(struct platform_device *pdev)
pm_runtime_set_autosuspend_delay(spi_imx->dev, MXC_RPM_TIMEOUT);
pm_runtime_use_autosuspend(spi_imx->dev);
+ pm_runtime_get_noresume(spi_imx->dev);
pm_runtime_set_active(spi_imx->dev);
pm_runtime_enable(spi_imx->dev);
diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
index 0d41406c036d..ab9035662717 100644
--- a/drivers/spi/spi-nxp-fspi.c
+++ b/drivers/spi/spi-nxp-fspi.c
@@ -1001,6 +1001,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
struct resource *res;
struct nxp_fspi *f;
int ret;
+ u32 reg;
ctlr = spi_alloc_master(&pdev->dev, sizeof(*f));
if (!ctlr)
@@ -1032,6 +1033,12 @@ static int nxp_fspi_probe(struct platform_device *pdev)
goto err_put_ctrl;
}
+ /* Clear potential interrupts */
+ reg = fspi_readl(f, f->iobase + FSPI_INTR);
+ if (reg)
+ fspi_writel(f, reg, f->iobase + FSPI_INTR);
+
+
/* find the resources - controller memory mapped space */
if (is_acpi_node(f->dev->fwnode))
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 05c75f890ace..fc9a59788d2e 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -3372,12 +3372,15 @@ int spi_setup(struct spi_device *spi)
if (!spi->max_speed_hz)
spi->max_speed_hz = spi->controller->max_speed_hz;
+ mutex_lock(&spi->controller->io_mutex);
+
if (spi->controller->setup)
status = spi->controller->setup(spi);
if (spi->controller->auto_runtime_pm && spi->controller->set_cs) {
status = pm_runtime_get_sync(spi->controller->dev.parent);
if (status < 0) {
+ mutex_unlock(&spi->controller->io_mutex);
pm_runtime_put_noidle(spi->controller->dev.parent);
dev_err(&spi->controller->dev, "Failed to power device: %d\n",
status);
@@ -3399,6 +3402,8 @@ int spi_setup(struct spi_device *spi)
spi_set_cs(spi, false);
}
+ mutex_unlock(&spi->controller->io_mutex);
+
if (spi->rt && !spi->controller->rt) {
spi->controller->rt = true;
spi_set_thread_rt(spi->controller);