diff options
| author | Hans de Goede <hdegoede@redhat.com> | 2014-05-21 09:39:54 -0400 |
|---|---|---|
| committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-05-26 19:29:01 -0400 |
| commit | 3cc6919bd61315ea60baf95f3f9868aacfd1ace4 (patch) | |
| tree | e50ebe95421333e2c18a146fc449ead2b84cd0f4 | |
| parent | bee564430feec1175ee64bcfd4913cacc519f817 (diff) | |
backlight: Add backlight device (un)registration notification
Some firmware drivers, ie acpi-video want to get themselves out of the
way (in some cases) when their also is a raw backlight device available.
Due to module loading ordering being unknown, acpi-video cannot be certain
that the backlight_device_registered(BACKLIGHT_RAW) it does for this is
the final verdict wrt there being a BACKLIGHT_RAW device.
By adding notification acpi-video can listen for backlight devices showing
up after it has loaded, and unregister its backlight device if desired.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Jingoo Han <jg1.han@samsung.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
| -rw-r--r-- | drivers/video/backlight/backlight.c | 40 | ||||
| -rw-r--r-- | include/linux/backlight.h | 7 |
2 files changed, 47 insertions, 0 deletions
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index bd2172c2d650..428089009cd5 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | 23 | ||
| 24 | static struct list_head backlight_dev_list; | 24 | static struct list_head backlight_dev_list; |
| 25 | static struct mutex backlight_dev_list_mutex; | 25 | static struct mutex backlight_dev_list_mutex; |
| 26 | static struct blocking_notifier_head backlight_notifier; | ||
| 26 | 27 | ||
| 27 | static const char *const backlight_types[] = { | 28 | static const char *const backlight_types[] = { |
| 28 | [BACKLIGHT_RAW] = "raw", | 29 | [BACKLIGHT_RAW] = "raw", |
| @@ -370,6 +371,9 @@ struct backlight_device *backlight_device_register(const char *name, | |||
| 370 | list_add(&new_bd->entry, &backlight_dev_list); | 371 | list_add(&new_bd->entry, &backlight_dev_list); |
| 371 | mutex_unlock(&backlight_dev_list_mutex); | 372 | mutex_unlock(&backlight_dev_list_mutex); |
| 372 | 373 | ||
| 374 | blocking_notifier_call_chain(&backlight_notifier, | ||
| 375 | BACKLIGHT_REGISTERED, new_bd); | ||
| 376 | |||
| 373 | return new_bd; | 377 | return new_bd; |
| 374 | } | 378 | } |
| 375 | EXPORT_SYMBOL(backlight_device_register); | 379 | EXPORT_SYMBOL(backlight_device_register); |
| @@ -413,6 +417,10 @@ void backlight_device_unregister(struct backlight_device *bd) | |||
| 413 | pmac_backlight = NULL; | 417 | pmac_backlight = NULL; |
| 414 | mutex_unlock(&pmac_backlight_mutex); | 418 | mutex_unlock(&pmac_backlight_mutex); |
| 415 | #endif | 419 | #endif |
| 420 | |||
| 421 | blocking_notifier_call_chain(&backlight_notifier, | ||
| 422 | BACKLIGHT_UNREGISTERED, bd); | ||
| 423 | |||
| 416 | mutex_lock(&bd->ops_lock); | 424 | mutex_lock(&bd->ops_lock); |
| 417 | bd->ops = NULL; | 425 | bd->ops = NULL; |
| 418 | mutex_unlock(&bd->ops_lock); | 426 | mutex_unlock(&bd->ops_lock); |
| @@ -438,6 +446,36 @@ static int devm_backlight_device_match(struct device *dev, void *res, | |||
| 438 | } | 446 | } |
| 439 | 447 | ||
| 440 | /** | 448 | /** |
| 449 | * backlight_register_notifier - get notified of backlight (un)registration | ||
| 450 | * @nb: notifier block with the notifier to call on backlight (un)registration | ||
| 451 | * | ||
| 452 | * @return 0 on success, otherwise a negative error code | ||
| 453 | * | ||
| 454 | * Register a notifier to get notified when backlight devices get registered | ||
| 455 | * or unregistered. | ||
| 456 | */ | ||
| 457 | int backlight_register_notifier(struct notifier_block *nb) | ||
| 458 | { | ||
| 459 | return blocking_notifier_chain_register(&backlight_notifier, nb); | ||
| 460 | } | ||
| 461 | EXPORT_SYMBOL(backlight_register_notifier); | ||
| 462 | |||
| 463 | /** | ||
| 464 | * backlight_unregister_notifier - unregister a backlight notifier | ||
| 465 | * @nb: notifier block to unregister | ||
| 466 | * | ||
| 467 | * @return 0 on success, otherwise a negative error code | ||
| 468 | * | ||
| 469 | * Register a notifier to get notified when backlight devices get registered | ||
| 470 | * or unregistered. | ||
| 471 | */ | ||
| 472 | int backlight_unregister_notifier(struct notifier_block *nb) | ||
| 473 | { | ||
| 474 | return blocking_notifier_chain_unregister(&backlight_notifier, nb); | ||
| 475 | } | ||
| 476 | EXPORT_SYMBOL(backlight_unregister_notifier); | ||
| 477 | |||
| 478 | /** | ||
| 441 | * devm_backlight_device_register - resource managed backlight_device_register() | 479 | * devm_backlight_device_register - resource managed backlight_device_register() |
| 442 | * @dev: the device to register | 480 | * @dev: the device to register |
| 443 | * @name: the name of the device | 481 | * @name: the name of the device |
| @@ -544,6 +582,8 @@ static int __init backlight_class_init(void) | |||
| 544 | backlight_class->pm = &backlight_class_dev_pm_ops; | 582 | backlight_class->pm = &backlight_class_dev_pm_ops; |
| 545 | INIT_LIST_HEAD(&backlight_dev_list); | 583 | INIT_LIST_HEAD(&backlight_dev_list); |
| 546 | mutex_init(&backlight_dev_list_mutex); | 584 | mutex_init(&backlight_dev_list_mutex); |
| 585 | BLOCKING_INIT_NOTIFIER_HEAD(&backlight_notifier); | ||
| 586 | |||
| 547 | return 0; | 587 | return 0; |
| 548 | } | 588 | } |
| 549 | 589 | ||
diff --git a/include/linux/backlight.h b/include/linux/backlight.h index 72647429adf6..adb14a8616df 100644 --- a/include/linux/backlight.h +++ b/include/linux/backlight.h | |||
| @@ -40,6 +40,11 @@ enum backlight_type { | |||
| 40 | BACKLIGHT_TYPE_MAX, | 40 | BACKLIGHT_TYPE_MAX, |
| 41 | }; | 41 | }; |
| 42 | 42 | ||
| 43 | enum backlight_notification { | ||
| 44 | BACKLIGHT_REGISTERED, | ||
| 45 | BACKLIGHT_UNREGISTERED, | ||
| 46 | }; | ||
| 47 | |||
| 43 | struct backlight_device; | 48 | struct backlight_device; |
| 44 | struct fb_info; | 49 | struct fb_info; |
| 45 | 50 | ||
| @@ -133,6 +138,8 @@ extern void devm_backlight_device_unregister(struct device *dev, | |||
| 133 | extern void backlight_force_update(struct backlight_device *bd, | 138 | extern void backlight_force_update(struct backlight_device *bd, |
| 134 | enum backlight_update_reason reason); | 139 | enum backlight_update_reason reason); |
| 135 | extern bool backlight_device_registered(enum backlight_type type); | 140 | extern bool backlight_device_registered(enum backlight_type type); |
| 141 | extern int backlight_register_notifier(struct notifier_block *nb); | ||
| 142 | extern int backlight_unregister_notifier(struct notifier_block *nb); | ||
| 136 | 143 | ||
| 137 | #define to_backlight_device(obj) container_of(obj, struct backlight_device, dev) | 144 | #define to_backlight_device(obj) container_of(obj, struct backlight_device, dev) |
| 138 | 145 | ||
