platform/x86: think-lmi: Add pending_reboot support
authorMark Pearson <markpearson@lenovo.com>
Mon, 28 Jun 2021 22:28:46 +0000 (18:28 -0400)
committerHans de Goede <hdegoede@redhat.com>
Wed, 14 Jul 2021 13:06:27 +0000 (15:06 +0200)
The Think-lmi driver was missing pending_reboot support as it wasn't
available from the BIOS. Turns out this is really useful to have from
user space so implementing from a purely SW point of view.

Thanks to Mario Limonciello for guidance on how fwupd would use this.

Suggested-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Mark Pearson <markpearson@lenovo.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20210628222846.8830-1-markpearson@lenovo.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
drivers/platform/x86/think-lmi.c
drivers/platform/x86/think-lmi.h

index 3671b5d206132872a348f4254f7a218aa372e60e..64dcec53a7a05e494a2f4c55eff1609191d14bcb 100644 (file)
@@ -571,6 +571,11 @@ static ssize_t current_value_store(struct kobject *kobj,
        else
                ret = tlmi_save_bios_settings("");
 
+       if (!ret && !tlmi_priv.pending_changes) {
+               tlmi_priv.pending_changes = true;
+               /* let userland know it may need to check reboot pending again */
+               kobject_uevent(&tlmi_priv.class_dev->kobj, KOBJ_CHANGE);
+       }
 out:
        kfree(auth_str);
        kfree(set_str);
@@ -647,6 +652,14 @@ static struct kobj_type tlmi_pwd_setting_ktype = {
        .sysfs_ops      = &tlmi_kobj_sysfs_ops,
 };
 
+static ssize_t pending_reboot_show(struct kobject *kobj, struct kobj_attribute *attr,
+                                  char *buf)
+{
+       return sprintf(buf, "%d\n", tlmi_priv.pending_changes);
+}
+
+static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot);
+
 /* ---- Initialisation --------------------------------------------------------- */
 static void tlmi_release_attr(void)
 {
@@ -667,6 +680,7 @@ static void tlmi_release_attr(void)
        sysfs_remove_group(&tlmi_priv.pwd_power->kobj, &auth_attr_group);
        kobject_put(&tlmi_priv.pwd_power->kobj);
        kset_unregister(tlmi_priv.authentication_kset);
+       sysfs_remove_file(&tlmi_priv.class_dev->kobj, &pending_reboot.attr);
 }
 
 static int tlmi_sysfs_init(void)
@@ -746,6 +760,11 @@ static int tlmi_sysfs_init(void)
        if (ret)
                goto fail_create_attr;
 
+       /* Create global sysfs files */
+       ret = sysfs_create_file(&tlmi_priv.class_dev->kobj, &pending_reboot.attr);
+       if (ret)
+               goto fail_create_attr;
+
        return ret;
 
 fail_create_attr:
index 6fa8da7af6c78a86c151163424feab78820ac7c8..eb598846628a6450e4024c730485923d0b06e395 100644 (file)
@@ -60,6 +60,7 @@ struct think_lmi {
        bool can_get_bios_selections;
        bool can_set_bios_password;
        bool can_get_password_settings;
+       bool pending_changes;
 
        struct tlmi_attr_setting *setting[TLMI_SETTINGS_COUNT];
        struct device *class_dev;