Skip to content

Commit

Permalink
iio: core: Add devm_ APIs for iio_channel_{get,release}
Browse files Browse the repository at this point in the history
Some of kernel driver uses the IIO framework to get the sensor
value via ADC or IIO HW driver. The client driver get iio channel
by iio_channel_get() and release it by calling iio_channel_release().

Add resource managed version (devm_*) of these APIs so that if client
calls the devm_iio_channel_get() then it need not to release it explicitly,
it can be done by managed device framework when driver get un-binded.

This reduces the code in error path and also need of .remove callback in
some cases.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
  • Loading branch information
Laxman Dewangan authored and Jonathan Cameron committed Apr 19, 2016
1 parent 5f991a9 commit 8bf872d
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
48 changes: 48 additions & 0 deletions drivers/iio/inkern.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,54 @@ void iio_channel_release(struct iio_channel *channel)
}
EXPORT_SYMBOL_GPL(iio_channel_release);

static void devm_iio_channel_free(struct device *dev, void *res)
{
struct iio_channel *channel = *(struct iio_channel **)res;

iio_channel_release(channel);
}

static int devm_iio_channel_match(struct device *dev, void *res, void *data)
{
struct iio_channel **r = res;

if (!r || !*r) {
WARN_ON(!r || !*r);
return 0;
}

return *r == data;
}

struct iio_channel *devm_iio_channel_get(struct device *dev,
const char *channel_name)
{
struct iio_channel **ptr, *channel;

ptr = devres_alloc(devm_iio_channel_free, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);

channel = iio_channel_get(dev, channel_name);
if (IS_ERR(channel)) {
devres_free(ptr);
return channel;
}

*ptr = channel;
devres_add(dev, ptr);

return channel;
}
EXPORT_SYMBOL_GPL(devm_iio_channel_get);

void devm_iio_channel_release(struct device *dev, struct iio_channel *channel)
{
WARN_ON(devres_release(dev, devm_iio_channel_free,
devm_iio_channel_match, channel));
}
EXPORT_SYMBOL_GPL(devm_iio_channel_release);

struct iio_channel *iio_channel_get_all(struct device *dev)
{
const char *name;
Expand Down
27 changes: 27 additions & 0 deletions include/linux/iio/consumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,33 @@ struct iio_channel *iio_channel_get(struct device *dev,
*/
void iio_channel_release(struct iio_channel *chan);

/**
* devm_iio_channel_get() - Resource managed version of iio_channel_get().
* @dev: Pointer to consumer device. Device name must match
* the name of the device as provided in the iio_map
* with which the desired provider to consumer mapping
* was registered.
* @consumer_channel: Unique name to identify the channel on the consumer
* side. This typically describes the channels use within
* the consumer. E.g. 'battery_voltage'
*
* Returns a pointer to negative errno if it is not able to get the iio channel
* otherwise returns valid pointer for iio channel.
*
* The allocated iio channel is automatically released when the device is
* unbound.
*/
struct iio_channel *devm_iio_channel_get(struct device *dev,
const char *consumer_channel);
/**
* devm_iio_channel_release() - Resource managed version of
* iio_channel_release().
* @dev: Pointer to consumer device for which resource
* is allocared.
* @chan: The channel to be released.
*/
void devm_iio_channel_release(struct device *dev, struct iio_channel *chan);

/**
* iio_channel_get_all() - get all channels associated with a client
* @dev: Pointer to consumer device.
Expand Down

0 comments on commit 8bf872d

Please sign in to comment.