platform/x86: ideapad-laptop: Fix interrupt storm on fn-lock toggle on some Yoga...
authorArnav Rawat <arnavr3@illinois.edu>
Fri, 11 Nov 2022 14:32:09 +0000 (14:32 +0000)
committerHans de Goede <hdegoede@redhat.com>
Wed, 16 Nov 2022 07:47:08 +0000 (08:47 +0100)
Commit 3ae86d2d4704 ("platform/x86: ideapad-laptop: Fix Legion 5 Fn lock
LED") uses the WMI event-id for the fn-lock event on some Legion 5 laptops
to manually toggle the fn-lock LED because the EC does not do it itself.
However, the same WMI ID is also sent on some Yoga laptops. Here, setting
the fn-lock state is not valid behavior, and causes the EC to spam
interrupts until the laptop is rebooted.

Add a set_fn_lock_led_list[] DMI-id list and only enable the workaround to
manually set the LED on models on this list.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=212671
Cc: Meng Dong <whenov@gmail.com>
Signed-off-by: Arnav Rawat <arnavr3@illinois.edu>
Link: https://lore.kernel.org/r/12093851.O9o76ZdvQC@fedora
[hdegoede@redhat.com: Check DMI-id list only once and store the result]
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
drivers/platform/x86/ideapad-laptop.c

index 33b3dfd..6c460cd 100644 (file)
@@ -136,6 +136,7 @@ struct ideapad_private {
                bool dytc                 : 1;
                bool fan_mode             : 1;
                bool fn_lock              : 1;
+               bool set_fn_lock_led      : 1;
                bool hw_rfkill_switch     : 1;
                bool kbd_bl               : 1;
                bool touchpad_ctrl_via_ec : 1;
@@ -1501,6 +1502,9 @@ static void ideapad_wmi_notify(u32 value, void *context)
                ideapad_input_report(priv, value);
                break;
        case 208:
+               if (!priv->features.set_fn_lock_led)
+                       break;
+
                if (!eval_hals(priv->adev->handle, &result)) {
                        bool state = test_bit(HALS_FNLOCK_STATE_BIT, &result);
 
@@ -1514,6 +1518,18 @@ static void ideapad_wmi_notify(u32 value, void *context)
 }
 #endif
 
+/* On some models we need to call exec_sals(SALS_FNLOCK_ON/OFF) to set the LED */
+static const struct dmi_system_id set_fn_lock_led_list[] = {
+       {
+               /* https://bugzilla.kernel.org/show_bug.cgi?id=212671 */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Legion R7000P2020H"),
+               }
+       },
+       {}
+};
+
 /*
  * Some ideapads have a hardware rfkill switch, but most do not have one.
  * Reading VPCCMD_R_RF always results in 0 on models without a hardware rfkill,
@@ -1556,6 +1572,7 @@ static void ideapad_check_features(struct ideapad_private *priv)
        acpi_handle handle = priv->adev->handle;
        unsigned long val;
 
+       priv->features.set_fn_lock_led = dmi_check_system(set_fn_lock_led_list);
        priv->features.hw_rfkill_switch = dmi_check_system(hw_rfkill_list);
 
        /* Most ideapads with ELAN0634 touchpad don't use EC touchpad switch */