extcon: Add devm_extcon_dev_allocate/free to manage the resource of extcon device
This patch add device managed devm_extcon_dev_{allocate,free} to automatically free the memory of extcon_dev structure without handling free operation. Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Reviewed-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
@ -601,6 +601,64 @@ void extcon_dev_free(struct extcon_dev *edev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(extcon_dev_free);
|
||||
|
||||
static int devm_extcon_dev_match(struct device *dev, void *res, void *data)
|
||||
{
|
||||
struct extcon_dev **r = res;
|
||||
|
||||
if (WARN_ON(!r || !*r))
|
||||
return 0;
|
||||
|
||||
return *r == data;
|
||||
}
|
||||
|
||||
static void devm_extcon_dev_release(struct device *dev, void *res)
|
||||
{
|
||||
extcon_dev_free(*(struct extcon_dev **)res);
|
||||
}
|
||||
|
||||
/**
|
||||
* devm_extcon_dev_allocate - Allocate managed extcon device
|
||||
* @dev: device owning the extcon device being created
|
||||
* @supported_cable: Array of supported cable names ending with NULL.
|
||||
* If supported_cable is NULL, cable name related APIs
|
||||
* are disabled.
|
||||
*
|
||||
* This function manages automatically the memory of extcon device using device
|
||||
* resource management and simplify the control of freeing the memory of extcon
|
||||
* device.
|
||||
*
|
||||
* Returns the pointer memory of allocated extcon_dev if success
|
||||
* or ERR_PTR(err) if fail
|
||||
*/
|
||||
struct extcon_dev *devm_extcon_dev_allocate(struct device *dev,
|
||||
const char **supported_cable)
|
||||
{
|
||||
struct extcon_dev **ptr, *edev;
|
||||
|
||||
ptr = devres_alloc(devm_extcon_dev_release, sizeof(*ptr), GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
edev = extcon_dev_allocate(supported_cable);
|
||||
if (IS_ERR(edev)) {
|
||||
devres_free(ptr);
|
||||
return edev;
|
||||
}
|
||||
|
||||
*ptr = edev;
|
||||
devres_add(dev, ptr);
|
||||
|
||||
return edev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_extcon_dev_allocate);
|
||||
|
||||
void devm_extcon_dev_free(struct device *dev, struct extcon_dev *edev)
|
||||
{
|
||||
WARN_ON(devres_release(dev, devm_extcon_dev_release,
|
||||
devm_extcon_dev_match, edev));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_extcon_dev_free);
|
||||
|
||||
/**
|
||||
* extcon_dev_register() - Register a new extcon device
|
||||
* @edev : the new extcon device (should be allocated before calling)
|
||||
@ -860,18 +918,6 @@ static void devm_extcon_dev_unreg(struct device *dev, void *res)
|
||||
extcon_dev_unregister(*(struct extcon_dev **)res);
|
||||
}
|
||||
|
||||
static int devm_extcon_dev_match(struct device *dev, void *res, void *data)
|
||||
{
|
||||
struct extcon_dev **r = res;
|
||||
|
||||
if (!r || !*r) {
|
||||
WARN_ON(!r || !*r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return *r == data;
|
||||
}
|
||||
|
||||
/**
|
||||
* devm_extcon_dev_register() - Resource-managed extcon_dev_register()
|
||||
* @dev: device to allocate extcon device
|
||||
|
Reference in New Issue
Block a user