From: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
To: Bartu Alev <bartualev@gmail.com>
Cc: Corentin Chary <corentin.chary@gmail.com>,
"Luke D. Jones" <luke@ljones.dev>,
Denis Benato <denis.benato@linux.dev>,
Hans de Goede <hansg@kernel.org>,
platform-driver-x86@vger.kernel.org,
LKML <linux-kernel@vger.kernel.org>,
linux-hwmon@vger.kernel.org, Guenter Roeck <linux@roeck-us.net>,
linux-api@vger.kernel.org
Subject: Re: [PATCH 7/7] platform/x86: asus-wmi: show the effective duty for enabled curves
Date: Mon, 9 Nov 2026 20:39:19 +0200 (EET) [thread overview]
Message-ID: <9e4832e9-9bd1-85c0-8b4d-e1de98373690@linux.intel.com> (raw)
In-Reply-To: <20261101-asus-fan-floors-v4-v1-7-b8d1c31a99a9@gmail.com>
On Sun, 1 Nov 2026, Bartu Alev wrote:
> When a custom fan curve is enabled, the embedded controller executes
> each point at max(written_duty, floor_duty). However,
> pwmY_auto_pointZ_pwm reports only the stored value, diverging from
> the duty applied by hardware.
>
> Return max(stored, floor) from pwmY_auto_pointZ_pwm when the curve is
> enabled and floor data is valid. When disabled, continue returning
> the stored value.
>
> Because the controller operates in integer percentages while sysfs
> uses PWM units (0-255), the reported value is an upper bound of the
> applied duty. Consequently, reading an enabled curve is not
> read/modify/write safe: writing back a read value commits the
> firmware floor into the stored curve.
>
> Trigger sysfs notifications on pwmY_auto_pointZ_pwm on enable and
> disable transitions, as well as floor refreshes, so pollers detect
> changes in effective duty.
>
> Signed-off-by: Bartu Alev <bartualev@gmail.com>
> ---
> Documentation/ABI/testing/sysfs-platform-asus-wmi | 14 +++++++++++
> drivers/platform/x86/asus-wmi.c | 30 +++++++++++++++++++----
> 2 files changed, 39 insertions(+), 5 deletions(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi
> index 24931cc97ca86..36b633a5dfc49 100644
> --- a/Documentation/ABI/testing/sysfs-platform-asus-wmi
> +++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi
> @@ -281,6 +281,20 @@ Description:
> (0-255); the driver scales the duty to the percentage the
> firmware expects when the curve is enabled.
>
> + While the curve is enabled, _pwm reports the effective duty,
> + which is the higher of the stored duty and the firmware floor
> + of the point (pwmY_auto_pointZ_floor_pwm). A disabled curve
> + reports the stored duty. The controller works in whole
> + percent, so the reported value is an upper bound: the applied
> + duty can be up to 2.5 pwm units lower.
> +
> + Reading while the curve is enabled is therefore not
> + read-modify-write safe: a curve editor that reads the points
> + and writes them back stores the effective duty as the new
> + curve, and the duty the user originally wrote is lost. Read
> + the curve while it is disabled, or write back the values that
> + were written rather than the ones that were read.
> +
> The embedded controller binds point Z (Z = 1..8) to the
> temperature decade [30 + 10 * (Z - 1), 39 + 10 * (Z - 1)]
> degrees Celsius and silently clamps the threshold into that
> diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
> index 74476904cb99c..bae5a528ac5d8 100644
> --- a/drivers/platform/x86/asus-wmi.c
> +++ b/drivers/platform/x86/asus-wmi.c
> @@ -324,7 +324,7 @@ struct asus_wmi {
> bool gpu_fan_curve_available;
> bool mid_fan_curve_available;
> struct fan_curve_data custom_fan_curves[3];
> - /* protects custom_fan_curves[].floors */
> + /* protects custom_fan_curves[].floors and .floors_valid */
> struct mutex fan_curve_lock;
> struct device *fan_curve_hwmon;
>
> @@ -3754,7 +3754,7 @@ static int fan_curve_load_floors(struct asus_wmi *asus, u32 fan_dev)
> return 0;
> }
>
> -static void fan_curve_notify_floors(struct asus_wmi *asus)
> +static void fan_curve_notify(struct asus_wmi *asus)
> {
> struct device *hwmon = asus->fan_curve_hwmon;
> bool valid[ARRAY_SIZE(asus->custom_fan_curves)];
> @@ -3778,6 +3778,10 @@ static void fan_curve_notify_floors(struct asus_wmi *asus)
> "pwm%d_auto_point%d_floor_pwm",
> fan + 1, point + 1);
> sysfs_notify(&hwmon->kobj, NULL, name);
> + snprintf(name, sizeof(name),
scnprintf()
> + "pwm%d_auto_point%d_pwm",
> + fan + 1, point + 1);
> + sysfs_notify(&hwmon->kobj, NULL, name);
> }
> }
> }
> @@ -3797,7 +3801,7 @@ static void fan_curve_refresh_floors(struct asus_wmi *asus)
> if (asus->mid_fan_curve_available)
> fan_curve_load_floors(asus, ASUS_WMI_DEVID_MID_FAN_CURVE);
>
> - fan_curve_notify_floors(asus);
> + fan_curve_notify(asus);
> }
>
> /* Check if the capability exists, populate its defaults and read its floor table */
> @@ -3855,15 +3859,28 @@ static ssize_t fan_curve_show(struct device *dev,
> struct asus_wmi *asus = dev_get_drvdata(dev);
> struct fan_curve_data *data;
> int value, pwm, index;
> + bool enabled;
>
> data = fan_curve_attr_2_select(asus, attr);
> pwm = dev_attr->nr & FAN_CURVE_PWM_MASK;
> index = dev_attr->index;
>
> - if (pwm)
> + if (pwm) {
> + enabled = data->enabled;
> value = data->percents[index];
> - else
> +
> + /*
> + * The EC runs the point at the higher of the curve and the
> + * firmware floor, so report the duty it applies. Only the
> + * floor table is protected by fan_curve_lock; enabled and
> + * percents are written without it, so this is a snapshot.
> + */
> + guard(mutex)(&asus->fan_curve_lock);
> + if (enabled && data->floors_valid)
> + value = max(value, (int)data->floors[index]);
> + } else {
> value = data->temps[index];
> + }
>
> return sysfs_emit(buf, "%d\n", value);
> }
> @@ -4059,6 +4076,9 @@ static ssize_t fan_curve_enable_store(struct device *dev,
> fan_curve_refresh_floors(asus);
> }
> }
> +
> + fan_curve_notify(asus);
> +
> return count;
> }
>
>
>
--
i.
prev parent reply other threads:[~2026-11-09 18:39 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-01 10:46 [PATCH 0/7] platform/x86: asus-wmi: expose the firmware fan floor tables Bartu Alev
2026-11-01 10:46 ` [PATCH 1/7] platform/x86: asus-wmi: dump buffer replies in the debugfs dsts file Bartu Alev
2026-11-01 10:51 ` sashiko-bot
2026-11-09 18:09 ` Ilpo Järvinen
2026-11-01 10:46 ` [PATCH 2/7] Documentation: ABI: document the ASUS custom fan curve attributes Bartu Alev
2026-11-01 10:50 ` sashiko-bot
2026-11-01 10:46 ` [PATCH 3/7] platform/x86: asus-wmi: define the fan floor table DEVIDs Bartu Alev
2026-11-01 10:49 ` sashiko-bot
2026-11-01 10:46 ` [PATCH 4/7] platform/x86: asus-wmi: read the firmware fan floor tables Bartu Alev
2026-11-01 11:02 ` sashiko-bot
2026-11-09 18:23 ` Ilpo Järvinen
2026-11-01 10:46 ` [PATCH 5/7] platform/x86: asus-wmi: reject short fan curve replies Bartu Alev
2026-11-01 10:55 ` sashiko-bot
2026-11-01 10:46 ` [PATCH 6/7] platform/x86: asus-wmi: expose the fan floor tables via hwmon Bartu Alev
2026-11-01 10:52 ` sashiko-bot
2026-11-09 18:34 ` Ilpo Järvinen
2026-11-01 10:46 ` [PATCH 7/7] platform/x86: asus-wmi: show the effective duty for enabled curves Bartu Alev
2026-11-01 11:00 ` sashiko-bot
2026-11-09 18:39 ` Ilpo Järvinen [this message]
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=9e4832e9-9bd1-85c0-8b4d-e1de98373690@linux.intel.com \
--to=ilpo.jarvinen@linux.intel.com \
--cc=bartualev@gmail.com \
--cc=corentin.chary@gmail.com \
--cc=denis.benato@linux.dev \
--cc=hansg@kernel.org \
--cc=linux-api@vger.kernel.org \
--cc=linux-hwmon@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@roeck-us.net \
--cc=luke@ljones.dev \
--cc=platform-driver-x86@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.