aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2023-02-19 21:44:39 +0100
committerJonathan Cameron <Jonathan.Cameron@huawei.com>2023-03-11 12:18:28 +0000
commit4ab8bef1eaa534d3669852f2fe22e0f1c86c1426 (patch)
tree02e0686018ee85ddd096acdaf58250756d30db57
parentc286b0472ca8d76092c1f4fb782c6745b26e74f6 (diff)
downloadiio-4ab8bef1eaa534d3669852f2fe22e0f1c86c1426.tar.gz
iio: adc: meson_saradc: Better handle BL30 not releasing the hardware
meson_sar_adc_lock() might return an error if BL30 doesn't release its lock on the hardware. Just returning early from .remove() is wrong however as this keeps the clocks and regulators on which is never cleaned up later. Given the BL30 not giving up its lock is a strong hint for broken behaviour, and there is nothing we can do about that: Just clean up ignoring the fact that we're not holding the lock. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Link: https://lore.kernel.org/r/20230219204439.1641640-1-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
-rw-r--r--drivers/iio/adc/meson_saradc.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c
index 85b6826cc10cf9..18937a262af6f8 100644
--- a/drivers/iio/adc/meson_saradc.c
+++ b/drivers/iio/adc/meson_saradc.c
@@ -957,14 +957,18 @@ err_lock:
return ret;
}
-static int meson_sar_adc_hw_disable(struct iio_dev *indio_dev)
+static void meson_sar_adc_hw_disable(struct iio_dev *indio_dev)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
int ret;
+ /*
+ * If taking the lock fails we have to assume that BL30 is broken. The
+ * best we can do then is to release the resources anyhow.
+ */
ret = meson_sar_adc_lock(indio_dev);
if (ret)
- return ret;
+ dev_err(indio_dev->dev.parent, "Failed to lock ADC (%pE)\n", ERR_PTR(ret));
clk_disable_unprepare(priv->adc_clk);
@@ -977,9 +981,8 @@ static int meson_sar_adc_hw_disable(struct iio_dev *indio_dev)
regulator_disable(priv->vref);
- meson_sar_adc_unlock(indio_dev);
-
- return 0;
+ if (!ret)
+ meson_sar_adc_unlock(indio_dev);
}
static irqreturn_t meson_sar_adc_irq(int irq, void *data)
@@ -1283,14 +1286,18 @@ static int meson_sar_adc_remove(struct platform_device *pdev)
iio_device_unregister(indio_dev);
- return meson_sar_adc_hw_disable(indio_dev);
+ meson_sar_adc_hw_disable(indio_dev);
+
+ return 0;
}
static int meson_sar_adc_suspend(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
- return meson_sar_adc_hw_disable(indio_dev);
+ meson_sar_adc_hw_disable(indio_dev);
+
+ return 0;
}
static int meson_sar_adc_resume(struct device *dev)