* [PATCH] hwmon: (nct6683) Restore manual fan control after resume
@ 2026-11-09 16:33 Tomasz Bojanowski
2026-11-09 17:13 ` Guenter Roeck
2026-11-09 17:13 ` Guenter Roeck
0 siblings, 2 replies; 3+ messages in thread
From: Tomasz Bojanowski @ 2026-11-09 16:33 UTC (permalink / raw)
To: Guenter Roeck; +Cc: Hamza Mahfooz, linux-hwmon, linux-kernel
On MSI boards with NCT6687D-R, the BIOS restores automatic fan control
on resume from S3. The manual mode and duty cycle set through
pwmN_enable and pwmN are lost, and pwmN_enable reports 2.
Remember the channels switched to manual mode through sysfs and their
duty cycle, and restore them on resume if the EC switched them back to
automatic mode. Other channels are not touched.
Tested on an MSI MAG B850M MORTAR WIFI (MS-7E61): with pwm16_enable set
to 1 and pwm16 to 153, pwm16_enable reads 2 after resume from S3 without
this patch. With this patch it stays 1 and the fan returns to the manual
duty cycle.
Fixes: 5410a1257e26 ("hwmon: (nct6683) Add fan control support for MSI boards with NCT6687D-R")
Signed-off-by: Tomasz Bojanowski <tomasz@bojanowski.me>
---
I used an AI assistant (Claude Code) during development. I reviewed all
of the changes, tested them on the hardware described above, and take
responsibility for them.
This addresses your comment on suspend/resume in [1]: on the MS-7E61,
the BIOS restores automatic fan control on resume from S3. The patch
does not depend on the fan curve patch; both apply in either order.
[1] https://lore.kernel.org/linux-hwmon/487b2f39-7e22-46db-9eaf-9b1dd9b31d31@roeck-us.net/
drivers/hwmon/nct6683.c | 39 +++++++++++++++++++++++++++++++++++----
1 file changed, 35 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/nct6683.c b/drivers/hwmon/nct6683.c
index 65e374c64fb8..d88b981efb1f 100644
--- a/drivers/hwmon/nct6683.c
+++ b/drivers/hwmon/nct6683.c
@@ -365,6 +365,10 @@ struct nct6683_data {
/* Remember extra register values over suspend/resume */
u8 hwm_cfg;
#endif
+
+ /* Manual fan control set through sysfs, restored on resume */
+ u16 pwm_manual; /* channels set to manual mode */
+ u8 pwm_cmd[NCT6683_NUM_REG_FAN]; /* their duty cycle */
};
struct nct6683_sio_data {
@@ -1052,8 +1056,11 @@ static int nct6683_set_pwm(struct nct6683_data *data, int ch, u8 val)
err = nct6683_fan_ctrl_update(data, ch, true, val);
else
err = -EBUSY;
- if (!err)
+ if (!err) {
data->pwm[ch] = val;
+ data->pwm_manual |= BIT(ch);
+ data->pwm_cmd[ch] = val;
+ }
mutex_unlock(&data->update_lock);
return err;
@@ -1130,10 +1137,17 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
manual = val == 1;
mutex_lock(&data->update_lock);
- if (nct6683_pwm_manual(data, index) != manual) {
- /* Keep the current duty cycle when switching to manual mode */
- cmd = manual ? nct6683_read(data, nct6683_pwm_reg(index)) : -1;
+ /* Keep the current duty cycle when switching to manual mode */
+ cmd = manual ? nct6683_read(data, nct6683_pwm_reg(index)) : -1;
+ if (nct6683_pwm_manual(data, index) != manual)
err = nct6683_fan_ctrl_update(data, index, manual, cmd);
+ if (!err) {
+ if (manual) {
+ data->pwm_manual |= BIT(index);
+ data->pwm_cmd[index] = cmd;
+ } else {
+ data->pwm_manual &= ~BIT(index);
+ }
}
mutex_unlock(&data->update_lock);
@@ -1549,11 +1563,28 @@ static int nct6683_suspend(struct device *dev)
static int nct6683_resume(struct device *dev)
{
struct nct6683_data *data = dev_get_drvdata(dev);
+ unsigned long manual;
+ int ch, err;
mutex_lock(&data->update_lock);
nct6683_write(data, NCT6683_HWM_CFG, data->hwm_cfg);
+ /* The BIOS may switch the fans back to automatic mode */
+ manual = data->pwm_manual;
+ for_each_set_bit(ch, &manual, NCT6683_NUM_REG_FAN) {
+ if (nct6683_pwm_manual(data, ch))
+ continue;
+ err = nct6683_fan_ctrl_update(data, ch, true, data->pwm_cmd[ch]);
+ if (err) {
+ dev_warn(dev, "Failed to restore manual mode of pwm%d: %d\n",
+ ch + 1, err);
+ /* The EC does not respond, skip the remaining channels */
+ if (err == -ETIMEDOUT)
+ break;
+ }
+ }
+
/* Force re-reading all values */
data->valid = false;
mutex_unlock(&data->update_lock);
base-commit: ec921ef8d81acf0cc41b3f3b6db54698e9a2917f
--
2.56.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] hwmon: (nct6683) Restore manual fan control after resume
2026-11-09 16:33 [PATCH] hwmon: (nct6683) Restore manual fan control after resume Tomasz Bojanowski
@ 2026-11-09 17:13 ` Guenter Roeck
2026-11-09 17:13 ` Guenter Roeck
1 sibling, 0 replies; 3+ messages in thread
From: Guenter Roeck @ 2026-11-09 17:13 UTC (permalink / raw)
To: Tomasz Bojanowski; +Cc: Hamza Mahfooz, linux-hwmon, linux-kernel
On Mon, Nov 09, 2026 at 05:33:28PM +0100, Tomasz Bojanowski wrote:
> On MSI boards with NCT6687D-R, the BIOS restores automatic fan control
> on resume from S3. The manual mode and duty cycle set through
> pwmN_enable and pwmN are lost, and pwmN_enable reports 2.
>
> Remember the channels switched to manual mode through sysfs and their
> duty cycle, and restore them on resume if the EC switched them back to
> automatic mode. Other channels are not touched.
>
> Tested on an MSI MAG B850M MORTAR WIFI (MS-7E61): with pwm16_enable set
> to 1 and pwm16 to 153, pwm16_enable reads 2 after resume from S3 without
> this patch. With this patch it stays 1 and the fan returns to the manual
> duty cycle.
>
> Fixes: 5410a1257e26 ("hwmon: (nct6683) Add fan control support for MSI boards with NCT6687D-R")
> Signed-off-by: Tomasz Bojanowski <tomasz@bojanowski.me>
Applied.
Thanks,
Guenter
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] hwmon: (nct6683) Restore manual fan control after resume
2026-11-09 16:33 [PATCH] hwmon: (nct6683) Restore manual fan control after resume Tomasz Bojanowski
2026-11-09 17:13 ` Guenter Roeck
@ 2026-11-09 17:13 ` Guenter Roeck
1 sibling, 0 replies; 3+ messages in thread
From: Guenter Roeck @ 2026-11-09 17:13 UTC (permalink / raw)
To: Tomasz Bojanowski; +Cc: Hamza Mahfooz, linux-hwmon, linux-kernel
On Mon, Nov 09, 2026 at 05:33:28PM +0100, Tomasz Bojanowski wrote:
> On MSI boards with NCT6687D-R, the BIOS restores automatic fan control
> on resume from S3. The manual mode and duty cycle set through
> pwmN_enable and pwmN are lost, and pwmN_enable reports 2.
>
> Remember the channels switched to manual mode through sysfs and their
> duty cycle, and restore them on resume if the EC switched them back to
> automatic mode. Other channels are not touched.
>
> Tested on an MSI MAG B850M MORTAR WIFI (MS-7E61): with pwm16_enable set
> to 1 and pwm16 to 153, pwm16_enable reads 2 after resume from S3 without
> this patch. With this patch it stays 1 and the fan returns to the manual
> duty cycle.
>
> Fixes: 5410a1257e26 ("hwmon: (nct6683) Add fan control support for MSI boards with NCT6687D-R")
> Signed-off-by: Tomasz Bojanowski <tomasz@bojanowski.me>
Applied.
Thanks,
Guenter
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-11-09 17:13 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-09 16:33 [PATCH] hwmon: (nct6683) Restore manual fan control after resume Tomasz Bojanowski
2026-11-09 17:13 ` Guenter Roeck
2026-11-09 17:13 ` Guenter Roeck
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®