soc: lpi: force lpi runtime suspend during adsp ssr

During adsp SSR, lpi runtime suspend is not called and
hw vote clks are not reset. Force LPI runtime suspend
during adsp SSR to avoid kernel panic.

Change-Id: I153c5826a282d7beb175a41a55e2d6bf5907eb62
Signed-off-by: Meng Wang <mengw@codeaurora.org>
This commit is contained in:
Meng Wang 2019-06-25 17:28:59 +08:00
commit ea4ace171f

View file

@ -111,6 +111,7 @@ struct lpi_gpio_state {
struct clk *lpass_core_hw_vote;
struct mutex slew_access_lock;
bool core_hw_vote_status;
struct mutex core_hw_vote_lock;
};
static const char *const lpi_gpio_groups[] = {
@ -134,6 +135,8 @@ static const char *const lpi_gpio_functions[] = {
[LPI_GPIO_FUNC_INDEX_FUNC5] = LPI_GPIO_FUNC_FUNC5,
};
int lpi_pinctrl_runtime_suspend(struct device *dev);
static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr)
{
int ret;
@ -464,7 +467,11 @@ static struct notifier_block service_nb = {
static void lpi_pinctrl_ssr_disable(struct device *dev, void *data)
{
struct lpi_gpio_state *state = dev_get_drvdata(dev);
lpi_dev_up = false;
if (state->core_hw_vote_status)
lpi_pinctrl_runtime_suspend(dev);
}
static const struct snd_event_ops lpi_pinctrl_ssr_ops = {
@ -664,6 +671,7 @@ static int lpi_pinctrl_probe(struct platform_device *pdev)
state->chip.can_sleep = false;
mutex_init(&state->slew_access_lock);
mutex_init(&state->core_hw_vote_lock);
state->ctrl = devm_pinctrl_register(dev, pctrldesc, state);
if (IS_ERR(state->ctrl))
@ -724,6 +732,7 @@ err_snd_evt:
err_range:
gpiochip_remove(&state->chip);
err_chip:
mutex_destroy(&state->core_hw_vote_lock);
mutex_destroy(&state->slew_access_lock);
err_io:
return ret;
@ -739,6 +748,7 @@ static int lpi_pinctrl_remove(struct platform_device *pdev)
snd_event_client_deregister(&pdev->dev);
audio_notifier_deregister("lpi_tlmm");
gpiochip_remove(&state->chip);
mutex_destroy(&state->core_hw_vote_lock);
mutex_destroy(&state->slew_access_lock);
return 0;
@ -761,6 +771,7 @@ int lpi_pinctrl_runtime_resume(struct device *dev)
return 0;
}
mutex_lock(&state->core_hw_vote_lock);
ret = clk_prepare_enable(state->lpass_core_hw_vote);
if (ret < 0)
dev_err(dev, "%s:lpass core hw island enable failed\n",
@ -769,6 +780,7 @@ int lpi_pinctrl_runtime_resume(struct device *dev)
state->core_hw_vote_status = true;
pm_runtime_set_autosuspend_delay(dev, LPI_AUTO_SUSPEND_DELAY);
mutex_unlock(&state->core_hw_vote_lock);
return 0;
}
@ -781,10 +793,12 @@ int lpi_pinctrl_runtime_suspend(struct device *dev)
return 0;
}
mutex_lock(&state->core_hw_vote_lock);
if (state->core_hw_vote_status) {
clk_disable_unprepare(state->lpass_core_hw_vote);
state->core_hw_vote_status = false;
}
mutex_unlock(&state->core_hw_vote_lock);
return 0;
}