Commit dca5480a authored by Stefan Wahren's avatar Stefan Wahren Committed by Krzysztof Kozlowski
Browse files

w1: w1_therm: fix locking behavior in convert_t

The commit 67b392f7 ("w1_therm: optimizing temperature read timings")
accidentially inverted the logic for lock handling of the bus mutex.

Before:
  pullup -> release lock before sleep
  no pullup -> release lock after sleep

After:
  pullup -> release lock after sleep
  no pullup -> release lock before sleep

This cause spurious measurements of 85 degree (powerup value) on the
Tarragon board with connected 1-w temperature sensor
(w1_therm.w1_strong_pull=0).

In the meantime a new feature for polling the conversion
completion has been integrated in these branches with
commit 021da53e ("w1: w1_therm: Add sysfs entries to control
conversion time and driver features"). But this feature isn't
available for parasite power mode, so handle this separately.

Link: https://lore.kernel.org/regressions/2023042645-attentive-amends-7b0b@gregkh/T/


Fixes: 67b392f7 ("w1_therm: optimizing temperature read timings")
Signed-off-by: default avatarStefan Wahren <stefan.wahren@i2se.com>
Link: https://lore.kernel.org/r/20230427112152.12313-1-stefan.wahren@i2se.com


Signed-off-by: default avatarKrzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
parent ac9a7868
Loading
Loading
Loading
Loading
+14 −17
Original line number Diff line number Diff line
@@ -1159,14 +1159,6 @@ static int convert_t(struct w1_slave *sl, struct therm_info *info)

			w1_write_8(dev_master, W1_CONVERT_TEMP);

			if (strong_pullup) { /*some device need pullup */
				sleep_rem = msleep_interruptible(t_conv);
				if (sleep_rem != 0) {
					ret = -EINTR;
					goto mt_unlock;
				}
				mutex_unlock(&dev_master->bus_mutex);
			} else { /*no device need pullup */
			if (SLAVE_FEATURES(sl) & W1_THERM_POLL_COMPLETION) {
				ret = w1_poll_completion(dev_master, W1_POLL_CONVERT_TEMP);
				if (ret) {
@@ -1174,8 +1166,14 @@ static int convert_t(struct w1_slave *sl, struct therm_info *info)
					goto mt_unlock;
				}
				mutex_unlock(&dev_master->bus_mutex);
				} else {
					/* Fixed delay */
			} else if (!strong_pullup) { /*no device need pullup */
				sleep_rem = msleep_interruptible(t_conv);
				if (sleep_rem != 0) {
					ret = -EINTR;
					goto mt_unlock;
				}
				mutex_unlock(&dev_master->bus_mutex);
			} else { /*some device need pullup */
				mutex_unlock(&dev_master->bus_mutex);
				sleep_rem = msleep_interruptible(t_conv);
				if (sleep_rem != 0) {
@@ -1183,7 +1181,6 @@ static int convert_t(struct w1_slave *sl, struct therm_info *info)
					goto dec_refcnt;
				}
			}
			}
			ret = read_scratchpad(sl, info);

			/* If enabled, check for conversion success */