Commit 2a9685d1 authored by Bartosz Golaszewski's avatar Bartosz Golaszewski Committed by Jonathan Cameron

iio: adc: xilinx: use more devres helpers and remove remove()

In order to simplify resource management and error paths in probe() and
entirely drop the remove() callback - use devres helpers wherever
possible. Define devm actions for cancelling the delayed work and
disabling the clock.
Signed-off-by: default avatarBartosz Golaszewski <bgolaszewski@baylibre.com>
Tested-by: default avatarAnand Ashok Dumbre <anandash@xilinx.com>
Reviewed-by: default avatarAnand Ashok Dumbre <anandash@xilinx.com>
Link: https://lore.kernel.org/r/20201130142759.28216-4-brgl@bgdev.plSigned-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent eab64715
...@@ -738,11 +738,12 @@ static const struct iio_trigger_ops xadc_trigger_ops = { ...@@ -738,11 +738,12 @@ static const struct iio_trigger_ops xadc_trigger_ops = {
static struct iio_trigger *xadc_alloc_trigger(struct iio_dev *indio_dev, static struct iio_trigger *xadc_alloc_trigger(struct iio_dev *indio_dev,
const char *name) const char *name)
{ {
struct device *dev = indio_dev->dev.parent;
struct iio_trigger *trig; struct iio_trigger *trig;
int ret; int ret;
trig = iio_trigger_alloc("%s%d-%s", indio_dev->name, trig = devm_iio_trigger_alloc(dev, "%s%d-%s", indio_dev->name,
indio_dev->id, name); indio_dev->id, name);
if (trig == NULL) if (trig == NULL)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
...@@ -750,15 +751,11 @@ static struct iio_trigger *xadc_alloc_trigger(struct iio_dev *indio_dev, ...@@ -750,15 +751,11 @@ static struct iio_trigger *xadc_alloc_trigger(struct iio_dev *indio_dev,
trig->ops = &xadc_trigger_ops; trig->ops = &xadc_trigger_ops;
iio_trigger_set_drvdata(trig, iio_priv(indio_dev)); iio_trigger_set_drvdata(trig, iio_priv(indio_dev));
ret = iio_trigger_register(trig); ret = devm_iio_trigger_register(dev, trig);
if (ret) if (ret)
goto error_free_trig; return ERR_PTR(ret);
return trig; return trig;
error_free_trig:
iio_trigger_free(trig);
return ERR_PTR(ret);
} }
static int xadc_power_adc_b(struct xadc *xadc, unsigned int seq_mode) static int xadc_power_adc_b(struct xadc *xadc, unsigned int seq_mode)
...@@ -1293,6 +1290,20 @@ static const char * const xadc_type_names[] = { ...@@ -1293,6 +1290,20 @@ static const char * const xadc_type_names[] = {
[XADC_TYPE_US] = "xilinx-system-monitor", [XADC_TYPE_US] = "xilinx-system-monitor",
}; };
static void xadc_clk_disable_unprepare(void *data)
{
struct clk *clk = data;
clk_disable_unprepare(clk);
}
static void xadc_cancel_delayed_work(void *data)
{
struct delayed_work *work = data;
cancel_delayed_work_sync(work);
}
static int xadc_probe(struct platform_device *pdev) static int xadc_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
...@@ -1341,34 +1352,35 @@ static int xadc_probe(struct platform_device *pdev) ...@@ -1341,34 +1352,35 @@ static int xadc_probe(struct platform_device *pdev)
return ret; return ret;
if (xadc->ops->flags & XADC_FLAGS_BUFFERED) { if (xadc->ops->flags & XADC_FLAGS_BUFFERED) {
ret = iio_triggered_buffer_setup(indio_dev, ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
&iio_pollfunc_store_time, &xadc_trigger_handler, &iio_pollfunc_store_time,
&xadc_buffer_ops); &xadc_trigger_handler,
&xadc_buffer_ops);
if (ret) if (ret)
return ret; return ret;
xadc->convst_trigger = xadc_alloc_trigger(indio_dev, "convst"); xadc->convst_trigger = xadc_alloc_trigger(indio_dev, "convst");
if (IS_ERR(xadc->convst_trigger)) { if (IS_ERR(xadc->convst_trigger))
ret = PTR_ERR(xadc->convst_trigger); return PTR_ERR(xadc->convst_trigger);
goto err_triggered_buffer_cleanup;
}
xadc->samplerate_trigger = xadc_alloc_trigger(indio_dev, xadc->samplerate_trigger = xadc_alloc_trigger(indio_dev,
"samplerate"); "samplerate");
if (IS_ERR(xadc->samplerate_trigger)) { if (IS_ERR(xadc->samplerate_trigger))
ret = PTR_ERR(xadc->samplerate_trigger); return PTR_ERR(xadc->samplerate_trigger);
goto err_free_convst_trigger;
}
} }
xadc->clk = devm_clk_get(dev, NULL); xadc->clk = devm_clk_get(dev, NULL);
if (IS_ERR(xadc->clk)) { if (IS_ERR(xadc->clk))
ret = PTR_ERR(xadc->clk); return PTR_ERR(xadc->clk);
goto err_free_samplerate_trigger;
}
ret = clk_prepare_enable(xadc->clk); ret = clk_prepare_enable(xadc->clk);
if (ret) if (ret)
goto err_free_samplerate_trigger; return ret;
ret = devm_add_action_or_reset(dev,
xadc_clk_disable_unprepare, xadc->clk);
if (ret)
return ret;
/* /*
* Make sure not to exceed the maximum samplerate since otherwise the * Make sure not to exceed the maximum samplerate since otherwise the
...@@ -1377,22 +1389,28 @@ static int xadc_probe(struct platform_device *pdev) ...@@ -1377,22 +1389,28 @@ static int xadc_probe(struct platform_device *pdev)
if (xadc->ops->flags & XADC_FLAGS_BUFFERED) { if (xadc->ops->flags & XADC_FLAGS_BUFFERED) {
ret = xadc_read_samplerate(xadc); ret = xadc_read_samplerate(xadc);
if (ret < 0) if (ret < 0)
goto err_free_samplerate_trigger; return ret;
if (ret > XADC_MAX_SAMPLERATE) { if (ret > XADC_MAX_SAMPLERATE) {
ret = xadc_write_samplerate(xadc, XADC_MAX_SAMPLERATE); ret = xadc_write_samplerate(xadc, XADC_MAX_SAMPLERATE);
if (ret < 0) if (ret < 0)
goto err_free_samplerate_trigger; return ret;
} }
} }
ret = request_irq(xadc->irq, xadc->ops->interrupt_handler, 0, ret = devm_request_irq(dev, xadc->irq, xadc->ops->interrupt_handler, 0,
dev_name(dev), indio_dev); dev_name(dev), indio_dev);
if (ret)
return ret;
ret = devm_add_action_or_reset(dev, xadc_cancel_delayed_work,
&xadc->zynq_unmask_work);
if (ret) if (ret)
goto err_clk_disable_unprepare; return ret;
ret = xadc->ops->setup(pdev, indio_dev, xadc->irq); ret = xadc->ops->setup(pdev, indio_dev, xadc->irq);
if (ret) if (ret)
goto err_free_irq; return ret;
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
xadc_read_adc_reg(xadc, XADC_REG_THRESHOLD(i), xadc_read_adc_reg(xadc, XADC_REG_THRESHOLD(i),
...@@ -1400,7 +1418,7 @@ static int xadc_probe(struct platform_device *pdev) ...@@ -1400,7 +1418,7 @@ static int xadc_probe(struct platform_device *pdev)
ret = xadc_write_adc_reg(xadc, XADC_REG_CONF0, conf0); ret = xadc_write_adc_reg(xadc, XADC_REG_CONF0, conf0);
if (ret) if (ret)
goto err_free_irq; return ret;
bipolar_mask = 0; bipolar_mask = 0;
for (i = 0; i < indio_dev->num_channels; i++) { for (i = 0; i < indio_dev->num_channels; i++) {
...@@ -1410,17 +1428,18 @@ static int xadc_probe(struct platform_device *pdev) ...@@ -1410,17 +1428,18 @@ static int xadc_probe(struct platform_device *pdev)
ret = xadc_write_adc_reg(xadc, XADC_REG_INPUT_MODE(0), bipolar_mask); ret = xadc_write_adc_reg(xadc, XADC_REG_INPUT_MODE(0), bipolar_mask);
if (ret) if (ret)
goto err_free_irq; return ret;
ret = xadc_write_adc_reg(xadc, XADC_REG_INPUT_MODE(1), ret = xadc_write_adc_reg(xadc, XADC_REG_INPUT_MODE(1),
bipolar_mask >> 16); bipolar_mask >> 16);
if (ret) if (ret)
goto err_free_irq; return ret;
/* Disable all alarms */ /* Disable all alarms */
ret = xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF1_ALARM_MASK, ret = xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF1_ALARM_MASK,
XADC_CONF1_ALARM_MASK); XADC_CONF1_ALARM_MASK);
if (ret) if (ret)
goto err_free_irq; return ret;
/* Set thresholds to min/max */ /* Set thresholds to min/max */
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
...@@ -1435,59 +1454,17 @@ static int xadc_probe(struct platform_device *pdev) ...@@ -1435,59 +1454,17 @@ static int xadc_probe(struct platform_device *pdev)
ret = xadc_write_adc_reg(xadc, XADC_REG_THRESHOLD(i), ret = xadc_write_adc_reg(xadc, XADC_REG_THRESHOLD(i),
xadc->threshold[i]); xadc->threshold[i]);
if (ret) if (ret)
goto err_free_irq; return ret;
} }
/* Go to non-buffered mode */ /* Go to non-buffered mode */
xadc_postdisable(indio_dev); xadc_postdisable(indio_dev);
ret = iio_device_register(indio_dev); return devm_iio_device_register(dev, indio_dev);
if (ret)
goto err_free_irq;
platform_set_drvdata(pdev, indio_dev);
return 0;
err_free_irq:
free_irq(xadc->irq, indio_dev);
cancel_delayed_work_sync(&xadc->zynq_unmask_work);
err_clk_disable_unprepare:
clk_disable_unprepare(xadc->clk);
err_free_samplerate_trigger:
if (xadc->ops->flags & XADC_FLAGS_BUFFERED)
iio_trigger_free(xadc->samplerate_trigger);
err_free_convst_trigger:
if (xadc->ops->flags & XADC_FLAGS_BUFFERED)
iio_trigger_free(xadc->convst_trigger);
err_triggered_buffer_cleanup:
if (xadc->ops->flags & XADC_FLAGS_BUFFERED)
iio_triggered_buffer_cleanup(indio_dev);
return ret;
}
static int xadc_remove(struct platform_device *pdev)
{
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct xadc *xadc = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
if (xadc->ops->flags & XADC_FLAGS_BUFFERED) {
iio_trigger_free(xadc->samplerate_trigger);
iio_trigger_free(xadc->convst_trigger);
iio_triggered_buffer_cleanup(indio_dev);
}
free_irq(xadc->irq, indio_dev);
cancel_delayed_work_sync(&xadc->zynq_unmask_work);
clk_disable_unprepare(xadc->clk);
return 0;
} }
static struct platform_driver xadc_driver = { static struct platform_driver xadc_driver = {
.probe = xadc_probe, .probe = xadc_probe,
.remove = xadc_remove,
.driver = { .driver = {
.name = "xadc", .name = "xadc",
.of_match_table = xadc_of_match_table, .of_match_table = xadc_of_match_table,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment