From: Florin Leotescu florin.leotescu@nxp.com
[ Upstream commit 0429415a084a15466e87d504e8c2a502488184a5 ]
Prevent the PWM value from being set to minimum when thermal zone temperature exceeds any trip point during driver probe. Otherwise, the PWM fan speed will remains at minimum speed and not respond to temperature changes.
Signed-off-by: Florin Leotescu florin.leotescu@nxp.com Link: https://lore.kernel.org/r/20250603113125.3175103-5-florin.leotescu@oss.nxp.c... Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
**Backport Status: YES**
This commit should be backported to stable kernel trees for the following reasons:
## Bug Fix Analysis
This commit fixes a **critical functional bug** where fan speeds remain stuck at minimum when the system temperature is already elevated during driver probe. The specific issue addressed:
1. **User-Impacting Bug**: When the thermal zone temperature exceeds trip points during driver initialization, the PWM fan controller incorrectly sets fans to minimum speed and they become unresponsive to temperature changes. This can lead to: - System overheating - Hardware damage from inadequate cooling - Thermal throttling affecting performance - Potential system crashes or shutdowns
2. **Clear Root Cause**: The bug occurs because the driver unconditionally initializes PWM to `pwm_min` without checking the current thermal state (`cur_state`). The fix properly checks if `cur_state > 0` and calculates appropriate PWM duty cycle using `EMC2305_PWM_STATE2DUTY()`.
3. **Small and Contained Fix**: The patch is minimal (8 lines added, 2 modified) and confined to a single function `emc2305_set_single_tz()`. The changes are: - Add a check for `cur_state > 0` - Calculate proper PWM value if temperature is elevated - Update state tracking to use calculated PWM instead of hardcoded minimum
4. **No Architectural Changes**: This is a straightforward initialization fix that doesn't change any interfaces, data structures, or driver architecture.
5. **Low Regression Risk**: The fix only affects initialization behavior when thermal state indicates elevated temperatures. Normal operation when temperature is below trip points remains unchanged.
6. **Critical for Thermal Management**: The emc2305 driver was added in kernel 5.20 (commit 0d8400c5a2ce from Aug 2022), making this a relatively recent driver where users encountering high-temperature boot scenarios would experience complete fan control failure.
The commit follows stable tree rules perfectly - it's a clear bugfix for a user-visible problem with minimal changes and low risk of introducing new issues. Systems booting in hot environments or after warm reboots would be particularly affected by this bug, making the fix important for operational reliability.
drivers/hwmon/emc2305.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/emc2305.c b/drivers/hwmon/emc2305.c index 234c54956a4b..1dbe3f26467d 100644 --- a/drivers/hwmon/emc2305.c +++ b/drivers/hwmon/emc2305.c @@ -299,6 +299,12 @@ static int emc2305_set_single_tz(struct device *dev, int idx) dev_err(dev, "Failed to register cooling device %s\n", emc2305_fan_name[idx]); return PTR_ERR(data->cdev_data[cdev_idx].cdev); } + + if (data->cdev_data[cdev_idx].cur_state > 0) + /* Update pwm when temperature is above trips */ + pwm = EMC2305_PWM_STATE2DUTY(data->cdev_data[cdev_idx].cur_state, + data->max_state, EMC2305_FAN_MAX); + /* Set minimal PWM speed. */ if (data->pwm_separate) { ret = emc2305_set_pwm(dev, pwm, cdev_idx); @@ -312,10 +318,10 @@ static int emc2305_set_single_tz(struct device *dev, int idx) } } data->cdev_data[cdev_idx].cur_state = - EMC2305_PWM_DUTY2STATE(data->pwm_min[cdev_idx], data->max_state, + EMC2305_PWM_DUTY2STATE(pwm, data->max_state, EMC2305_FAN_MAX); data->cdev_data[cdev_idx].last_hwmon_state = - EMC2305_PWM_DUTY2STATE(data->pwm_min[cdev_idx], data->max_state, + EMC2305_PWM_DUTY2STATE(pwm, data->max_state, EMC2305_FAN_MAX); return 0; }