diff options
| author | Krzysztof Kozlowski <k.kozlowski@samsung.com> | 2015-03-12 03:44:12 -0400 |
|---|---|---|
| committer | Sebastian Reichel <sre@kernel.org> | 2015-03-13 18:15:52 -0400 |
| commit | 1a352462b5377ac68f5955d674b3460c7bac52a3 (patch) | |
| tree | b2dbecd8b038ccaddd262af47efa4fdf64c75696 /drivers/power | |
| parent | 297d716f6260cc9421d971b124ca196b957ee458 (diff) | |
power_supply: Add power_supply_put for decrementing device reference counter
The power_supply_get_by_phandle() and power_supply_get_by_name() use
function class_find_device() for obtaining the reference to power
supply. Each use of class_find_device() increases the power supply's
device reference counter.
However the reference counter was not decreased by users of this API.
Thus final device_unregister() call from power_supply_unregister() could
not release the device and clean up its resources. This lead to memory
leak if at least once power_supply_get_by_*() was called between
registering and unregistering the power supply.
Add and document new API power_supply_put() for decrementing the
reference counter.
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Acked-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Reviewed-by: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Sebastian Reichel <sre@kernel.org>
Diffstat (limited to 'drivers/power')
| -rw-r--r-- | drivers/power/power_supply_core.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c index e51405b176c8..b4ec14683b7f 100644 --- a/drivers/power/power_supply_core.c +++ b/drivers/power/power_supply_core.c | |||
| @@ -336,6 +336,17 @@ static int power_supply_match_device_by_name(struct device *dev, const void *dat | |||
| 336 | return strcmp(psy->desc->name, name) == 0; | 336 | return strcmp(psy->desc->name, name) == 0; |
| 337 | } | 337 | } |
| 338 | 338 | ||
| 339 | /** | ||
| 340 | * power_supply_get_by_name() - Search for a power supply and returns its ref | ||
| 341 | * @name: Power supply name to fetch | ||
| 342 | * | ||
| 343 | * If power supply was found, it increases reference count for the | ||
| 344 | * internal power supply's device. The user should power_supply_put() | ||
| 345 | * after usage. | ||
| 346 | * | ||
| 347 | * Return: On success returns a reference to a power supply with | ||
| 348 | * matching name equals to @name, a NULL otherwise. | ||
| 349 | */ | ||
| 339 | struct power_supply *power_supply_get_by_name(const char *name) | 350 | struct power_supply *power_supply_get_by_name(const char *name) |
| 340 | { | 351 | { |
| 341 | struct device *dev = class_find_device(power_supply_class, NULL, name, | 352 | struct device *dev = class_find_device(power_supply_class, NULL, name, |
| @@ -345,12 +356,39 @@ struct power_supply *power_supply_get_by_name(const char *name) | |||
| 345 | } | 356 | } |
| 346 | EXPORT_SYMBOL_GPL(power_supply_get_by_name); | 357 | EXPORT_SYMBOL_GPL(power_supply_get_by_name); |
| 347 | 358 | ||
| 359 | /** | ||
| 360 | * power_supply_put() - Drop reference obtained with power_supply_get_by_name | ||
| 361 | * @psy: Reference to put | ||
| 362 | * | ||
| 363 | * The reference to power supply should be put before unregistering | ||
| 364 | * the power supply. | ||
| 365 | */ | ||
| 366 | void power_supply_put(struct power_supply *psy) | ||
| 367 | { | ||
| 368 | might_sleep(); | ||
| 369 | |||
| 370 | put_device(&psy->dev); | ||
| 371 | } | ||
| 372 | EXPORT_SYMBOL_GPL(power_supply_put); | ||
| 373 | |||
| 348 | #ifdef CONFIG_OF | 374 | #ifdef CONFIG_OF |
| 349 | static int power_supply_match_device_node(struct device *dev, const void *data) | 375 | static int power_supply_match_device_node(struct device *dev, const void *data) |
| 350 | { | 376 | { |
| 351 | return dev->parent && dev->parent->of_node == data; | 377 | return dev->parent && dev->parent->of_node == data; |
| 352 | } | 378 | } |
| 353 | 379 | ||
| 380 | /** | ||
| 381 | * power_supply_get_by_phandle() - Search for a power supply and returns its ref | ||
| 382 | * @np: Pointer to device node holding phandle property | ||
| 383 | * @phandle_name: Name of property holding a power supply name | ||
| 384 | * | ||
| 385 | * If power supply was found, it increases reference count for the | ||
| 386 | * internal power supply's device. The user should power_supply_put() | ||
| 387 | * after usage. | ||
| 388 | * | ||
| 389 | * Return: On success returns a reference to a power supply with | ||
| 390 | * matching name equals to value under @property, NULL or ERR_PTR otherwise. | ||
| 391 | */ | ||
| 354 | struct power_supply *power_supply_get_by_phandle(struct device_node *np, | 392 | struct power_supply *power_supply_get_by_phandle(struct device_node *np, |
| 355 | const char *property) | 393 | const char *property) |
| 356 | { | 394 | { |
