ACPI / video: Unregister the backlight device if a raw one shows up later
authorHans de Goede <hdegoede@redhat.com>
Wed, 21 May 2014 13:39:55 +0000 (15:39 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 26 May 2014 23:29:01 +0000 (01:29 +0200)
When video.use_native_backlight=1 and non intel gfx are in use, the raw
backlight device of the gfx driver will show up after acpi-video has done its
acpi_video_verify_backlight_support() check.

This causes video.use_native_backlight=1 to not have the desired result.

This patch fixes this by adding a backlight notifier and when a raw
backlight is registered or unregistered re-doing the
acpi_video_verify_backlight_support() check.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/video.c

index cd4389262d4f30838c7ca50bcc130cc042ee9069..d40c04cbb422b43a3fcbf329f98387aaf2e0ab83 100644 (file)
@@ -151,6 +151,7 @@ struct acpi_video_enumerated_device {
 struct acpi_video_bus {
        struct acpi_device *device;
        bool backlight_registered;
+       bool backlight_notifier_registered;
        u8 dos_setting;
        struct acpi_video_enumerated_device *attached_array;
        u8 attached_count;
@@ -162,6 +163,7 @@ struct acpi_video_bus {
        struct input_dev *input;
        char phys[32];  /* for input device */
        struct notifier_block pm_nb;
+       struct notifier_block backlight_nb;
 };
 
 struct acpi_video_device_flags {
@@ -1732,6 +1734,9 @@ static int acpi_video_bus_register_backlight(struct acpi_video_bus *video)
 {
        struct acpi_video_device *dev;
 
+       if (video->backlight_registered)
+               return 0;
+
        if (!acpi_video_verify_backlight_support())
                return 0;
 
@@ -1876,6 +1881,56 @@ static void acpi_video_bus_remove_notify_handler(struct acpi_video_bus *video)
        video->input = NULL;
 }
 
+static int acpi_video_backlight_notify(struct notifier_block *nb,
+                                       unsigned long val, void *bd)
+{
+       struct backlight_device *backlight = bd;
+       struct acpi_video_bus *video;
+
+       /* acpi_video_verify_backlight_support only cares about raw devices */
+       if (backlight->props.type != BACKLIGHT_RAW)
+               return NOTIFY_DONE;
+
+       video = container_of(nb, struct acpi_video_bus, backlight_nb);
+
+       switch (val) {
+       case BACKLIGHT_REGISTERED:
+               if (!acpi_video_verify_backlight_support())
+                       acpi_video_bus_unregister_backlight(video);
+               break;
+       case BACKLIGHT_UNREGISTERED:
+               acpi_video_bus_register_backlight(video);
+               break;
+       }
+
+       return NOTIFY_OK;
+}
+
+static int acpi_video_bus_add_backlight_notify_handler(
+                                               struct acpi_video_bus *video)
+{
+       int error;
+
+       video->backlight_nb.notifier_call = acpi_video_backlight_notify;
+       video->backlight_nb.priority = 0;
+       error = backlight_register_notifier(&video->backlight_nb);
+       if (error == 0)
+               video->backlight_notifier_registered = true;
+
+       return error;
+}
+
+static int acpi_video_bus_remove_backlight_notify_handler(
+                                               struct acpi_video_bus *video)
+{
+       if (!video->backlight_notifier_registered)
+               return 0;
+
+       video->backlight_notifier_registered = false;
+
+       return backlight_unregister_notifier(&video->backlight_nb);
+}
+
 static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
 {
        struct acpi_video_device *dev, *next;
@@ -1957,6 +2012,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
 
        acpi_video_bus_register_backlight(video);
        acpi_video_bus_add_notify_handler(video);
+       acpi_video_bus_add_backlight_notify_handler(video);
 
        return 0;
 
@@ -1980,6 +2036,7 @@ static int acpi_video_bus_remove(struct acpi_device *device)
 
        video = acpi_driver_data(device);
 
+       acpi_video_bus_remove_backlight_notify_handler(video);
        acpi_video_bus_remove_notify_handler(video);
        acpi_video_bus_unregister_backlight(video);
        acpi_video_bus_put_devices(video);
This page took 0.029971 seconds and 5 git commands to generate.