aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio/adc/lpc18xx_adc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/adc/lpc18xx_adc.c')
-rw-r--r--drivers/iio/adc/lpc18xx_adc.c75
1 files changed, 37 insertions, 38 deletions
diff --git a/drivers/iio/adc/lpc18xx_adc.c b/drivers/iio/adc/lpc18xx_adc.c
index 3566990ae87d..ceefa4d793cf 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_clear_cr_reg(void *data)
+{
+ struct lpc18xx_adc *adc = data;
+
+ writel(0, adc->base + LPC18XX_ADC_CR);
+}
+
+static void lpc18xx_clk_disable(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;
@@ -127,7 +144,6 @@ static int lpc18xx_adc_probe(struct platform_device *pdev)
if (!indio_dev)
return -ENOMEM;
- platform_set_drvdata(pdev, indio_dev);
adc = iio_priv(indio_dev);
adc->dev = &pdev->dev;
mutex_init(&adc->lock);
@@ -137,19 +153,17 @@ static int lpc18xx_adc_probe(struct platform_device *pdev)
return PTR_ERR(adc->base);
adc->clk = devm_clk_get(&pdev->dev, NULL);
- if (IS_ERR(adc->clk)) {
- dev_err(&pdev->dev, "error getting clock\n");
- return PTR_ERR(adc->clk);
- }
+ if (IS_ERR(adc->clk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(adc->clk),
+ "error getting clock\n");
rate = clk_get_rate(adc->clk);
clkdiv = DIV_ROUND_UP(rate, LPC18XX_ADC_CLK_TARGET);
adc->vref = devm_regulator_get(&pdev->dev, "vref");
- if (IS_ERR(adc->vref)) {
- dev_err(&pdev->dev, "error getting regulator\n");
- return PTR_ERR(adc->vref);
- }
+ if (IS_ERR(adc->vref))
+ return dev_err_probe(&pdev->dev, PTR_ERR(adc->vref),
+ "error getting regulator\n");
indio_dev->name = dev_name(&pdev->dev);
indio_dev->info = &lpc18xx_adc_info;
@@ -163,44 +177,30 @@ 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,
+ 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;
- }
-
- return 0;
-
-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);
+ ret = devm_add_action_or_reset(&pdev->dev, lpc18xx_clear_cr_reg, adc);
+ if (ret)
+ return ret;
- return 0;
+ return devm_iio_device_register(&pdev->dev, indio_dev);
}
static const struct of_device_id lpc18xx_adc_match[] = {
@@ -211,7 +211,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,