From: Armin Wolf <W_Armin@gmx.de>
To: hansg@kernel.org, ilpo.jarvinen@linux.intel.com
Cc: wse@tuxedocomputers.com, platform-driver-x86@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH v2 5/7] platform/x86: uniwill-laptop: Rework FN lock/super key suspend handling
Date: Fri, 17 Apr 2026 07:09:10 +0200 [thread overview]
Message-ID: <20260417050912.5582-6-W_Armin@gmx.de> (raw)
In-Reply-To: <20260417050912.5582-1-W_Armin@gmx.de>
Currently the suspend handling for the FN lock and super key enable
features saves the whole values of the affected registers instead of
the individual feature state. This duplicates the register access
logic from the associated sysfs attributes.
Rework the suspend handling to reuse said register access logic and
only store the individual feature state as a boolean value.
Reviewed-by: Werner Sembach <wse@tuxedocomputers.com>
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
---
drivers/platform/x86/uniwill/uniwill-acpi.c | 117 ++++++++++++--------
1 file changed, 73 insertions(+), 44 deletions(-)
diff --git a/drivers/platform/x86/uniwill/uniwill-acpi.c b/drivers/platform/x86/uniwill/uniwill-acpi.c
index dac80c78ca0b..8c00d762ab08 100644
--- a/drivers/platform/x86/uniwill/uniwill-acpi.c
+++ b/drivers/platform/x86/uniwill/uniwill-acpi.c
@@ -341,8 +341,8 @@ struct uniwill_data {
struct acpi_battery_hook hook;
unsigned int last_charge_ctrl;
struct mutex battery_lock; /* Protects the list of currently registered batteries */
- unsigned int last_status;
- unsigned int last_switch_status;
+ bool last_fn_lock_state;
+ bool last_super_key_enable_state;
struct mutex super_key_lock; /* Protects the toggling of the super key lock state */
struct list_head batteries;
struct mutex led_lock; /* Protects writes to the lightbar registers */
@@ -619,11 +619,22 @@ static const struct regmap_config uniwill_ec_config = {
.use_single_write = true,
};
+static int uniwill_write_fn_lock(struct uniwill_data *data, bool status)
+{
+ unsigned int value;
+
+ if (status)
+ value = FN_LOCK_STATUS;
+ else
+ value = 0;
+
+ return regmap_update_bits(data->regmap, EC_ADDR_BIOS_OEM, FN_LOCK_STATUS, value);
+}
+
static ssize_t fn_lock_store(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct uniwill_data *data = dev_get_drvdata(dev);
- unsigned int value;
bool enable;
int ret;
@@ -631,21 +642,15 @@ static ssize_t fn_lock_store(struct device *dev, struct device_attribute *attr,
if (ret < 0)
return ret;
- if (enable)
- value = FN_LOCK_STATUS;
- else
- value = 0;
-
- ret = regmap_update_bits(data->regmap, EC_ADDR_BIOS_OEM, FN_LOCK_STATUS, value);
+ ret = uniwill_write_fn_lock(data, enable);
if (ret < 0)
return ret;
return count;
}
-static ssize_t fn_lock_show(struct device *dev, struct device_attribute *attr, char *buf)
+static int uniwill_read_fn_lock(struct uniwill_data *data, bool *status)
{
- struct uniwill_data *data = dev_get_drvdata(dev);
unsigned int value;
int ret;
@@ -653,23 +658,31 @@ static ssize_t fn_lock_show(struct device *dev, struct device_attribute *attr, c
if (ret < 0)
return ret;
- return sysfs_emit(buf, "%d\n", !!(value & FN_LOCK_STATUS));
-}
+ *status = !!(value & FN_LOCK_STATUS);
-static DEVICE_ATTR_RW(fn_lock);
+ return 0;
+}
-static ssize_t super_key_enable_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t fn_lock_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct uniwill_data *data = dev_get_drvdata(dev);
- unsigned int value;
- bool enable;
+ bool status;
int ret;
- ret = kstrtobool(buf, &enable);
+ ret = uniwill_read_fn_lock(data, &status);
if (ret < 0)
return ret;
+ return sysfs_emit(buf, "%d\n", status);
+}
+
+static DEVICE_ATTR_RW(fn_lock);
+
+static int uniwill_write_super_key_enable(struct uniwill_data *data, bool status)
+{
+ unsigned int value;
+ int ret;
+
guard(mutex)(&data->super_key_lock);
ret = regmap_read(data->regmap, EC_ADDR_SWITCH_STATUS, &value);
@@ -680,20 +693,33 @@ static ssize_t super_key_enable_store(struct device *dev, struct device_attribut
* We can only toggle the super key lock, so we return early if the setting
* is already in the correct state.
*/
- if (enable == !(value & SUPER_KEY_LOCK_STATUS))
- return count;
+ if (status == !(value & SUPER_KEY_LOCK_STATUS))
+ return 0;
+
+ return regmap_write_bits(data->regmap, EC_ADDR_TRIGGER, TRIGGER_SUPER_KEY_LOCK,
+ TRIGGER_SUPER_KEY_LOCK);
+}
+
+static ssize_t super_key_enable_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct uniwill_data *data = dev_get_drvdata(dev);
+ bool enable;
+ int ret;
- ret = regmap_write_bits(data->regmap, EC_ADDR_TRIGGER, TRIGGER_SUPER_KEY_LOCK,
- TRIGGER_SUPER_KEY_LOCK);
+ ret = kstrtobool(buf, &enable);
+ if (ret < 0)
+ return ret;
+
+ ret = uniwill_write_super_key_enable(data, enable);
if (ret < 0)
return ret;
return count;
}
-static ssize_t super_key_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
+static int uniwill_read_super_key_enable(struct uniwill_data *data, bool *status)
{
- struct uniwill_data *data = dev_get_drvdata(dev);
unsigned int value;
int ret;
@@ -701,7 +727,22 @@ static ssize_t super_key_enable_show(struct device *dev, struct device_attribute
if (ret < 0)
return ret;
- return sysfs_emit(buf, "%d\n", !(value & SUPER_KEY_LOCK_STATUS));
+ *status = !(value & SUPER_KEY_LOCK_STATUS);
+
+ return 0;
+}
+
+static ssize_t super_key_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct uniwill_data *data = dev_get_drvdata(dev);
+ bool status;
+ int ret;
+
+ ret = uniwill_read_super_key_enable(data, &status);
+ if (ret < 0)
+ return ret;
+
+ return sysfs_emit(buf, "%d\n", status);
}
static DEVICE_ATTR_RW(super_key_enable);
@@ -1715,10 +1756,10 @@ static int uniwill_suspend_fn_lock(struct uniwill_data *data)
return 0;
/*
- * The EC_ADDR_BIOS_OEM is marked as volatile, so we have to restore it
+ * EC_ADDR_BIOS_OEM is marked as volatile, so we have to restore it
* ourselves.
*/
- return regmap_read(data->regmap, EC_ADDR_BIOS_OEM, &data->last_status);
+ return uniwill_read_fn_lock(data, &data->last_fn_lock_state);
}
static int uniwill_suspend_super_key(struct uniwill_data *data)
@@ -1727,10 +1768,10 @@ static int uniwill_suspend_super_key(struct uniwill_data *data)
return 0;
/*
- * The EC_ADDR_SWITCH_STATUS is marked as volatile, so we have to restore it
+ * EC_ADDR_SWITCH_STATUS is marked as volatile, so we have to restore it
* ourselves.
*/
- return regmap_read(data->regmap, EC_ADDR_SWITCH_STATUS, &data->last_switch_status);
+ return uniwill_read_super_key_enable(data, &data->last_super_key_enable_state);
}
static int uniwill_suspend_battery(struct uniwill_data *data)
@@ -1787,27 +1828,15 @@ static int uniwill_resume_fn_lock(struct uniwill_data *data)
if (!uniwill_device_supports(data, UNIWILL_FEATURE_FN_LOCK))
return 0;
- return regmap_update_bits(data->regmap, EC_ADDR_BIOS_OEM, FN_LOCK_STATUS,
- data->last_status);
+ return uniwill_write_fn_lock(data, data->last_fn_lock_state);
}
static int uniwill_resume_super_key(struct uniwill_data *data)
{
- unsigned int value;
- int ret;
-
if (!uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY))
return 0;
- ret = regmap_read(data->regmap, EC_ADDR_SWITCH_STATUS, &value);
- if (ret < 0)
- return ret;
-
- if ((data->last_switch_status & SUPER_KEY_LOCK_STATUS) == (value & SUPER_KEY_LOCK_STATUS))
- return 0;
-
- return regmap_write_bits(data->regmap, EC_ADDR_TRIGGER, TRIGGER_SUPER_KEY_LOCK,
- TRIGGER_SUPER_KEY_LOCK);
+ return uniwill_write_super_key_enable(data, data->last_super_key_enable_state);
}
static int uniwill_resume_battery(struct uniwill_data *data)
--
2.39.5
next prev parent reply other threads:[~2026-04-17 5:09 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-17 5:09 [PATCH v2 0/7] platform/x86: uniwill-laptop: Charging-related improvements Armin Wolf
2026-04-17 5:09 ` [PATCH v2 1/7] platform/x86: uniwill-laptop: Properly initialize charging threshold Armin Wolf
2026-04-30 12:53 ` Ilpo Järvinen
2026-05-03 21:34 ` Armin Wolf
2026-04-17 5:09 ` [PATCH v2 2/7] platform/x86: uniwill-laptop: Accept charging threshold of 0 Armin Wolf
2026-04-30 12:55 ` Ilpo Järvinen
2026-04-17 5:09 ` [PATCH v2 3/7] platform/x86: uniwill-laptop: Fix behavior of "force" module param Armin Wolf
2026-04-17 12:01 ` Werner Sembach
2026-04-30 12:57 ` Ilpo Järvinen
2026-04-17 5:09 ` [PATCH v2 4/7] platform/x86: uniwill-laptop: Do not enable the charging limit even when forced Armin Wolf
2026-04-17 12:01 ` Werner Sembach
2026-04-30 12:57 ` Ilpo Järvinen
2026-04-17 5:09 ` Armin Wolf [this message]
2026-04-30 13:11 ` [PATCH v2 5/7] platform/x86: uniwill-laptop: Rework FN lock/super key suspend handling Ilpo Järvinen
2026-04-17 5:09 ` [PATCH v2 6/7] platform/x86: uniwill-laptop: Mark EC_ADDR_OEM_4 as volatile Armin Wolf
2026-04-30 13:13 ` Ilpo Järvinen
2026-04-17 5:09 ` [PATCH v2 7/7] platform/x86: uniwill-laptop: Add support for battery charge modes Armin Wolf
2026-04-20 20:03 ` Werner Sembach
2026-04-30 13:22 ` Ilpo Järvinen
2026-04-30 13:41 ` Armin Wolf
2026-05-04 8:44 ` Werner Sembach
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260417050912.5582-6-W_Armin@gmx.de \
--to=w_armin@gmx.de \
--cc=hansg@kernel.org \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=platform-driver-x86@vger.kernel.org \
--cc=wse@tuxedocomputers.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox