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 <msavaliy@codeaurora.org>
This commit is contained in:
Mukesh Kumar Savaliya 2021-05-07 22:02:52 +05:30 • committed by Gerrit - the friendly Code Review server
commit 156907d38f

View file

@ -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