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

Commit 052f12a0 authored by Soumya Managoli's avatar Soumya Managoli Committed by Gerrit - the friendly Code Review server
Browse files

soc: Synchronize RESET event and lpi ops in legacy driver



Race condition is observed during ADSP SSR
when LPI pinctrl receives the SERVICE DOWN
event and lpi gpio read or write is executed.
Synchronize these functions using lock.

Change-Id: Ie80c41e260b4b572c1c3ede8a2a58a3a0332fe7d
Signed-off-by: default avatarSoumya Managoli <smanag@codeaurora.org>
parent 63a7be89
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ struct lpi_gpio_state {
	char __iomem	*base;
	struct clk *lpass_core_hw_vote;
	bool core_hw_vote_status;
	struct mutex lpi_mutex;
};

static const char *const lpi_gpio_groups[] = {
@@ -120,12 +121,16 @@ static const char *const lpi_gpio_functions[] = {
static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr)
{
	int ret;
	struct lpi_gpio_state *state = dev_get_drvdata(lpi_dev);

	mutex_lock(&state->lpi_mutex);
	if (!lpi_dev_up) {
		pr_err_ratelimited("%s: ADSP is down due to SSR, return\n",
				   __func__);
		mutex_unlock(&state->lpi_mutex);
		return 0;
	}

	pm_runtime_get_sync(lpi_dev);

	ret = ioread32(pad->base + pad->offset + addr);
@@ -134,15 +139,20 @@ static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr)

	pm_runtime_mark_last_busy(lpi_dev);
	pm_runtime_put_autosuspend(lpi_dev);
	mutex_unlock(&state->lpi_mutex);
	return ret;
}

static int lpi_gpio_write(struct lpi_gpio_pad *pad, unsigned int addr,
			  unsigned int val)
{
	struct lpi_gpio_state *state = dev_get_drvdata(lpi_dev);

	mutex_lock(&state->lpi_mutex);
	if (!lpi_dev_up) {
		pr_err_ratelimited("%s: ADSP is down due to SSR, return\n",
				   __func__);
		mutex_unlock(&state->lpi_mutex);
		return 0;
	}
	pm_runtime_get_sync(lpi_dev);
@@ -151,6 +161,7 @@ static int lpi_gpio_write(struct lpi_gpio_pad *pad, unsigned int addr,

	pm_runtime_mark_last_busy(lpi_dev);
	pm_runtime_put_autosuspend(lpi_dev);
	mutex_unlock(&state->lpi_mutex);
	return 0;
}

@@ -382,8 +393,10 @@ static int lpi_notifier_service_cb(struct notifier_block *this,
				   unsigned long opcode, void *ptr)
{
	static bool initial_boot = true;
	struct lpi_gpio_state *state = dev_get_drvdata(lpi_dev);

	pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode);
	mutex_lock(&state->lpi_mutex);

	switch (opcode) {
	case AUDIO_NOTIFIER_SERVICE_DOWN:
@@ -403,6 +416,7 @@ static int lpi_notifier_service_cb(struct notifier_block *this,
	default:
		break;
	}
	mutex_unlock(&state->lpi_mutex);
	return NOTIFY_OK;
}

@@ -643,6 +657,7 @@ static int lpi_pinctrl_probe(struct platform_device *pdev)
	pm_runtime_use_autosuspend(&pdev->dev);
	pm_runtime_set_suspended(&pdev->dev);
	pm_runtime_enable(&pdev->dev);
	mutex_init(&state->lpi_mutex);

	return 0;

@@ -658,6 +673,7 @@ static int lpi_pinctrl_remove(struct platform_device *pdev)
{
	struct lpi_gpio_state *state = platform_get_drvdata(pdev);

	mutex_destroy(&state->lpi_mutex);
	pm_runtime_disable(&pdev->dev);
	pm_runtime_set_suspended(&pdev->dev);