Re: [PATCH v2 6/6] platform/x86: ayaneo-ec: Add suspend hook

From: Armin Wolf
Date: Sun Oct 26 2025 - 18:50:07 EST


Am 15.10.25 um 10:44 schrieb Antheas Kapenekakis:

The Ayaneo EC resets after hibernation, losing the charge control state.
Add a small PM hook to restore this state on hibernation resume.

The fan speed is also lost during hibernation, but since hibernation
failures are common with this class of devices, setting a low fan speed
when the userspace program controlling the fan will potentially not
take over could cause the device to overheat, so it is not restored.

I am still not happy with potentially breaking fancontrol on this device.
Most users expect fancontrol to continue working after hibernation, so not
restoring the fan speed configuration seems risky to me. Would it be enough
to warn users about his inside the documentation?


Signed-off-by: Antheas Kapenekakis <lkml@xxxxxxxxxxx>
---
drivers/platform/x86/ayaneo-ec.c | 42 ++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)

diff --git a/drivers/platform/x86/ayaneo-ec.c b/drivers/platform/x86/ayaneo-ec.c
index 73e9dd39c703..8529f6f8dc69 100644
--- a/drivers/platform/x86/ayaneo-ec.c
+++ b/drivers/platform/x86/ayaneo-ec.c
@@ -37,6 +37,8 @@
#define AYANEO_MODULE_LEFT BIT(0)
#define AYANEO_MODULE_RIGHT BIT(1)
+#define AYANEO_CACHE_LEN 1
+
struct ayaneo_ec_quirk {
bool has_fan_control;
bool has_charge_control;
@@ -47,6 +49,8 @@ struct ayaneo_ec_platform_data {
struct platform_device *pdev;
struct ayaneo_ec_quirk *quirks;
struct acpi_battery_hook battery_hook;
+
+ u8 cache[AYANEO_CACHE_LEN];
};
static const struct ayaneo_ec_quirk quirk_fan = {
@@ -464,10 +468,48 @@ static int ayaneo_ec_probe(struct platform_device *pdev)
return 0;
}
+static int ayaneo_freeze(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct ayaneo_ec_platform_data *data = platform_get_drvdata(pdev);
+ int ret, i = 0;
+
+ if (data->quirks->has_charge_control) {
+ ret = ec_read(AYANEO_CHARGE_REG, &data->cache[i]);
+ if (ret)
+ return ret;
+ i++;
+ }
+
+ return 0;
+}
+
+static int ayaneo_thaw(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct ayaneo_ec_platform_data *data = platform_get_drvdata(pdev);
+ int ret, i = 0;
+
+ if (data->quirks->has_charge_control) {
+ ret = ec_write(AYANEO_CHARGE_REG, data->cache[i]);
+ if (ret)
+ return ret;
+ i++;
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops ayaneo_pm_ops = {
+ .freeze = ayaneo_freeze,
+ .thaw = ayaneo_thaw,
+};
+
static struct platform_driver ayaneo_platform_driver = {
.driver = {
.name = "ayaneo-ec",
.dev_groups = ayaneo_ec_groups,
+ .pm = &ayaneo_pm_ops,

Please use pm_sleep_ptr() here.

Thanks,
Armin Wolf

},
.probe = ayaneo_ec_probe,
};