Merge tag 'objtool-core-2022-10-07' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-block.git] / drivers / acpi / acpi_video.c
index 6d209ea68bd8e8754f1e51ac13867015e60fd33e..32953646caebf6a57bac1d367ad0d79ec104d822 100644 (file)
@@ -47,9 +47,6 @@ module_param(brightness_switch_enabled, bool, 0644);
 static bool allow_duplicates;
 module_param(allow_duplicates, bool, 0644);
 
-static int disable_backlight_sysfs_if = -1;
-module_param(disable_backlight_sysfs_if, int, 0444);
-
 #define REPORT_OUTPUT_KEY_EVENTS               0x01
 #define REPORT_BRIGHTNESS_KEY_EVENTS           0x02
 static int report_key_events = -1;
@@ -73,6 +70,16 @@ module_param(device_id_scheme, bool, 0444);
 static int only_lcd = -1;
 module_param(only_lcd, int, 0444);
 
+/*
+ * Display probing is known to take up to 5 seconds, so delay the fallback
+ * backlight registration by 5 seconds + 3 seconds for some extra margin.
+ */
+static int register_backlight_delay = 8;
+module_param(register_backlight_delay, int, 0444);
+MODULE_PARM_DESC(register_backlight_delay,
+       "Delay in seconds before doing fallback (non GPU driver triggered) "
+       "backlight registration, set to 0 to disable.");
+
 static bool may_report_brightness_keys;
 static int register_count;
 static DEFINE_MUTEX(register_count_mutex);
@@ -81,7 +88,9 @@ static LIST_HEAD(video_bus_head);
 static int acpi_video_bus_add(struct acpi_device *device);
 static int acpi_video_bus_remove(struct acpi_device *device);
 static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
-void acpi_video_detect_exit(void);
+static void acpi_video_bus_register_backlight_work(struct work_struct *ignored);
+static DECLARE_DELAYED_WORK(video_bus_register_backlight_work,
+                           acpi_video_bus_register_backlight_work);
 
 /*
  * Indices in the _BCL method response: the first two items are special,
@@ -382,14 +391,6 @@ static int video_set_bqc_offset(const struct dmi_system_id *d)
        return 0;
 }
 
-static int video_disable_backlight_sysfs_if(
-       const struct dmi_system_id *d)
-{
-       if (disable_backlight_sysfs_if == -1)
-               disable_backlight_sysfs_if = 1;
-       return 0;
-}
-
 static int video_set_device_id_scheme(const struct dmi_system_id *d)
 {
        device_id_scheme = true;
@@ -462,56 +463,6 @@ static const struct dmi_system_id video_dmi_table[] = {
                },
        },
 
-       /*
-        * Some machines have a broken acpi-video interface for brightness
-        * control, but still need an acpi_video_device_lcd_set_level() call
-        * on resume to turn the backlight power on.  We Enable backlight
-        * control on these systems, but do not register a backlight sysfs
-        * as brightness control does not work.
-        */
-       {
-        /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */
-        .callback = video_disable_backlight_sysfs_if,
-        .ident = "Toshiba Portege R700",
-        .matches = {
-               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
-               DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R700"),
-               },
-       },
-       {
-        /* https://bugs.freedesktop.org/show_bug.cgi?id=82634 */
-        .callback = video_disable_backlight_sysfs_if,
-        .ident = "Toshiba Portege R830",
-        .matches = {
-               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
-               DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R830"),
-               },
-       },
-       {
-        /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */
-        .callback = video_disable_backlight_sysfs_if,
-        .ident = "Toshiba Satellite R830",
-        .matches = {
-               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
-               DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE R830"),
-               },
-       },
-       {
-        .callback = video_disable_backlight_sysfs_if,
-        .ident = "Toshiba Satellite Z830",
-        .matches = {
-               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
-               DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Z830"),
-               },
-       },
-       {
-        .callback = video_disable_backlight_sysfs_if,
-        .ident = "Toshiba Portege Z830",
-        .matches = {
-               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
-               DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE Z830"),
-               },
-       },
        /*
         * Some machine's _DOD IDs don't have bit 31(Device ID Scheme) set
         * but the IDs actually follow the Device ID Scheme.
@@ -1774,9 +1725,6 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device)
        if (result)
                return;
 
-       if (disable_backlight_sysfs_if > 0)
-               return;
-
        name = kasprintf(GFP_KERNEL, "acpi_video%d", count);
        if (!name)
                return;
@@ -1875,8 +1823,6 @@ static int acpi_video_bus_register_backlight(struct acpi_video_bus *video)
        if (video->backlight_registered)
                return 0;
 
-       acpi_video_run_bcl_for_osi(video);
-
        if (acpi_video_get_backlight_type() != acpi_backlight_video)
                return 0;
 
@@ -2102,7 +2048,11 @@ static int acpi_video_bus_add(struct acpi_device *device)
        list_add_tail(&video->entry, &video_bus_head);
        mutex_unlock(&video_list_lock);
 
-       acpi_video_bus_register_backlight(video);
+       /*
+        * The userspace visible backlight_device gets registered separately
+        * from acpi_video_register_backlight().
+        */
+       acpi_video_run_bcl_for_osi(video);
        acpi_video_bus_add_notify_handler(video);
 
        return 0;
