From: Leilk Liu <leilk.liu@xxxxxxxxxxxx> [ Upstream commit dc5fa590273890a8541ce6e999d606bfb2d73797 ] 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@xxxxxxxxxxxx> Link: https://lore.kernel.org/r/20210508060214.1485-1-leilk.liu@xxxxxxxxxxxx Signed-off-by: Mark Brown <broonie@xxxxxxxxxx> Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> --- drivers/spi/spi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 8da4fe475b84..5495138c257e 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -3463,9 +3463,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); @@ -3476,11 +3479,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) || -- 2.30.2