spi: spi-msm-geni: Keep device to suspend if PM call fails

If the runtime PM is disabled, call to get_sync() will fail. In this
scenario, keep device to suspend state and return the error with warn
stack. This should help balance the runtime PM count in get_sync()
failed scenario.

In addition, if the runtime PM is found to be disabled, decide to
return an error and let framework retry the transfers.

Change-Id: Ic3336df922973050ebea00ab4dbab6ef0c61d765
Signed-off-by: Anil Veshala <quic_aveshala@quicinc.com>
This commit is contained in:
Anil Veshala committed 2021-12-29 15:17:37 +05:30
1 parent 0a59cc889f
commit 08c0ed4f3c
1 file changed
+40
+40
View File
@@ -751,12 +751,24 @@ static int spi_geni_prepare_message(struct spi_master *spi,
if (mas->shared_ee) {
if (mas->setup) {
/* Client to respect system suspend */
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);
goto exit_prepare_message;
}
ret = 0;
@@ -882,6 +894,14 @@ static int spi_geni_prepare_transfer_hardware(struct spi_master *spi)
/* Adjust the IB based on the max speed of the slave.*/
rsc->ib = max_speed * DEFAULT_BUS_WIDTH;
/* Client to respect system suspend */
if (!pm_runtime_enabled(mas->dev)) {
GENI_SE_ERR(mas->ipc, false, NULL,
"%s: System suspended\n", __func__);
return -EACCES;
}
if (mas->gsi_mode && !mas->shared_ee) {
struct se_geni_rsc *rsc;
int ret = 0;
@@ -900,7 +920,10 @@ static int spi_geni_prepare_transfer_hardware(struct spi_master *spi)
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);
goto exit_prepare_transfer_hardware;
}
ret = 0;
@@ -1288,6 +1311,17 @@ static int spi_geni_transfer_one(struct spi_master *spi,
GENI_SE_DBG(mas->ipc, false, mas->dev,
"current xfer_timeout:%lu ms.\n", xfer_timeout);
/* Double check PM status, client might have not taken wakelock and
* continue to queue more transfers. Post auto-suspend, system suspend
* can keep driver to forced suspend, hence it's client's responsibility
* to not allow system suspend to trigger.
*/
if (pm_runtime_status_suspended(mas->dev)) {
GENI_SE_ERR(mas->ipc, true, mas->dev,
"%s: device is PM suspended\n", __func__);
return -EACCES;
}
if (mas->cur_xfer_mode != GSI_DMA) {
reinit_completion(&mas->xfer_done);
ret = setup_fifo_xfer(xfer, mas, slv->mode, spi);
@@ -1764,10 +1798,12 @@ static int spi_geni_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "Failed to register SPI master\n");
goto spi_geni_probe_unmap;
}
dev_info(&pdev->dev, "%s: completed\n", __func__);
return ret;
spi_geni_probe_unmap:
devm_iounmap(&pdev->dev, geni_mas->base);
spi_geni_probe_err:
dev_info(&pdev->dev, "%s: ret:%d\n", __func__, ret);
spi_master_put(spi);
return ret;
}
@@ -1791,6 +1827,8 @@ static int spi_geni_runtime_suspend(struct device *dev)
struct spi_master *spi = get_spi_master(dev);
struct spi_geni_master *geni_mas = spi_master_get_devdata(spi);
GENI_SE_DBG(geni_mas->ipc, false, NULL, "%s:\n", __func__);
if (geni_mas->shared_ee)
goto exit_rt_suspend;
@@ -1813,6 +1851,8 @@ static int spi_geni_runtime_resume(struct device *dev)
struct spi_master *spi = get_spi_master(dev);
struct spi_geni_master *geni_mas = spi_master_get_devdata(spi);
GENI_SE_DBG(geni_mas->ipc, false, NULL, "%s:\n", __func__);
if (geni_mas->shared_ee)
goto exit_rt_resume;