Re: [PATCH] iio: adc: lpc18xx_adc: Convert probe to device managed version

From: Alexandru Ardelean
Date: Mon Oct 11 2021 - 04:09:46 EST


On Fri, Oct 8, 2021 at 9:31 PM André Gustavo Nakagomi Lopez
<andregnl@xxxxxx> wrote:
>
> The remove function and the goto sections are not necessary if devm
> functions are used.
>
> Convert device register to devm version. Add hook functions to release
> device resources, and use them inside probe with devm_add_action,
> which will release resources on driver detach.
>
> To maintain the order of which device resources were released/reseted,
> register the hook functions as soon as resources are obtained/initialized.
> Since devres actions are called on driver detach, the remove
> function and the error-handling goto sections are no longer necessary.
>

Hey,

Patch looks good overall.

A few notes:
1. you can now remove the "platform_set_drvdata(....)" call. The
private data is no longer needed.

> Signed-off-by: André Gustavo Nakagomi Lopez <andregnl@xxxxxx>
> ---
> I was not able to test the patch due to the fact I do not have the necessary hardware.
> drivers/iio/adc/lpc18xx_adc.c | 60 +++++++++++++++++++----------------
> 1 file changed, 33 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/iio/adc/lpc18xx_adc.c b/drivers/iio/adc/lpc18xx_adc.c
> index 3566990ae87d..7b6ba5e4a003 100644
> --- a/drivers/iio/adc/lpc18xx_adc.c
> +++ b/drivers/iio/adc/lpc18xx_adc.c
> @@ -115,6 +115,23 @@ static const struct iio_info lpc18xx_adc_info = {
> .read_raw = lpc18xx_adc_read_raw,
> };
>
> +static void lpc18xx_writel(void *data)
> +{
> + struct lpc18xx_adc *adc = data;
> +
> + writel(0, adc->base + LPC18XX_ADC_CR);
> +}
> +
> +static void lpc18xx_clk_disable_unprepare(void *clk)
> +{
> + clk_disable_unprepare(clk);
> +}
> +
> +static void lpc18xx_regulator_disable(void *vref)
> +{
> + regulator_disable(vref);
> +}
> +
> static int lpc18xx_adc_probe(struct platform_device *pdev)
> {
> struct iio_dev *indio_dev;
> @@ -163,46 +180,36 @@ static int lpc18xx_adc_probe(struct platform_device *pdev)
> return ret;
> }
>
> + ret = devm_add_action_or_reset(&pdev->dev, lpc18xx_regulator_disable, adc->vref);
> + if (ret)
> + return ret;
> +
> ret = clk_prepare_enable(adc->clk);
> if (ret) {
> dev_err(&pdev->dev, "unable to enable clock\n");
> - goto dis_reg;
> + return ret;
> }
>
> + ret = devm_add_action_or_reset(&pdev->dev, lpc18xx_clk_disable_unprepare,

You can leave this as-is.but "lpc18xx_clk_disable" also works.
No strong opinion

> + adc->clk);
> + if (ret)
> + return ret;
> +
> adc->cr_reg = (clkdiv << LPC18XX_ADC_CR_CLKDIV_SHIFT) |
> LPC18XX_ADC_CR_PDN;
> writel(adc->cr_reg, adc->base + LPC18XX_ADC_CR);
>
> - ret = iio_device_register(indio_dev);
> - if (ret) {
> - dev_err(&pdev->dev, "unable to register device\n");
> - goto dis_clk;
> - }
> + ret = devm_add_action_or_reset(&pdev->dev, lpc18xx_writel, adc);

"lpc18xx_writel" is a little vague. Maybe "lpc18xx_clear_cr_reg()"
since this clears the control register.

> + if (ret)
> + return ret;
>
> - return 0;
> + ret = devm_iio_device_register(&pdev->dev, indio_dev);

You can directly do:
return devm_iio_device_register(&pdev->dev, indio_dev);

The kernel should print probe failure.

> + if (ret)
> + dev_err(&pdev->dev, "unable to register device\n");
>
> -dis_clk:
> - writel(0, adc->base + LPC18XX_ADC_CR);
> - clk_disable_unprepare(adc->clk);
> -dis_reg:
> - regulator_disable(adc->vref);
> return ret;
> }
>
> -static int lpc18xx_adc_remove(struct platform_device *pdev)
> -{
> - struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> - struct lpc18xx_adc *adc = iio_priv(indio_dev);
> -
> - iio_device_unregister(indio_dev);
> -
> - writel(0, adc->base + LPC18XX_ADC_CR);
> - clk_disable_unprepare(adc->clk);
> - regulator_disable(adc->vref);
> -
> - return 0;
> -}
> -
> static const struct of_device_id lpc18xx_adc_match[] = {
> { .compatible = "nxp,lpc1850-adc" },
> { /* sentinel */ }
> @@ -211,7 +218,6 @@ MODULE_DEVICE_TABLE(of, lpc18xx_adc_match);
>
> static struct platform_driver lpc18xx_adc_driver = {
> .probe = lpc18xx_adc_probe,
> - .remove = lpc18xx_adc_remove,
> .driver = {
> .name = "lpc18xx-adc",
> .of_match_table = lpc18xx_adc_match,
> --
> 2.33.0
>