From 156907d38fed1edbc52620ed141a08b2f275b08e Mon Sep 17 00:00:00 2001 From: Mukesh Kumar Savaliya Date: Fri, 7 May 2021 22:02:52 +0530 Subject: [PATCH] spi: spi-msm-geni: Protect from register access in suspend state This change protects from unclocked access if framework calls the prepare_message() from any condition. Though driver expects to return from transfer_hardware() if PM is not enabled, this will double sure to ensure clocks are enabled before further transfer. Do not serve system suspend if driver is runtime active, let runtime suspend happen first and then serve system suspend. Change-Id: I78613a6aefa9a28f2793277152494f36b8c933e8 Signed-off-by: Mukesh Kumar Savaliya --- drivers/spi/spi-msm-geni.c | 45 +++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/drivers/spi/spi-msm-geni.c b/drivers/spi/spi-msm-geni.c index 6a0e134afbcf..5f350c02fc8a 100644 --- a/drivers/spi/spi-msm-geni.c +++ b/drivers/spi/spi-msm-geni.c @@ -1045,6 +1045,25 @@ static int spi_geni_prepare_message(struct spi_master *spi, } } + if (pm_runtime_status_suspended(mas->dev) && !mas->is_le_vm) { + if (!pm_runtime_enabled(mas->dev)) { + GENI_SE_ERR(mas->ipc, false, NULL, + "%s: System suspended\n", __func__); + return -EACCES; + } + + ret = pm_runtime_get_sync(mas->dev); + if (ret < 0) { + dev_err(mas->dev, + "%s:pm_runtime_get_sync failed %d\n", __func__, ret); + WARN_ON_ONCE(1); + pm_runtime_put_noidle(mas->dev); + /* Set device in suspended since resume failed */ + pm_runtime_set_suspended(mas->dev); + return ret; + } + } + mas->cur_xfer_mode = select_xfer_mode(spi, spi_msg); if (mas->cur_xfer_mode < 0) { @@ -2281,27 +2300,17 @@ static int spi_geni_resume(struct device *dev) static int spi_geni_suspend(struct device *dev) { int ret = 0; + struct spi_master *spi = get_spi_master(dev); + struct spi_geni_master *geni_mas = spi_master_get_devdata(spi); if (!pm_runtime_status_suspended(dev)) { - struct spi_master *spi = get_spi_master(dev); - struct spi_geni_master *geni_mas = spi_master_get_devdata(spi); - - if (list_empty(&spi->queue) && !spi->cur_msg) { - GENI_SE_ERR(geni_mas->ipc, true, dev, - "%s: Force suspend", __func__); - ret = spi_geni_runtime_suspend(dev); - if (ret) { - GENI_SE_ERR(geni_mas->ipc, true, dev, - "Force suspend Failed:%d", ret); - } else { - pm_runtime_disable(dev); - pm_runtime_set_suspended(dev); - pm_runtime_enable(dev); - } - } else { - ret = -EBUSY; - } + GENI_SE_ERR(geni_mas->ipc, true, dev, + ":%s: runtime PM is active\n", __func__); + ret = -EBUSY; + return ret; } + + GENI_SE_ERR(geni_mas->ipc, true, dev, ":%s: End\n", __func__); return ret; } #else