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 | ||