iio: imu: adis: Add Managed device functions
This patch adds support for a managed device version of adis_setup_buffer_and_trigger. It works exactly as the original one but it calls all the devm_iio_* functions to setup an iio buffer and trigger. Hence we do not need to care about cleaning those and we do not need to support a remove() callback for every driver using the adis library. Signed-off-by: Nuno Sá <nuno.sa@analog.com> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
parent
f3c034f617
commit
fec86c6b83
|
@ -156,6 +156,14 @@ static irqreturn_t adis_trigger_handler(int irq, void *p)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void adis_buffer_cleanup(void *arg)
|
||||
{
|
||||
struct adis *adis = arg;
|
||||
|
||||
kfree(adis->buffer);
|
||||
kfree(adis->xfer);
|
||||
}
|
||||
|
||||
/**
|
||||
* adis_setup_buffer_and_trigger() - Sets up buffer and trigger for the adis device
|
||||
* @adis: The adis device.
|
||||
|
@ -198,6 +206,43 @@ error_buffer_cleanup:
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger);
|
||||
|
||||
/**
|
||||
* devm_adis_setup_buffer_and_trigger() - Sets up buffer and trigger for
|
||||
* the managed adis device
|
||||
* @adis: The adis device
|
||||
* @indio_dev: The IIO device
|
||||
* @trigger_handler: Optional trigger handler, may be NULL.
|
||||
*
|
||||
* Returns 0 on success, a negative error code otherwise.
|
||||
*
|
||||
* This function perfoms exactly the same as adis_setup_buffer_and_trigger()
|
||||
*/
|
||||
int
|
||||
devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev,
|
||||
irq_handler_t trigger_handler)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!trigger_handler)
|
||||
trigger_handler = adis_trigger_handler;
|
||||
|
||||
ret = devm_iio_triggered_buffer_setup(&adis->spi->dev, indio_dev,
|
||||
&iio_pollfunc_store_time,
|
||||
trigger_handler, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (adis->spi->irq) {
|
||||
ret = devm_adis_probe_trigger(adis, indio_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return devm_add_action_or_reset(&adis->spi->dev, adis_buffer_cleanup,
|
||||
adis);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_adis_setup_buffer_and_trigger);
|
||||
|
||||
/**
|
||||
* adis_cleanup_buffer_and_trigger() - Free buffer and trigger resources
|
||||
* @adis: The adis device.
|
||||
|
|
|
@ -27,6 +27,13 @@ static const struct iio_trigger_ops adis_trigger_ops = {
|
|||
.set_trigger_state = &adis_data_rdy_trigger_set_state,
|
||||
};
|
||||
|
||||
static void adis_trigger_setup(struct adis *adis)
|
||||
{
|
||||
adis->trig->dev.parent = &adis->spi->dev;
|
||||
adis->trig->ops = &adis_trigger_ops;
|
||||
iio_trigger_set_drvdata(adis->trig, adis);
|
||||
}
|
||||
|
||||
/**
|
||||
* adis_probe_trigger() - Sets up trigger for a adis device
|
||||
* @adis: The adis device
|
||||
|
@ -45,9 +52,7 @@ int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
|
|||
if (adis->trig == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
adis->trig->dev.parent = &adis->spi->dev;
|
||||
adis->trig->ops = &adis_trigger_ops;
|
||||
iio_trigger_set_drvdata(adis->trig, adis);
|
||||
adis_trigger_setup(adis);
|
||||
|
||||
ret = request_irq(adis->spi->irq,
|
||||
&iio_trigger_generic_data_rdy_poll,
|
||||
|
@ -73,6 +78,36 @@ error_free_trig:
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(adis_probe_trigger);
|
||||
|
||||
/**
|
||||
* devm_adis_probe_trigger() - Sets up trigger for a managed adis device
|
||||
* @adis: The adis device
|
||||
* @indio_dev: The IIO device
|
||||
*
|
||||
* Returns 0 on success or a negative error code
|
||||
*/
|
||||
int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
adis->trig = devm_iio_trigger_alloc(&adis->spi->dev, "%s-dev%d",
|
||||
indio_dev->name, indio_dev->id);
|
||||
if (!adis->trig)
|
||||
return -ENOMEM;
|
||||
|
||||
adis_trigger_setup(adis);
|
||||
|
||||
ret = devm_request_irq(&adis->spi->dev, adis->spi->irq,
|
||||
&iio_trigger_generic_data_rdy_poll,
|
||||
IRQF_TRIGGER_RISING,
|
||||
indio_dev->name,
|
||||
adis->trig);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return devm_iio_trigger_register(&adis->spi->dev, adis->trig);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_adis_probe_trigger);
|
||||
|
||||
/**
|
||||
* adis_remove_trigger() - Remove trigger for a adis devices
|
||||
* @adis: The adis device
|
||||
|
|
|
@ -448,11 +448,15 @@ struct adis_burst {
|
|||
unsigned int extra_len;
|
||||
};
|
||||
|
||||
int
|
||||
devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev,
|
||||
irq_handler_t trigger_handler);
|
||||
int adis_setup_buffer_and_trigger(struct adis *adis,
|
||||
struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *));
|
||||
void adis_cleanup_buffer_and_trigger(struct adis *adis,
|
||||
struct iio_dev *indio_dev);
|
||||
|
||||
int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev);
|
||||
int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev);
|
||||
void adis_remove_trigger(struct adis *adis);
|
||||
|
||||
|
@ -461,6 +465,13 @@ int adis_update_scan_mode(struct iio_dev *indio_dev,
|
|||
|
||||
#else /* CONFIG_IIO_BUFFER */
|
||||
|
||||
static inline int
|
||||
devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev,
|
||||
irq_handler_t trigger_handler)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int adis_setup_buffer_and_trigger(struct adis *adis,
|
||||
struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *))
|
||||
{
|
||||
|
@ -472,6 +483,12 @@ static inline void adis_cleanup_buffer_and_trigger(struct adis *adis,
|
|||
{
|
||||
}
|
||||
|
||||
static inline int devm_adis_probe_trigger(struct adis *adis,
|
||||
struct iio_dev *indio_dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int adis_probe_trigger(struct adis *adis,
|
||||
struct iio_dev *indio_dev)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue