FAILED: patch "[PATCH] hwmon: (tmp108) Fix initial conversion delay and wait until ready" failed to apply to 6.12-stable tree
Subsystems (2)
Sasha Levin
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x 7cd60538073e465310c94b2a2f0ea8d2f03768ef
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '[email protected]' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'
Thanks,
Sasha
------------------ original commit in Linus's tree ------------------
From 7cd60538073e465310c94b2a2f0ea8d2f03768ef Mon Sep 17 00:00:00 2001
From: Guenter Roeck <[email protected]>
Date: Fri, 30 Oct 2026 20:02:08 -0700
Subject: [PATCH] hwmon: (tmp108) Fix initial conversion delay and wait until
ready
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In tmp108_common_probe(), the driver only adds the 30 ms conversion delay (TMP108_CONVERSION_TIME_MS) to ready_time if the sensor was previously in TMP108_MODE_SHUTDOWN. However, the TMP108 hardware defaults to continuous conversion mode (TMP108_MODE_CONTINUOUS) upon power-on reset, including immediately after enabling the vcc supply regulator during probe, while the temperature register retains its power-on reset value of 0x0000 (0°C) until the first conversion completes. Because the initial mode is not shutdown, the delay is bypassed and early reads via thermal zone registration or sysfs before the first conversion finishes return an uninitialized 0°C reading.
In addition, returning -EAGAIN from tmp108_read() while waiting for a conversion to complete after probe or resume can trigger an unnecessary tight retry loop in callers or fail initial reads.
Unconditionally set ready_time to TMP108_CONVERSION_TIME_MS ahead in tmp108_common_probe(), track ready_time as ktime_t, and wait for the remaining conversion time in tmp108_read() using usleep_range() instead of returning -EAGAIN.
--- drivers/hwmon/tmp108.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-)
drivers/hwmon/tmp108.c +11 -15
@@ -13,7 +13,7 @@#include <linux/i2c.h> #include <linux/i3c/device.h> #include <linux/init.h> -#include <linux/jiffies.h> +#include <linux/ktime.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/slab.h>
@@ -78,7 +78,7 @@struct tmp108 {struct regmap *regmap;u16 orig_config; -u64 ready_time; +ktime_t ready_time;const struct tmp108_params *params; };
@@ -121,6 +121,7 @@ static int tmp108_read(struct device *dev, enum hwmon_sensor_types type,struct tmp108 *tmp108 =dev_get_drvdata (dev);unsigned int regval;int err, hyst; +s64 delay;if (type == hwmon_chip) {if (attr == hwmon_chip_update_interval) {
@@ -137,12 +138,10 @@ static int tmp108_read(struct device *dev, enum hwmon_sensor_types type,switch (attr) {case hwmon_temp_input: -/* Is it too early to return a conversion ? */ -if (time_before64 (get_jiffies_64 (), tmp108->ready_time)) { -dev_dbg (dev,"%s: Conversion not ready yet..\n" , - __func__); -return -EAGAIN ; - } +/* Wait if it is too early to return a conversion */ + delay =ktime_us_delta (tmp108->ready_time,ktime_get ()); +if (delay >0 ) +usleep_range (delay, delay +1000 ); err =regmap_read (tmp108->regmap,TMP108_REG_TEMP , ®val);if (err <0 )return err;
@@ -477,11 +476,8 @@ static int tmp108_common_probe(struct device *dev, struct regmap *regmap, char *return err; } - tmp108->ready_time =get_jiffies_64 (); -if ((tmp108->orig_config &TMP108_CONF_MODE_MASK ) == -TMP108_MODE_SHUTDOWN ) - tmp108->ready_time += -msecs_to_jiffies (TMP108_CONVERSION_TIME_MS ); + tmp108->ready_time =ktime_add_ms (ktime_get (), +TMP108_CONVERSION_TIME_MS ); err =devm_add_action_or_reset (dev, tmp108_restore_config, tmp108);if (err) {
@@ -528,8 +524,8 @@ static int tmp108_resume(struct device *dev) err =regmap_update_bits (tmp108->regmap,TMP108_REG_CONF ,TMP108_CONF_MODE_MASK ,TMP108_MODE_CONTINUOUS ); - tmp108->ready_time =get_jiffies_64 () + -msecs_to_jiffies (TMP108_CONVERSION_TIME_MS ); + tmp108->ready_time =ktime_add_ms (ktime_get (), +TMP108_CONVERSION_TIME_MS );return err; }
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 1/3 hwmon: (tmp108) Add helper function tmp108_common_probe() to prepare I3C support
From: Frank Li <[email protected]>
[ Upstream commit 700f3250198d51093884254220a96777a922dd47 ]
Add help function tmp108_common_probe() to pave road to support i3c for P3T1085(NXP) chip.
Use dev_err_probe() to simplify the code.
Message-ID: <[email protected]>
Stable-dep-of: 7cd60538073e ("hwmon: (tmp108) Fix initial conversion delay and wait until ready")
--- drivers/hwmon/tmp108.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-)
drivers/hwmon/tmp108.c +21 -18
@@ -323,33 +323,19 @@ static const struct regmap_config tmp108_regmap_config = { .use_single_write = true, }; -static int tmp108_probe (struct i2c_client *client) +static int tmp108_common_probe (struct device *dev,struct regmap *regmap,char *name) { -struct device *dev = &client->dev;struct device *hwmon_dev;struct tmp108 *tmp108; -int err;u32 config; - -if (!i2c_check_functionality (client->adapter, -I2C_FUNC_SMBUS_WORD_DATA )) { -dev_err (dev, -"adapter doesn't support SMBus word transactions\n" ); -return -ENODEV ; - } +int err; tmp108 =devm_kzalloc (dev,sizeof (*tmp108),GFP_KERNEL );if (!tmp108)return -ENOMEM ;dev_set_drvdata (dev, tmp108); - - tmp108->regmap =devm_regmap_init_i2c (client, &tmp108_regmap_config); -if (IS_ERR (tmp108->regmap)) { - err =PTR_ERR (tmp108->regmap); -dev_err (dev,"regmap init failed: %d" , err); -return err; - } + tmp108->regmap = regmap; err =regmap_read (tmp108->regmap,TMP108_REG_CONF , &config);if (err <0 ) {
@@ -383,13 +369,30 @@ static int tmp108_probe(struct i2c_client *client)return err; } - hwmon_dev =devm_hwmon_device_register_with_info (dev, client->name, + hwmon_dev =devm_hwmon_device_register_with_info (dev, name, tmp108, &tmp108_chip_info,NULL );return PTR_ERR_OR_ZERO (hwmon_dev); } +static int tmp108_probe (struct i2c_client *client) +{ +struct device *dev = &client->dev; +struct regmap *regmap; + +if (!i2c_check_functionality (client->adapter, +I2C_FUNC_SMBUS_WORD_DATA )) +return dev_err_probe (dev, -ENODEV , +"adapter doesn't support SMBus word transactions\n" ); + + regmap =devm_regmap_init_i2c (client, &tmp108_regmap_config); +if (IS_ERR (regmap)) +return dev_err_probe (dev,PTR_ERR (regmap),"regmap init failed" ); + +return tmp108_common_probe (dev, regmap, client->name); +} +static int tmp108_suspend (struct device *dev) {struct tmp108 *tmp108 =dev_get_drvdata (dev);
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/3 i3c: master: replace ENOTSUPP with SUSV4-compliant EOPNOTSUPP
From: Wolfram Sang <[email protected]>
[ Upstream commit d10a4c323883c41cf1b652309e61c48bce248e35 ]
Replace non-standard ENOTSUPP with the SUSV4-defined error code EOPNOTSUPP to fix below checkpatch warning:
"ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP"
Stable-dep-of: 7cd60538073e ("hwmon: (tmp108) Fix initial conversion delay and wait until ready")
--- drivers/i3c/master.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
drivers/i3c/master.c +10 -10
@@ -844,14 +844,14 @@ static int i3c_master_send_ccc_cmd_locked(struct i3c_master_controller *master,return -EINVAL ;if (!master->ops->send_ccc_cmd) -return -ENOTSUPP ; +return -EOPNOTSUPP ;if ((cmd->id &I3C_CCC_DIRECT ) && (!cmd->dests || !cmd->ndests))return -EINVAL ;if (master->ops->supports_ccc_cmd && !master->ops->supports_ccc_cmd (master, cmd)) -return -ENOTSUPP ; +return -EOPNOTSUPP ; ret = master->ops->send_ccc_cmd (master, cmd);if (ret) {
@@ -1441,7 +1441,7 @@ static int i3c_master_retrieve_dev_info(struct i3c_dev_desc *dev)if (dev->info.bcr &I3C_BCR_HDR_CAP ) { ret =i3c_master_gethdrcap_locked (master, &dev->info); -if (ret && ret != -ENOTSUPP ) +if (ret && ret != -EOPNOTSUPP )return ret; }
@@ -2244,7 +2244,7 @@ of_i3c_master_add_i2c_boardinfo(struct i3c_master_controller *master,*/ if (boardinfo->base.flags &I2C_CLIENT_TEN ) {dev_err (dev,"I2C device with 10 bit address not supported." ); -return -ENOTSUPP ; +return -EOPNOTSUPP ; }/* LVR is encoded in reg[2]. */
@@ -2374,13 +2374,13 @@ static int i3c_master_i2c_adapter_xfer(struct i2c_adapter *adap,return -EINVAL ;if (!master->ops->i2c_xfers) -return -ENOTSUPP ; +return -EOPNOTSUPP ;/* Doing transfers to different devices is not supported. */ addr = xfers[0 ].addr;for (i =1 ; i < nxfers; i++) {if (addr != xfers[i].addr) -return -ENOTSUPP ; +return -EOPNOTSUPP ; }i3c_bus_normaluse_lock (&master->bus);
@@ -2801,7 +2801,7 @@ static int i3c_master_check_ops(const struct i3c_master_controller_ops *ops)* controller) * @ops: the master controller operations * @secondary: true if you are registering a secondary master. Will return -* -ENOTSUPP if set to true since secondary masters are not yet +* -EOPNOTSUPP if set to true since secondary masters are not yet * supported * * This function takes care of everything for you:
@@ -2828,7 +2828,7 @@ int i3c_master_register(struct i3c_master_controller *master,/* We do not support secondary masters yet. */ if (secondary) -return -ENOTSUPP ; +return -EOPNOTSUPP ; ret =i3c_master_check_ops (ops);if (ret)
@@ -2988,7 +2988,7 @@ int i3c_dev_do_priv_xfers_locked(struct i3c_dev_desc *dev,return -EINVAL ;if (!master->ops->priv_xfers) -return -ENOTSUPP ; +return -EOPNOTSUPP ;return master->ops->priv_xfers (dev, xfers, nxfers); }
@@ -3038,7 +3038,7 @@ int i3c_dev_request_ibi_locked(struct i3c_dev_desc *dev,int ret;if (!master->ops->request_ibi) -return -ENOTSUPP ; +return -EOPNOTSUPP ;if (dev->ibi)return -EBUSY ;
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/3 hwmon: (tmp108) Fix initial conversion delay and wait until ready
In reply to Sasha LevinFrom: Guenter Roeck <[email protected]>
[ Upstream commit 7cd60538073e465310c94b2a2f0ea8d2f03768ef ]
In tmp108_common_probe(), the driver only adds the 30 ms conversion delay (TMP108_CONVERSION_TIME_MS) to ready_time if the sensor was previously in TMP108_MODE_SHUTDOWN. However, the TMP108 hardware defaults to continuous conversion mode (TMP108_MODE_CONTINUOUS) upon power-on reset, including immediately after enabling the vcc supply regulator during probe, while the temperature register retains its power-on reset value of 0x0000 (0°C) until the first conversion completes. Because the initial mode is not shutdown, the delay is bypassed and early reads via thermal zone registration or sysfs before the first conversion finishes return an uninitialized 0°C reading.
In addition, returning -EAGAIN from tmp108_read() while waiting for a conversion to complete after probe or resume can trigger an unnecessary tight retry loop in callers or fail initial reads.
Unconditionally set ready_time to TMP108_CONVERSION_TIME_MS ahead in tmp108_common_probe(), track ready_time as ktime_t, and wait for the remaining conversion time in tmp108_read() using usleep_range() instead of returning -EAGAIN.
--- drivers/hwmon/tmp108.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-)
drivers/hwmon/tmp108.c +11 -15
@@ -14,7 +14,7 @@#include <linux/of.h> #include <linux/i2c.h> #include <linux/init.h> -#include <linux/jiffies.h> +#include <linux/ktime.h> #include <linux/regmap.h> #include <linux/slab.h>
@@ -73,7 +73,7 @@struct tmp108 {struct regmap *regmap;u16 orig_config; -u64 ready_time; +ktime_t ready_time; };/* convert 12-bit TMP108 register value to milliCelsius */
@@ -94,6 +94,7 @@ static int tmp108_read(struct device *dev, enum hwmon_sensor_types type,struct tmp108 *tmp108 =dev_get_drvdata (dev);unsigned int regval;int err, hyst; +s64 delay;if (type == hwmon_chip) {if (attr == hwmon_chip_update_interval) {
@@ -123,12 +124,10 @@ static int tmp108_read(struct device *dev, enum hwmon_sensor_types type,switch (attr) {case hwmon_temp_input: -/* Is it too early to return a conversion ? */ -if (time_before64 (get_jiffies_64 (), tmp108->ready_time)) { -dev_dbg (dev,"%s: Conversion not ready yet..\n" , - __func__); -return -EAGAIN ; - } +/* Wait if it is too early to return a conversion */ + delay =ktime_us_delta (tmp108->ready_time,ktime_get ()); +if (delay >0 ) +usleep_range (delay, delay +1000 ); err =regmap_read (tmp108->regmap,TMP108_REG_TEMP , ®val);if (err <0 )return err;
@@ -357,11 +356,8 @@ static int tmp108_common_probe(struct device *dev, struct regmap *regmap, char *return err; } - tmp108->ready_time =get_jiffies_64 (); -if ((tmp108->orig_config &TMP108_CONF_MODE_MASK ) == -TMP108_MODE_SHUTDOWN ) - tmp108->ready_time += -msecs_to_jiffies (TMP108_CONVERSION_TIME_MS ); + tmp108->ready_time =ktime_add_ms (ktime_get (), +TMP108_CONVERSION_TIME_MS ); err =devm_add_action_or_reset (dev, tmp108_restore_config, tmp108);if (err) {
@@ -408,8 +404,8 @@ static int tmp108_resume(struct device *dev) err =regmap_update_bits (tmp108->regmap,TMP108_REG_CONF ,TMP108_CONF_MODE_MASK ,TMP108_MODE_CONTINUOUS ); - tmp108->ready_time =get_jiffies_64 () + -msecs_to_jiffies (TMP108_CONVERSION_TIME_MS ); + tmp108->ready_time =ktime_add_ms (ktime_get (), +TMP108_CONVERSION_TIME_MS );return err; }
Signature · 1 line
2.53.0