From 4b489349e161ef0f1722845faa8ba245477d1f3a Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 19 Jun 2019 13:50:13 +0800 Subject: [PATCH] soc: lpi: check if vote clk is enabled before accessing LPI GPIO HW vote clock may fail to get enabled. Check if hw vote clk is enabled in lpi_gpio_read and lpi_gpio_write to avoid kernel panic. Change-Id: I077e5c61058d9d90be98ff3a0c0834049ad7e584 Signed-off-by: Meng Wang --- soc/pinctrl-lpi.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index ff9e9406c438..15c32253668a 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -136,7 +136,8 @@ static const char *const lpi_gpio_functions[] = { static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr) { - int ret; + int ret = 0; + struct lpi_gpio_state *state = dev_get_drvdata(lpi_dev); if (!lpi_dev_up) { pr_err_ratelimited("%s: ADSP is down due to SSR, return\n", @@ -144,11 +145,18 @@ static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr) return 0; } pm_runtime_get_sync(lpi_dev); + if (!state->core_hw_vote_status) { + pr_err_ratelimited("%s: core hw vote clk is not enabled\n", + __func__); + ret = -EINVAL; + goto err; + } ret = ioread32(pad->base + pad->offset + addr); if (ret < 0) pr_err("%s: read 0x%x failed\n", __func__, addr); +err: pm_runtime_mark_last_busy(lpi_dev); pm_runtime_put_autosuspend(lpi_dev); return ret; @@ -157,18 +165,27 @@ static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr) 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); + int ret = 0; + if (!lpi_dev_up) { pr_err_ratelimited("%s: ADSP is down due to SSR, return\n", - __func__); + __func__); return 0; } pm_runtime_get_sync(lpi_dev); + if (!state->core_hw_vote_status) { + pr_err_ratelimited("%s: core hw vote clk is not enabled\n", + __func__); + ret = -EINVAL; + goto err; + } iowrite32(val, pad->base + pad->offset + addr); - +err: pm_runtime_mark_last_busy(lpi_dev); pm_runtime_put_autosuspend(lpi_dev); - return 0; + return ret; } static int lpi_gpio_get_groups_count(struct pinctrl_dev *pctldev)