* [PATCH/RFC v4 1/3] iio: trigger: implement devm_iio_trigger_alloc/devm_iio_triger_free
@ 2013-08-16 13:11 Jacek Anaszewski
2013-08-17 18:35 ` Jonathan Cameron
0 siblings, 1 reply; 2+ messages in thread
From: Jacek Anaszewski @ 2013-08-16 13:11 UTC (permalink / raw)
To: linux-iio; +Cc: devicetree, jic23, kyungmin.park, s.nawrocki, Jacek Anaszewski
Add a resource managed devm_iio_trigger_alloc()/devm_iio_triger_free()
to automatically clean up triggers allocated by IIO drivers, thus
leading to simplified IIO drivers code.
Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
Signed-off-by: Kyunmin Park <kyungmin.park@samsung.com>
---
drivers/iio/industrialio-trigger.c | 71 ++++++++++++++++++++++++++++++++++--
include/linux/iio/iio.h | 29 +++++++++++++++
2 files changed, 96 insertions(+), 4 deletions(-)
diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c
index 0dd9bb8..3c4180e 100644
--- a/drivers/iio/industrialio-trigger.c
+++ b/drivers/iio/industrialio-trigger.c
@@ -424,9 +424,8 @@ static void iio_trig_subirqunmask(struct irq_data *d)
trig->subirqs[d->irq - trig->subirq_base].enabled = true;
}
-struct iio_trigger *iio_trigger_alloc(const char *fmt, ...)
+struct iio_trigger *viio_trigger_alloc(const char *fmt, va_list vargs)
{
- va_list vargs;
struct iio_trigger *trig;
trig = kzalloc(sizeof *trig, GFP_KERNEL);
if (trig) {
@@ -444,9 +443,9 @@ struct iio_trigger *iio_trigger_alloc(const char *fmt, ...)
kfree(trig);
return NULL;
}
- va_start(vargs, fmt);
+
trig->name = kvasprintf(GFP_KERNEL, fmt, vargs);
- va_end(vargs);
+
if (trig->name == NULL) {
irq_free_descs(trig->subirq_base,
CONFIG_IIO_CONSUMERS_PER_TRIGGER);
@@ -469,6 +468,18 @@ struct iio_trigger *iio_trigger_alloc(const char *fmt, ...)
}
return trig;
}
+
+struct iio_trigger *iio_trigger_alloc(const char *fmt, ...)
+{
+ struct iio_trigger *trig;
+ va_list vargs;
+
+ va_start(vargs, fmt);
+ trig = viio_trigger_alloc(fmt, vargs);
+ va_end(vargs);
+
+ return trig;
+}
EXPORT_SYMBOL(iio_trigger_alloc);
void iio_trigger_free(struct iio_trigger *trig)
@@ -478,6 +489,58 @@ void iio_trigger_free(struct iio_trigger *trig)
}
EXPORT_SYMBOL(iio_trigger_free);
+
+static void devm_iio_trigger_release(struct device *dev, void *res)
+{
+ iio_trigger_free(*(struct iio_trigger **)res);
+}
+
+static int devm_iio_trigger_match(struct device *dev, void *res, void *data)
+{
+ struct iio_trigger **r = res;
+ if (!r || !*r) {
+ WARN_ON(!r || !*r);
+ return 0;
+ }
+ return *r == data;
+}
+
+struct iio_trigger *devm_iio_trigger_alloc(struct device *dev,
+ const char *fmt, ...)
+{
+ struct iio_trigger **ptr, *trig;
+ va_list vargs;
+
+ ptr = devres_alloc(devm_iio_trigger_release, sizeof(*ptr),
+ GFP_KERNEL);
+ if (!ptr)
+ return NULL;
+
+ /* use raw alloc_dr for kmalloc caller tracing */
+ va_start(vargs, fmt);
+ trig = viio_trigger_alloc(fmt, vargs);
+ va_end(vargs);
+ if (trig) {
+ *ptr = trig;
+ devres_add(dev, ptr);
+ } else {
+ devres_free(ptr);
+ }
+
+ return trig;
+}
+EXPORT_SYMBOL_GPL(devm_iio_trigger_alloc);
+
+void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig)
+{
+ int rc;
+
+ rc = devres_release(dev, devm_iio_trigger_release,
+ devm_iio_trigger_match, iio_trig);
+ WARN_ON(rc);
+}
+EXPORT_SYMBOL_GPL(devm_iio_trigger_free);
+
void iio_device_register_trigger_consumer(struct iio_dev *indio_dev)
{
indio_dev->groups[indio_dev->groupcounter++] =
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index 09ebe0a..2103cc3 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -557,6 +557,35 @@ struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv);
void devm_iio_device_free(struct device *dev, struct iio_dev *indio_dev);
/**
+ * devm_iio_trigger_alloc - Resource-managed iio_trigger_alloc()
+ * @dev: Device to allocate iio_trigger for
+ * @fmt: trigger name format. If it includes format
+ * specifiers, the additional arguments following
+ * format are formatted and inserted in the resulting
+ * string replacing their respective specifiers.
+ *
+ * Managed iio_trigger_alloc. iio_trigger allocated with this function is
+ * automatically freed on driver detach.
+ *
+ * If an iio_trigger allocated with this function needs to be freed separately,
+ * devm_iio_trigger_free() must be used.
+ *
+ * RETURNS:
+ * Pointer to allocated iio_trigger on success, NULL on failure.
+ */
+struct iio_trigger *devm_iio_trigger_alloc(struct device *dev,
+ const char *fmt, ...);
+
+/**
+ * devm_iio_trigger_free - Resource-managed iio_trigger_free()
+ * @dev: Device this iio_dev belongs to
+ * @iio_trig: the iio_trigger associated with the device
+ *
+ * Free iio_trigger allocated with devm_iio_trigger_alloc().
+ */
+void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig);
+
+/**
* iio_buffer_enabled() - helper function to test if the buffer is enabled
* @indio_dev: IIO device structure for device
**/
--
1.7.5.4
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH/RFC v4 1/3] iio: trigger: implement devm_iio_trigger_alloc/devm_iio_triger_free
2013-08-16 13:11 [PATCH/RFC v4 1/3] iio: trigger: implement devm_iio_trigger_alloc/devm_iio_triger_free Jacek Anaszewski
@ 2013-08-17 18:35 ` Jonathan Cameron
0 siblings, 0 replies; 2+ messages in thread
From: Jonathan Cameron @ 2013-08-17 18:35 UTC (permalink / raw)
To: Jacek Anaszewski; +Cc: linux-iio, devicetree, kyungmin.park, s.nawrocki
On 08/16/13 14:11, Jacek Anaszewski wrote:
> Add a resource managed devm_iio_trigger_alloc()/devm_iio_triger_free()
> to automatically clean up triggers allocated by IIO drivers, thus
> leading to simplified IIO drivers code.
>
> Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
> Signed-off-by: Kyunmin Park <kyungmin.park@samsung.com>
Good. I thought of doing this myself when the iio_dev version came
along but am always happy to have someone else put in the work for me ;)
Couple of little points though before we merge this:
1) Needs adding to the list in Documentation/driver-model/devres.txt
2) The viio_trigger_alloc sould be static
3) A few bits of additional unwanted whitespace have snuck in.
I've fixed these little bits up and applied the patch to the togreg
branch of iio.git
Thanks,
Jonathan
> ---
> drivers/iio/industrialio-trigger.c | 71 ++++++++++++++++++++++++++++++++++--
> include/linux/iio/iio.h | 29 +++++++++++++++
> 2 files changed, 96 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c
> index 0dd9bb8..3c4180e 100644
> --- a/drivers/iio/industrialio-trigger.c
> +++ b/drivers/iio/industrialio-trigger.c
> @@ -424,9 +424,8 @@ static void iio_trig_subirqunmask(struct irq_data *d)
> trig->subirqs[d->irq - trig->subirq_base].enabled = true;
> }
>
> -struct iio_trigger *iio_trigger_alloc(const char *fmt, ...)
> +struct iio_trigger *viio_trigger_alloc(const char *fmt, va_list vargs)
> {
> - va_list vargs;
> struct iio_trigger *trig;
> trig = kzalloc(sizeof *trig, GFP_KERNEL);
> if (trig) {
> @@ -444,9 +443,9 @@ struct iio_trigger *iio_trigger_alloc(const char *fmt, ...)
> kfree(trig);
> return NULL;
> }
> - va_start(vargs, fmt);
> +
> trig->name = kvasprintf(GFP_KERNEL, fmt, vargs);
> - va_end(vargs);
> +
> if (trig->name == NULL) {
> irq_free_descs(trig->subirq_base,
> CONFIG_IIO_CONSUMERS_PER_TRIGGER);
> @@ -469,6 +468,18 @@ struct iio_trigger *iio_trigger_alloc(const char *fmt, ...)
> }
> return trig;
> }
> +
> +struct iio_trigger *iio_trigger_alloc(const char *fmt, ...)
> +{
> + struct iio_trigger *trig;
> + va_list vargs;
> +
> + va_start(vargs, fmt);
> + trig = viio_trigger_alloc(fmt, vargs);
> + va_end(vargs);
> +
> + return trig;
> +}
> EXPORT_SYMBOL(iio_trigger_alloc);
>
> void iio_trigger_free(struct iio_trigger *trig)
> @@ -478,6 +489,58 @@ void iio_trigger_free(struct iio_trigger *trig)
> }
> EXPORT_SYMBOL(iio_trigger_free);
>
> +
> +static void devm_iio_trigger_release(struct device *dev, void *res)
> +{
> + iio_trigger_free(*(struct iio_trigger **)res);
> +}
> +
> +static int devm_iio_trigger_match(struct device *dev, void *res, void *data)
> +{
> + struct iio_trigger **r = res;
> + if (!r || !*r) {
> + WARN_ON(!r || !*r);
> + return 0;
> + }
> + return *r == data;
> +}
> +
> +struct iio_trigger *devm_iio_trigger_alloc(struct device *dev,
> + const char *fmt, ...)
> +{
> + struct iio_trigger **ptr, *trig;
> + va_list vargs;
> +
> + ptr = devres_alloc(devm_iio_trigger_release, sizeof(*ptr),
> + GFP_KERNEL);
> + if (!ptr)
> + return NULL;
> +
> + /* use raw alloc_dr for kmalloc caller tracing */
> + va_start(vargs, fmt);
> + trig = viio_trigger_alloc(fmt, vargs);
> + va_end(vargs);
> + if (trig) {
> + *ptr = trig;
> + devres_add(dev, ptr);
> + } else {
> + devres_free(ptr);
> + }
> +
> + return trig;
> +}
> +EXPORT_SYMBOL_GPL(devm_iio_trigger_alloc);
> +
> +void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig)
> +{
> + int rc;
> +
> + rc = devres_release(dev, devm_iio_trigger_release,
> + devm_iio_trigger_match, iio_trig);
> + WARN_ON(rc);
> +}
> +EXPORT_SYMBOL_GPL(devm_iio_trigger_free);
> +
> void iio_device_register_trigger_consumer(struct iio_dev *indio_dev)
> {
> indio_dev->groups[indio_dev->groupcounter++] =
> diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
> index 09ebe0a..2103cc3 100644
> --- a/include/linux/iio/iio.h
> +++ b/include/linux/iio/iio.h
> @@ -557,6 +557,35 @@ struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv);
> void devm_iio_device_free(struct device *dev, struct iio_dev *indio_dev);
>
> /**
> + * devm_iio_trigger_alloc - Resource-managed iio_trigger_alloc()
> + * @dev: Device to allocate iio_trigger for
> + * @fmt: trigger name format. If it includes format
> + * specifiers, the additional arguments following
> + * format are formatted and inserted in the resulting
> + * string replacing their respective specifiers.
> + *
> + * Managed iio_trigger_alloc. iio_trigger allocated with this function is
> + * automatically freed on driver detach.
> + *
> + * If an iio_trigger allocated with this function needs to be freed separately,
> + * devm_iio_trigger_free() must be used.
> + *
> + * RETURNS:
> + * Pointer to allocated iio_trigger on success, NULL on failure.
> + */
> +struct iio_trigger *devm_iio_trigger_alloc(struct device *dev,
> + const char *fmt, ...);
> +
> +/**
> + * devm_iio_trigger_free - Resource-managed iio_trigger_free()
> + * @dev: Device this iio_dev belongs to
> + * @iio_trig: the iio_trigger associated with the device
> + *
> + * Free iio_trigger allocated with devm_iio_trigger_alloc().
> + */
> +void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig);
> +
> +/**
> * iio_buffer_enabled() - helper function to test if the buffer is enabled
> * @indio_dev: IIO device structure for device
> **/
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2013-08-17 17:35 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-16 13:11 [PATCH/RFC v4 1/3] iio: trigger: implement devm_iio_trigger_alloc/devm_iio_triger_free Jacek Anaszewski
2013-08-17 18:35 ` Jonathan Cameron
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.