[PATCH 3/3] iio: adc: ti_am335x_adc: convert rest of probe to devm_ functions

From: Alexandru Ardelean
Date: Tue Apr 28 2020 - 07:14:26 EST


This change converts the rest of the probe to use devm_ functions.
Consequently this allows us to remove the remove hook.

It tries to preserve the initial order or probe & remove.
The devm_add_action() call hooks the cleanup routine (what's needed still
for the remove part).
If that doesn't work the DMA channel is cleaned up manually inside the
probe hook. This done (like this) because the remove hook has a peculiar
cleanup that tries to restore a step-mask, and that only seems to happen on
the remove hook, and not in any probe error-cleanup paths.

Signed-off-by: Alexandru Ardelean <alexandru.ardelean@xxxxxxxxxx>
---
drivers/iio/adc/ti_am335x_adc.c | 63 +++++++++++++++++----------------
1 file changed, 32 insertions(+), 31 deletions(-)

diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index 03b2ab649cc3..9fac83e036c1 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -562,6 +562,18 @@ static int tiadc_request_dma(struct platform_device *pdev,
return -ENOMEM;
}

+static void tiadc_cleanup_dma(struct tiadc_device *adc_dev)
+{
+ struct tiadc_dma *dma = &adc_dev->dma;
+
+ if (!dma->chan)
+ return;
+
+ dma_free_coherent(dma->chan->device->dev, DMA_BUFFER_SIZE,
+ dma->buf, dma->addr);
+ dma_release_channel(dma->chan);
+}
+
static int tiadc_parse_dt(struct platform_device *pdev,
struct tiadc_device *adc_dev)
{
@@ -593,6 +605,17 @@ static int tiadc_parse_dt(struct platform_device *pdev,
return 0;
}

+static void tiadc_cleanup(void *data)
+{
+ struct tiadc_device *adc_dev = data;
+ u32 step_en;
+
+ tiadc_cleanup_dma(adc_dev);
+
+ step_en = get_adc_step_mask(adc_dev);
+ am335x_tsc_se_clr(adc_dev->mfd_tscadc, step_en);
+}
+
static int tiadc_probe(struct platform_device *pdev)
{
struct iio_dev *indio_dev;
@@ -635,48 +658,27 @@ static int tiadc_probe(struct platform_device *pdev)
IRQF_SHARED,
&tiadc_buffer_setup_ops);

+ err = devm_iio_device_register(&pdev->dev, indio_dev);
if (err)
- goto err_free_channels;
-
- err = iio_device_register(indio_dev);
- if (err)
- goto err_buffer_unregister;
+ return err;

platform_set_drvdata(pdev, indio_dev);

err = tiadc_request_dma(pdev, adc_dev);
if (err && err == -EPROBE_DEFER)
- goto err_dma;
+ return err;
+
+ err = devm_add_action(&pdev->dev, tiadc_cleanup, adc_dev);
+ if (err)
+ goto err_free_dma;

return 0;

-err_dma:
- iio_device_unregister(indio_dev);
-err_buffer_unregister:
-err_free_channels:
+err_free_dma:
+ tiadc_cleanup_dma(adc_dev);
return err;
}

-static int tiadc_remove(struct platform_device *pdev)
-{
- struct iio_dev *indio_dev = platform_get_drvdata(pdev);
- struct tiadc_device *adc_dev = iio_priv(indio_dev);
- struct tiadc_dma *dma = &adc_dev->dma;
- u32 step_en;
-
- if (dma->chan) {
- dma_free_coherent(dma->chan->device->dev, DMA_BUFFER_SIZE,
- dma->buf, dma->addr);
- dma_release_channel(dma->chan);
- }
- iio_device_unregister(indio_dev);
-
- step_en = get_adc_step_mask(adc_dev);
- am335x_tsc_se_clr(adc_dev->mfd_tscadc, step_en);
-
- return 0;
-}
-
static int __maybe_unused tiadc_suspend(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
@@ -723,7 +725,6 @@ static struct platform_driver tiadc_driver = {
.of_match_table = ti_adc_dt_ids,
},
.probe = tiadc_probe,
- .remove = tiadc_remove,
};
module_platform_driver(tiadc_driver);

--
2.17.1