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

Commit 50ef13ec authored by Aditya Bavanari's avatar Aditya Bavanari
Browse files

asoc: codecs: Fix LPI TLMM GPIO invalid access issue



Runtime suspend gets called multiple times during SSR
scenarios leading to clock count mismatch. Add logic
to prevent this in all macros and pinctrl lpi driver.

Change-Id: I380631c1db8cd7d94a8909affd8c96c87f24817c
Signed-off-by: default avatarAditya Bavanari <abavanar@codeaurora.org>
parent 49ac33f0
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -1235,8 +1235,15 @@ static int rx_macro_event_handler(struct snd_soc_component *component,
				rx_priv->swr_ctrl_data[0].rx_swr_pdev,
				SWR_DEVICE_SSR_DOWN, NULL);
		}
		if (!pm_runtime_status_suspended(rx_dev))
			bolero_runtime_suspend(rx_dev);
		if ((!pm_runtime_enabled(rx_dev) ||
		     !pm_runtime_suspended(rx_dev))) {
			ret = bolero_runtime_suspend(rx_dev);
			if (!ret) {
				pm_runtime_disable(rx_dev);
				pm_runtime_set_suspended(rx_dev);
				pm_runtime_enable(rx_dev);
			}
		}
		break;
	case BOLERO_MACRO_EVT_SSR_UP:
		rx_priv->dev_up = true;
+10 −2
Original line number Diff line number Diff line
@@ -342,6 +342,7 @@ static int tx_macro_event_handler(struct snd_soc_component *component,
{
	struct device *tx_dev = NULL;
	struct tx_macro_priv *tx_priv = NULL;
	int ret = 0;

	if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
		return -EINVAL;
@@ -356,8 +357,15 @@ static int tx_macro_event_handler(struct snd_soc_component *component,
				tx_priv->swr_ctrl_data[0].tx_swr_pdev,
				SWR_DEVICE_SSR_DOWN, NULL);
		}
		if (!pm_runtime_status_suspended(tx_dev))
			bolero_runtime_suspend(tx_dev);
		if ((!pm_runtime_enabled(tx_dev) ||
		     !pm_runtime_suspended(tx_dev))) {
			ret = bolero_runtime_suspend(tx_dev);
			if (!ret) {
				pm_runtime_disable(tx_dev);
				pm_runtime_set_suspended(tx_dev);
				pm_runtime_enable(tx_dev);
			}
		}
		break;
	case BOLERO_MACRO_EVT_SSR_UP:
		/* reset swr after ssr/pdr */
+9 −2
Original line number Diff line number Diff line
@@ -252,8 +252,15 @@ static int va_macro_event_handler(struct snd_soc_component *component,
		bolero_rsc_clk_reset(va_dev, VA_CORE_CLK);
		break;
	case BOLERO_MACRO_EVT_SSR_DOWN:
		if (!pm_runtime_status_suspended(va_dev))
			bolero_runtime_suspend(va_dev);
		if ((!pm_runtime_enabled(va_dev) ||
		     !pm_runtime_suspended(va_dev))) {
			ret = bolero_runtime_suspend(va_dev);
			if (!ret) {
				pm_runtime_disable(va_dev);
				pm_runtime_set_suspended(va_dev);
				pm_runtime_enable(va_dev);
			}
		}
		break;
	default:
		break;
+9 −2
Original line number Diff line number Diff line
@@ -920,8 +920,15 @@ static int wsa_macro_event_handler(struct snd_soc_component *component,
				wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
				SWR_DEVICE_SSR_DOWN, NULL);
		}
		if (!pm_runtime_status_suspended(wsa_dev))
			bolero_runtime_suspend(wsa_dev);
		if ((!pm_runtime_enabled(wsa_dev) ||
		     !pm_runtime_suspended(wsa_dev))) {
			ret = bolero_runtime_suspend(wsa_dev);
			if (!ret) {
				pm_runtime_disable(wsa_dev);
				pm_runtime_set_suspended(wsa_dev);
				pm_runtime_enable(wsa_dev);
			}
		}
		break;
	case BOLERO_MACRO_EVT_SSR_UP:
		/* reset swr after ssr/pdr */
+34 −34
Original line number Diff line number Diff line
@@ -481,6 +481,39 @@ static int lpi_notifier_service_cb(struct notifier_block *this,
	return NOTIFY_OK;
}

int lpi_pinctrl_suspend(struct device *dev)
{
	int ret = 0;

	dev_dbg(dev, "%s: system suspend\n", __func__);

	if ((!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev))) {
		ret = lpi_pinctrl_runtime_suspend(dev);
		if (!ret) {
			/*
			 * Synchronize runtime-pm and system-pm states:
			 * At this point, we are already suspended. If
			 * runtime-pm still thinks its active, then
			 * make sure its status is in sync with HW
			 * status. The three below calls let the
			 * runtime-pm know that we are suspended
			 * already without re-invoking the suspend
			 * callback
			 */
			pm_runtime_disable(dev);
			pm_runtime_set_suspended(dev);
			pm_runtime_enable(dev);
		}
	}

	return ret;
}

int lpi_pinctrl_resume(struct device *dev)
{
	return 0;
}

static struct notifier_block service_nb = {
	.notifier_call  = lpi_notifier_service_cb,
	.priority = -INT_MAX,
@@ -489,7 +522,7 @@ static struct notifier_block service_nb = {
static void lpi_pinctrl_ssr_disable(struct device *dev, void *data)
{
	lpi_dev_up = false;
	lpi_pinctrl_runtime_suspend(dev);
	lpi_pinctrl_suspend(dev);
}

static const struct snd_event_ops lpi_pinctrl_ssr_ops = {
@@ -820,39 +853,6 @@ int lpi_pinctrl_runtime_suspend(struct device *dev)
	return 0;
}

int lpi_pinctrl_suspend(struct device *dev)
{
	int ret = 0;

	dev_dbg(dev, "%s: system suspend\n", __func__);

	if ((!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev))) {
		ret = lpi_pinctrl_runtime_suspend(dev);
		if (!ret) {
			/*
			 * Synchronize runtime-pm and system-pm states:
			 * At this point, we are already suspended. If
			 * runtime-pm still thinks its active, then
			 * make sure its status is in sync with HW
			 * status. The three below calls let the
			 * runtime-pm know that we are suspended
			 * already without re-invoking the suspend
			 * callback
			 */
			pm_runtime_disable(dev);
			pm_runtime_set_suspended(dev);
			pm_runtime_enable(dev);
		}
	}

	return ret;
}

int lpi_pinctrl_resume(struct device *dev)
{
	return 0;
}

static const struct dev_pm_ops lpi_pinctrl_dev_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(
		lpi_pinctrl_suspend,