From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C530D3290C7; Fri, 7 Aug 2026 14:45:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786113956; cv=none; b=Q6UD2PaEuAMRGiYcjclEJP+HN4hCzKUTAkfAi1ScKYxAxzcdb56SbWp4k2DMNYOaw3eWAXZQPn7xs0ZJmER57kyVFYwDLYWMjE1h0tqnMkb8Jag0c7bSDRBmJyYD6Qqj/GwIW7xLiGIGDuomwU6YemlWZ5nY7PAf5lQ3Nj9Yz70= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786113956; c=relaxed/simple; bh=oIJN1hK/gbDxBsEFpslV+361GoelwZnkwrbpFPjfJ9s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=i9OJhyNw12/zK1AvXpfPcDnNvjRv4qrhMszK3Y+aYbFzx9rZRYJOJ1uFMKYedGlRSSTo8f59z9cJzzabmy0lk/YA5Kkb6x6oFCxnAUnp0Y1LpQq6EWwRUCj3qw58pYiwmZr9ATYYuCp8JXfJhUJvMs1UFS5t8LOBEupCpVh4nhU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=YGEBj/Bk; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="YGEBj/Bk" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E39D91F000E9; Fri, 7 Aug 2026 14:45:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1786113954; bh=u0IA7HR6+0oLXTeDcTc/fTMvUVu7Pb2lbaq5+55Mj28=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=YGEBj/Bk0ipbWd2bOQ+eFTS5q6VIfdaJNPhj9eUHWu6AAYFGAzmtokfMOrBIy5kyT w+ltolFSJ9r2V6RKuahf9mA8NG9Y64Fv5+ll1I1oTA3RVpjSzgZuKj0gBX5XqK6aO4 /AGBOdqL/6xWsHIIYWIioq4hfPaToZjmm8dv53Is= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, sashiko-bot@kernel.org, Luiz Angelo Daros de Luca , Guenter Roeck , Sasha Levin Subject: [PATCH 6.12 076/337] hwmon: (adt7470) Fix fans stuck in manual mode on I2C errors Date: Fri, 7 Aug 2026 16:34:39 +0200 Message-ID: <20260807143420.161164950@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260807143418.516897842@linuxfoundation.org> References: <20260807143418.516897842@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Luiz Angelo Daros de Luca [ Upstream commit 625a2c02a1c04571232a746fe188b4d9a8d63edd ] During adt7470_read_temperatures(), the driver temporarily switches the PWM channels to manual mode, performs the temperature collection, and then restores the original configuration registers. However, if an I2C transaction fails at any point after entering manual mode, the function aborts and returns immediately. This leaves the configuration registers un-restored, permanently trapping the fans in manual mode. Introduce a recovery path to ensure that the original PWM configuration registers are always restored, even when intermediate I2C operations fail. Reported-by: sashiko-bot@kernel.org Closes: https://lore.kernel.org/r/20260716213252.EACA71F000E9@smtp.kernel.org Fixes: ef67959c4253 ("hwmon: (adt7470) Convert to use regmap") Signed-off-by: Luiz Angelo Daros de Luca Link: https://lore.kernel.org/r/20260727-adt7470_fixes-v2-1-598e38a46ba6@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/adt7470.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index dbee6926fa055..ef8f411df61be 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c @@ -205,11 +205,12 @@ static inline int adt7470_write_word_data(struct adt7470_data *data, unsigned in /* Probe for temperature sensors. Assumes lock is held */ static int adt7470_read_temperatures(struct adt7470_data *data) { - unsigned long res; + struct device *dev = regmap_get_device(data->regmap); + u8 pwm[ADT7470_FAN_COUNT]; unsigned int pwm_cfg[2]; - int err; + unsigned long res; + int err, err2; int i; - u8 pwm[ADT7470_FAN_COUNT]; /* save pwm[1-4] config register */ err = regmap_read(data->regmap, ADT7470_REG_PWM_CFG(0), &pwm_cfg[0]); @@ -233,19 +234,19 @@ static int adt7470_read_temperatures(struct adt7470_data *data) err = regmap_update_bits(data->regmap, ADT7470_REG_PWM_CFG(2), ADT7470_PWM_AUTO_MASK, 0); if (err < 0) - return err; + goto out_restore; /* write pwm control to whatever it was */ err = regmap_bulk_write(data->regmap, ADT7470_REG_PWM(0), &pwm[0], ADT7470_PWM_COUNT); if (err < 0) - return err; + goto out_restore; /* start reading temperature sensors */ err = regmap_update_bits(data->regmap, ADT7470_REG_CFG, ADT7470_T05_STB_MASK, ADT7470_T05_STB_MASK); if (err < 0) - return err; + goto out_restore; /* Delay is 200ms * number of temp sensors. */ res = msleep_interruptible((data->num_temp_sensors >= 0 ? @@ -256,13 +257,30 @@ static int adt7470_read_temperatures(struct adt7470_data *data) err = regmap_update_bits(data->regmap, ADT7470_REG_CFG, ADT7470_T05_STB_MASK, 0); if (err < 0) - return err; + goto out_restore; +out_restore: /* restore pwm[1-4] config registers */ - err = regmap_write(data->regmap, ADT7470_REG_PWM_CFG(0), pwm_cfg[0]); - if (err < 0) - return err; - err = regmap_write(data->regmap, ADT7470_REG_PWM_CFG(2), pwm_cfg[1]); + err2 = regmap_write(data->regmap, ADT7470_REG_PWM_CFG(0), pwm_cfg[0]); + if (err2 < 0) { + dev_warn_ratelimited(dev, + "failed to restore PWM{1,2} config (%d)\n", + err2); + + if (!err) + err = err2; + } + + err2 = regmap_write(data->regmap, ADT7470_REG_PWM_CFG(2), pwm_cfg[1]); + if (err2 < 0) { + dev_warn_ratelimited(dev, + "failed to restore PWM{3,4} config (%d)\n", + err2); + + if (!err) + err = err2; + } + if (err < 0) return err; -- 2.53.0