diff options
author | Jingoo Han <jg1.han@samsung.com> | 2013-07-03 18:05:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 19:07:43 -0400 |
commit | 8318fde4ac78f6793b1cbaf57659902253a61617 (patch) | |
tree | 7b7a30f1bdcd75972b8efba43fece1d48f19d611 | |
parent | 9ed3936fd7e918bfea565f51aa4379967009d7dd (diff) |
backlight: add devm_backlight_device_{register,unregister}()
These functions allow the driver core to automatically clean up any
allocation made by backlight drivers. Thus it simplifies the error
paths.
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Cc: Tejun Heo <tj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/video/backlight/backlight.c | 75 | ||||
-rw-r--r-- | include/linux/backlight.h | 6 |
2 files changed, 81 insertions, 0 deletions
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index e3c279083253..53c52fbc9395 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c | |||
@@ -370,6 +370,81 @@ void backlight_device_unregister(struct backlight_device *bd) | |||
370 | } | 370 | } |
371 | EXPORT_SYMBOL(backlight_device_unregister); | 371 | EXPORT_SYMBOL(backlight_device_unregister); |
372 | 372 | ||
373 | static void devm_backlight_device_release(struct device *dev, void *res) | ||
374 | { | ||
375 | struct backlight_device *backlight = *(struct backlight_device **)res; | ||
376 | |||
377 | backlight_device_unregister(backlight); | ||
378 | } | ||
379 | |||
380 | static int devm_backlight_device_match(struct device *dev, void *res, | ||
381 | void *data) | ||
382 | { | ||
383 | struct backlight_device **r = res; | ||
384 | |||
385 | return *r == data; | ||
386 | } | ||
387 | |||
388 | /** | ||
389 | * devm_backlight_device_register - resource managed backlight_device_register() | ||
390 | * @dev: the device to register | ||
391 | * @name: the name of the device | ||
392 | * @parent: a pointer to the parent device | ||
393 | * @devdata: an optional pointer to be stored for private driver use | ||
394 | * @ops: the backlight operations structure | ||
395 | * @props: the backlight properties | ||
396 | * | ||
397 | * @return a struct backlight on success, or an ERR_PTR on error | ||
398 | * | ||
399 | * Managed backlight_device_register(). The backlight_device returned | ||
400 | * from this function are automatically freed on driver detach. | ||
401 | * See backlight_device_register() for more information. | ||
402 | */ | ||
403 | struct backlight_device *devm_backlight_device_register(struct device *dev, | ||
404 | const char *name, struct device *parent, void *devdata, | ||
405 | const struct backlight_ops *ops, | ||
406 | const struct backlight_properties *props) | ||
407 | { | ||
408 | struct backlight_device **ptr, *backlight; | ||
409 | |||
410 | ptr = devres_alloc(devm_backlight_device_release, sizeof(*ptr), | ||
411 | GFP_KERNEL); | ||
412 | if (!ptr) | ||
413 | return ERR_PTR(-ENOMEM); | ||
414 | |||
415 | backlight = backlight_device_register(name, parent, devdata, ops, | ||
416 | props); | ||
417 | if (!IS_ERR(backlight)) { | ||
418 | *ptr = backlight; | ||
419 | devres_add(dev, ptr); | ||
420 | } else { | ||
421 | devres_free(ptr); | ||
422 | } | ||
423 | |||
424 | return backlight; | ||
425 | } | ||
426 | EXPORT_SYMBOL(devm_backlight_device_register); | ||
427 | |||
428 | /** | ||
429 | * devm_backlight_device_unregister - resource managed backlight_device_unregister() | ||
430 | * @dev: the device to unregister | ||
431 | * @bd: the backlight device to unregister | ||
432 | * | ||
433 | * Deallocated a backlight allocated with devm_backlight_device_register(). | ||
434 | * Normally this function will not need to be called and the resource management | ||
435 | * code will ensure that the resource is freed. | ||
436 | */ | ||
437 | void devm_backlight_device_unregister(struct device *dev, | ||
438 | struct backlight_device *bd) | ||
439 | { | ||
440 | int rc; | ||
441 | |||
442 | rc = devres_release(dev, devm_backlight_device_release, | ||
443 | devm_backlight_device_match, bd); | ||
444 | WARN_ON(rc); | ||
445 | } | ||
446 | EXPORT_SYMBOL(devm_backlight_device_unregister); | ||
447 | |||
373 | #ifdef CONFIG_OF | 448 | #ifdef CONFIG_OF |
374 | static int of_parent_match(struct device *dev, const void *data) | 449 | static int of_parent_match(struct device *dev, const void *data) |
375 | { | 450 | { |
diff --git a/include/linux/backlight.h b/include/linux/backlight.h index da9a0825e007..53b77949c79d 100644 --- a/include/linux/backlight.h +++ b/include/linux/backlight.h | |||
@@ -114,7 +114,13 @@ static inline void backlight_update_status(struct backlight_device *bd) | |||
114 | extern struct backlight_device *backlight_device_register(const char *name, | 114 | extern struct backlight_device *backlight_device_register(const char *name, |
115 | struct device *dev, void *devdata, const struct backlight_ops *ops, | 115 | struct device *dev, void *devdata, const struct backlight_ops *ops, |
116 | const struct backlight_properties *props); | 116 | const struct backlight_properties *props); |
117 | extern struct backlight_device *devm_backlight_device_register( | ||
118 | struct device *dev, const char *name, struct device *parent, | ||
119 | void *devdata, const struct backlight_ops *ops, | ||
120 | const struct backlight_properties *props); | ||
117 | extern void backlight_device_unregister(struct backlight_device *bd); | 121 | extern void backlight_device_unregister(struct backlight_device *bd); |
122 | extern void devm_backlight_device_unregister(struct device *dev, | ||
123 | struct backlight_device *bd); | ||
118 | extern void backlight_force_update(struct backlight_device *bd, | 124 | extern void backlight_force_update(struct backlight_device *bd, |
119 | enum backlight_update_reason reason); | 125 | enum backlight_update_reason reason); |
120 | 126 | ||