@@ -2127,20 +2077,25 @@ static int acpi_video_bus_remove(struct acpi_device *device)
 
        video = acpi_driver_data(device);
 
-       acpi_video_bus_remove_notify_handler(video);
-       acpi_video_bus_unregister_backlight(video);
-       acpi_video_bus_put_devices(video);
-
        mutex_lock(&video_list_lock);
        list_del(&video->entry);
        mutex_unlock(&video_list_lock);
 
+       acpi_video_bus_remove_notify_handler(video);
+       acpi_video_bus_unregister_backlight(video);
+       acpi_video_bus_put_devices(video);
+
        kfree(video->attached_array);
        kfree(video);
 
        return 0;
 }
 
+static void acpi_video_bus_register_backlight_work(struct work_struct *ignored)
+{
+       acpi_video_register_backlight();
+}
+
 static int __init is_i740(struct pci_dev *dev)
 {
        if (dev->device == 0x00D1)
@@ -2251,6 +2206,18 @@ int acpi_video_register(void)
         */
        register_count = 1;
 
+       /*
+        * acpi_video_bus_add() skips registering the userspace visible
+        * backlight_device. The intend is for this to be registered by the
+        * drm/kms driver calling acpi_video_register_backlight() *after* it is
+        * done setting up its own native backlight device. The delayed work
+        * ensures that acpi_video_register_backlight() always gets called
+        * eventually, in case there is no drm/kms driver or it is disabled.
+        */
+       if (register_backlight_delay)
+               schedule_delayed_work(&video_bus_register_backlight_work,
+                                     register_backlight_delay * HZ);
+
 leave:
        mutex_unlock(&register_count_mutex);
        return ret;
@@ -2261,6 +2228,7 @@ void acpi_video_unregister(void)
 {
        mutex_lock(&register_count_mutex);
        if (register_count) {
+               cancel_delayed_work_sync(&video_bus_register_backlight_work);
                acpi_bus_unregister_driver(&acpi_video_bus);
                register_count = 0;
                may_report_brightness_keys = false;
@@ -2269,19 +2237,16 @@ void acpi_video_unregister(void)
 }
 EXPORT_SYMBOL(acpi_video_unregister);
 
-void acpi_video_unregister_backlight(void)
+void acpi_video_register_backlight(void)
 {
        struct acpi_video_bus *video;
 
-       mutex_lock(&register_count_mutex);
-       if (register_count) {
-               mutex_lock(&video_list_lock);
-               list_for_each_entry(video, &video_bus_head, entry)
-                       acpi_video_bus_unregister_backlight(video);
-               mutex_unlock(&video_list_lock);
-       }
-       mutex_unlock(&register_count_mutex);
+       mutex_lock(&video_list_lock);
+       list_for_each_entry(video, &video_bus_head, entry)
+               acpi_video_bus_register_backlight(video);
+       mutex_unlock(&video_list_lock);
 }
+EXPORT_SYMBOL(acpi_video_register_backlight);
 
 bool acpi_video_handles_brightness_key_presses(void)
 {
@@ -2318,7 +2283,6 @@ static int __init acpi_video_init(void)
 
 static void __exit acpi_video_exit(void)
 {
-       acpi_video_detect_exit();
        acpi_video_unregister();
 }