Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb759fe6 authored by aveshala's avatar aveshala
Browse files

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: Ifb6558a46dfb383f962e8ed40ed712be7ccd4c86
Signed-off-by: default avataraveshala <quic_aveshala@quicinc.com>
parent 0a59cc88
Loading
Loading
Loading
Loading
+27 −18
Original line number Diff line number Diff line
@@ -774,6 +774,25 @@ static int spi_geni_prepare_message(struct spi_master *spi,
		}
	}

	if (pm_runtime_status_suspended(mas->dev)) {
		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) {
@@ -1837,27 +1856,17 @@ static int spi_geni_resume(struct device *dev)
static int spi_geni_suspend(struct device *dev)
{
	int ret = 0;

	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) {
	if (!pm_runtime_status_suspended(dev)) {
		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 {
			":%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