Skip to content

Commit

Permalink
iio: adc: xilinx: use more devres helpers and remove remove()
Browse files Browse the repository at this point in the history
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: Bartosz Golaszewski <[email protected]>
Tested-by: Anand Ashok Dumbre <[email protected]>
Reviewed-by: Anand Ashok Dumbre <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jonathan Cameron <[email protected]>
  • Loading branch information
brgl authored and jic23 committed Jan 9, 2021
1 parent eab6471 commit 2a9685d
Showing 1 changed file with 55 additions and 78 deletions.
133 changes: 55 additions & 78 deletions drivers/iio/adc/xilinx-xadc-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -738,27 +738,24 @@ static const struct iio_trigger_ops xadc_trigger_ops = {
static struct iio_trigger *xadc_alloc_trigger(struct iio_dev *indio_dev,
const char *name)
{
struct device *dev = indio_dev->dev.parent;
struct iio_trigger *trig;
int ret;

trig = iio_trigger_alloc("%s%d-%s", indio_dev->name,
indio_dev->id, name);
trig = devm_iio_trigger_alloc(dev, "%s%d-%s", indio_dev->name,
indio_dev->id, name);
if (trig == NULL)
return ERR_PTR(-ENOMEM);

trig->dev.parent = indio_dev->dev.parent;
trig->ops = &xadc_trigger_ops;
iio_trigger_set_drvdata(trig, iio_priv(indio_dev));

ret = iio_trigger_register(trig);
ret = devm_iio_trigger_register(dev, trig);
if (ret)
goto error_free_trig;
return ERR_PTR(ret);

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)
Expand Down Expand Up @@ -1293,6 +1290,20 @@ static const char * const xadc_type_names[] = {
[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)
{
struct device *dev = &pdev->dev;
Expand Down Expand Up @@ -1341,34 +1352,35 @@ static int xadc_probe(struct platform_device *pdev)
return ret;

if (xadc->ops->flags & XADC_FLAGS_BUFFERED) {
ret = iio_triggered_buffer_setup(indio_dev,
&iio_pollfunc_store_time, &xadc_trigger_handler,
&xadc_buffer_ops);
ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
&iio_pollfunc_store_time,
&xadc_trigger_handler,
&xadc_buffer_ops);
if (ret)
return ret;

xadc->convst_trigger = xadc_alloc_trigger(indio_dev, "convst");
if (IS_ERR(xadc->convst_trigger)) {
ret = PTR_ERR(xadc->convst_trigger);
goto err_triggered_buffer_cleanup;
}
if (IS_ERR(xadc->convst_trigger))
return PTR_ERR(xadc->convst_trigger);

xadc->samplerate_trigger = xadc_alloc_trigger(indio_dev,
"samplerate");
if (IS_ERR(xadc->samplerate_trigger)) {
ret = PTR_ERR(xadc->samplerate_trigger);
goto err_free_convst_trigger;
}
if (IS_ERR(xadc->samplerate_trigger))
return PTR_ERR(xadc->samplerate_trigger);
}

xadc->clk = devm_clk_get(dev, NULL);
if (IS_ERR(xadc->clk)) {
ret = PTR_ERR(xadc->clk);
goto err_free_samplerate_trigger;
}
if (IS_ERR(xadc->clk))
return PTR_ERR(xadc->clk);

ret = clk_prepare_enable(xadc->clk);
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
Expand All @@ -1377,30 +1389,36 @@ static int xadc_probe(struct platform_device *pdev)
if (xadc->ops->flags & XADC_FLAGS_BUFFERED) {
ret = xadc_read_samplerate(xadc);
if (ret < 0)
goto err_free_samplerate_trigger;
return ret;

if (ret > XADC_MAX_SAMPLERATE) {
ret = xadc_write_samplerate(xadc, XADC_MAX_SAMPLERATE);
if (ret < 0)
goto err_free_samplerate_trigger;
return ret;
}
}

ret = request_irq(xadc->irq, xadc->ops->interrupt_handler, 0,
dev_name(dev), indio_dev);
ret = devm_request_irq(dev, xadc->irq, xadc->ops->interrupt_handler, 0,
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)
goto err_clk_disable_unprepare;
return ret;

ret = xadc->ops->setup(pdev, indio_dev, xadc->irq);
if (ret)
goto err_free_irq;
return ret;

for (i = 0; i < 16; i++)
xadc_read_adc_reg(xadc, XADC_REG_THRESHOLD(i),
&xadc->threshold[i]);

ret = xadc_write_adc_reg(xadc, XADC_REG_CONF0, conf0);
if (ret)
goto err_free_irq;
return ret;

bipolar_mask = 0;
for (i = 0; i < indio_dev->num_channels; i++) {
Expand All @@ -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);
if (ret)
goto err_free_irq;
return ret;

ret = xadc_write_adc_reg(xadc, XADC_REG_INPUT_MODE(1),
bipolar_mask >> 16);
if (ret)
goto err_free_irq;
return ret;

/* Disable all alarms */
ret = xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF1_ALARM_MASK,
XADC_CONF1_ALARM_MASK);
if (ret)
goto err_free_irq;
return ret;

/* Set thresholds to min/max */
for (i = 0; i < 16; i++) {
Expand All @@ -1435,59 +1454,17 @@ static int xadc_probe(struct platform_device *pdev)
ret = xadc_write_adc_reg(xadc, XADC_REG_THRESHOLD(i),
xadc->threshold[i]);
if (ret)
goto err_free_irq;
return ret;
}

/* Go to non-buffered mode */
xadc_postdisable(indio_dev);

ret = iio_device_register(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;
return devm_iio_device_register(dev, indio_dev);
}

static struct platform_driver xadc_driver = {
.probe = xadc_probe,
.remove = xadc_remove,
.driver = {
.name = "xadc",
.of_match_table = xadc_of_match_table,
Expand Down

0 comments on commit 2a9685d

Please sign in to comment.