From: George Stark gnstark@sberdevices.ru
commit 09738ccbc4148c62d6c8c4644ff4a099d57f49ad upstream.
Enable core clock at probe stage and disable it at remove stage. Core clock is responsible for turning on/off the entire SoC module so it should be on before the first module register is touched and be off at very last moment.
Fixes: 3adbf3427330 ("iio: adc: add a driver for the SAR ADC found in Amlogic Meson SoCs") Signed-off-by: George Stark gnstark@sberdevices.ru Link: https://lore.kernel.org/r/20230721102413.255726-2-gnstark@sberdevices.ru Cc: stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/adc/meson_saradc.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-)
--- a/drivers/iio/adc/meson_saradc.c +++ b/drivers/iio/adc/meson_saradc.c @@ -916,12 +916,6 @@ static int meson_sar_adc_hw_enable(struc goto err_vref; }
- ret = clk_prepare_enable(priv->core_clk); - if (ret) { - dev_err(dev, "failed to enable core clk\n"); - goto err_core_clk; - } - regval = FIELD_PREP(MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, 1); regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, regval); @@ -948,8 +942,6 @@ err_adc_clk: regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, MESON_SAR_ADC_REG3_ADC_EN, 0); meson_sar_adc_set_bandgap(indio_dev, false); - clk_disable_unprepare(priv->core_clk); -err_core_clk: regulator_disable(priv->vref); err_vref: meson_sar_adc_unlock(indio_dev); @@ -977,8 +969,6 @@ static void meson_sar_adc_hw_disable(str
meson_sar_adc_set_bandgap(indio_dev, false);
- clk_disable_unprepare(priv->core_clk); - regulator_disable(priv->vref);
if (!ret) @@ -1211,7 +1201,7 @@ static int meson_sar_adc_probe(struct pl if (IS_ERR(priv->clkin)) return dev_err_probe(dev, PTR_ERR(priv->clkin), "failed to get clkin\n");
- priv->core_clk = devm_clk_get(dev, "core"); + priv->core_clk = devm_clk_get_enabled(dev, "core"); if (IS_ERR(priv->core_clk)) return dev_err_probe(dev, PTR_ERR(priv->core_clk), "failed to get core clk\n");
@@ -1294,15 +1284,26 @@ static int meson_sar_adc_remove(struct p static int meson_sar_adc_suspend(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
meson_sar_adc_hw_disable(indio_dev);
+ clk_disable_unprepare(priv->core_clk); + return 0; }
static int meson_sar_adc_resume(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); + int ret; + + ret = clk_prepare_enable(priv->core_clk); + if (ret) { + dev_err(dev, "failed to enable core clk\n"); + return ret; + }
return meson_sar_adc_hw_enable(indio_dev); }