Commit 739ba1bf authored by Chanwoo Choi's avatar Chanwoo Choi

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: default avatarChanwoo Choi <cw00.choi@samsung.com>
Reviewed-by: default avatarFelipe Balbi <balbi@ti.com>
parent a9af6522
...@@ -601,6 +601,64 @@ void extcon_dev_free(struct extcon_dev *edev) ...@@ -601,6 +601,64 @@ void extcon_dev_free(struct extcon_dev *edev)
} }
EXPORT_SYMBOL_GPL(extcon_dev_free); 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 * extcon_dev_register() - Register a new extcon device
* @edev : the new extcon device (should be allocated before calling) * @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) ...@@ -860,18 +918,6 @@ static void devm_extcon_dev_unreg(struct device *dev, void *res)
extcon_dev_unregister(*(struct extcon_dev **)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() * devm_extcon_dev_register() - Resource-managed extcon_dev_register()
* @dev: device to allocate extcon device * @dev: device to allocate extcon device
......
...@@ -196,6 +196,9 @@ extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name); ...@@ -196,6 +196,9 @@ extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name);
*/ */
extern struct extcon_dev *extcon_dev_allocate(const char **cables); extern struct extcon_dev *extcon_dev_allocate(const char **cables);
extern void extcon_dev_free(struct extcon_dev *edev); extern void extcon_dev_free(struct extcon_dev *edev);
extern struct extcon_dev *devm_extcon_dev_allocate(struct device *dev,
const char **cables);
extern void devm_extcon_dev_free(struct device *dev, struct extcon_dev *edev);
/* /*
* get/set/update_state access the 32b encoded state value, which represents * get/set/update_state access the 32b encoded state value, which represents
...@@ -280,6 +283,14 @@ static inline struct extcon_dev *extcon_dev_allocate(const char **cables) ...@@ -280,6 +283,14 @@ static inline struct extcon_dev *extcon_dev_allocate(const char **cables)
static inline void extcon_dev_free(struct extcon_dev *edev) { } static inline void extcon_dev_free(struct extcon_dev *edev) { }
static inline struct extcon_dev *devm_extcon_dev_allocate(struct device *dev,
const char **cables)
{
return ERR_PTR(-ENOSYS);
}
static inline void devm_extcon_dev_free(struct extcon_dev *edev) { }
static inline u32 extcon_get_state(struct extcon_dev *edev) static inline u32 extcon_get_state(struct extcon_dev *edev)
{ {
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment