diff options
author | Leilk Liu <leilk.liu@mediatek.com> | 2021-05-08 09:02:14 +0300 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2021-05-10 15:00:28 +0300 |
commit | dc5fa590273890a8541ce6e999d606bfb2d73797 (patch) | |
tree | 8cfe049a27dba5dd046e314a1047644eeead04fa /drivers/spi/spi.c | |
parent | 680ec0549a055eb464dce6ffb4bfb736ef87236e (diff) | |
download | linux-dc5fa590273890a8541ce6e999d606bfb2d73797.tar.xz |
spi: take the SPI IO-mutex in the spi_set_cs_timing method
this patch takes the io_mutex to prevent an unprotected HW
register modification in the set_cs_timing callback.
Fixes: 4cea6b8cc34e ("spi: add power control when set_cs_timing")
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Link: https://lore.kernel.org/r/20210508060214.1485-1-leilk.liu@mediatek.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r-- | drivers/spi/spi.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index f9885c096563..a565e7d6bf3b 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -3457,9 +3457,12 @@ int spi_set_cs_timing(struct spi_device *spi, struct spi_delay *setup, if (spi->controller->set_cs_timing && !(spi->cs_gpiod || gpio_is_valid(spi->cs_gpio))) { + mutex_lock(&spi->controller->io_mutex); + if (spi->controller->auto_runtime_pm) { status = pm_runtime_get_sync(parent); if (status < 0) { + mutex_unlock(&spi->controller->io_mutex); pm_runtime_put_noidle(parent); dev_err(&spi->controller->dev, "Failed to power device: %d\n", status); @@ -3470,11 +3473,13 @@ int spi_set_cs_timing(struct spi_device *spi, struct spi_delay *setup, hold, inactive); pm_runtime_mark_last_busy(parent); pm_runtime_put_autosuspend(parent); - return status; } else { - return spi->controller->set_cs_timing(spi, setup, hold, + status = spi->controller->set_cs_timing(spi, setup, hold, inactive); } + + mutex_unlock(&spi->controller->io_mutex); + return status; } if ((setup && setup->unit == SPI_DELAY_UNIT_SCK) || |