From 991f9fa90360b64e8b79688d8ab0f034983a959d Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Sun, 24 Jul 2016 17:05:32 -0700 Subject: hwmon: (sht3x) set initial jiffies to last_update Handling the wraparound requires the data->last_update to be set to an initial jiffies value. Otherwise on 32-bit systems you will not be able to request a reading till the 5 minute jiffies rollover happens. Cc: Guenter Roeck Cc: David Frey Signed-off-by: Matt Ranostay Reviewed-by: Jean Delvare Fixes: 7c84f7f80d6fc ("hwmon: add support for Sensirion SHT3x sensors") Signed-off-by: Guenter Roeck --- drivers/hwmon/sht3x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/sht3x.c b/drivers/hwmon/sht3x.c index b73a48832732..6ea99cd6ae79 100644 --- a/drivers/hwmon/sht3x.c +++ b/drivers/hwmon/sht3x.c @@ -720,7 +720,7 @@ static int sht3x_probe(struct i2c_client *client, data->setup.blocking_io = false; data->setup.high_precision = true; data->mode = 0; - data->last_update = 0; + data->last_update = jiffies - msecs_to_jiffies(3000); data->client = client; crc8_populate_msb(sht3x_crc8_table, SHT3X_CRC8_POLYNOMIAL); -- cgit v1.2.3 From be9d6374a76ffbeda783a5bdcb00e219c7bda2d0 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 25 Jul 2016 14:47:18 -0700 Subject: hwmon: (lm90) Add missing assignment Coverity reports the following error. >>> CID 1364474: Error handling issues (CHECKED_RETURN) >>> Calling "lm90_read_reg" without checking return value (as is done >>> elsewhere 28 out of 29 times). 532 lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH); 533 if (val < 0) 534 return val; Fixes: 10bfef47bd259 ("hwmon: (lm90) Read limit registers only once") Reviewed-by: Jean Delvare Signed-off-by: Guenter Roeck --- drivers/hwmon/lm90.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index f51e758ba529..7b3eedf76c62 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -529,7 +529,7 @@ static int lm90_update_limits(struct device *dev) return val; data->temp_hyst = val; - lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH); + val = lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH); if (val < 0) return val; data->temp11[REMOTE_LOW] = val << 8; -- cgit v1.2.3 From c5fcf01bcfceb245da575cc5bfa4391642649f2d Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 25 Jul 2016 14:53:23 -0700 Subject: hwmon: (lm90) Improve error handling Replace devm_add_action() with devm_add_action_or_reset(), and check its return value. Reviewed-by: Jean Delvare Signed-off-by: Guenter Roeck --- drivers/hwmon/lm90.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 7b3eedf76c62..fa15f7238a28 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -1551,9 +1551,7 @@ static int lm90_init_client(struct i2c_client *client, struct lm90_data *data) if (config != data->config_orig) /* Only write if changed */ i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); - devm_add_action(&client->dev, lm90_restore_conf, data); - - return 0; + return devm_add_action_or_reset(&client->dev, lm90_restore_conf, data); } static bool lm90_is_tripped(struct i2c_client *client, u16 *status) @@ -1640,7 +1638,9 @@ static int lm90_probe(struct i2c_client *client, return err; } - devm_add_action(dev, lm90_regulator_disable, regulator); + err = devm_add_action_or_reset(dev, lm90_regulator_disable, regulator); + if (err) + return err; data = devm_kzalloc(dev, sizeof(struct lm90_data), GFP_KERNEL); if (!data) @@ -1696,7 +1696,9 @@ static int lm90_probe(struct i2c_client *client, err = device_create_file(dev, &dev_attr_pec); if (err) return err; - devm_add_action(dev, lm90_remove_pec, dev); + err = devm_add_action_or_reset(dev, lm90_remove_pec, dev); + if (err) + return err; } hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, -- cgit v1.2.3 From 90e2b545ce78516e727ba641e9f2b0703a17da1a Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 25 Jul 2016 14:56:00 -0700 Subject: hwmon: (lm75) Improve error handling Use devm_add_action_or_reset() instead of devm_add_action(), and check its return value. Signed-off-by: Guenter Roeck --- drivers/hwmon/lm75.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index 547a9c87c68c..92f9d4bbf597 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -220,7 +220,7 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) struct device *dev = &client->dev; struct device *hwmon_dev; struct lm75_data *data; - int status; + int status, err; u8 set_mask, clr_mask; int new; enum lm75_type kind = id->driver_data; @@ -331,7 +331,9 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) if (status != new) i2c_smbus_write_byte_data(client, LM75_REG_CONF, new); - devm_add_action(dev, lm75_remove, data); + err = devm_add_action_or_reset(dev, lm75_remove, data); + if (err) + return err; dev_dbg(dev, "Config %02x\n", new); -- cgit v1.2.3 From 1aa4f0289fd5554a9cd58e5b47a361b14256ea90 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 25 Jul 2016 14:57:47 -0700 Subject: hwmon: (tmp102) Improve error handling Use devm_add_action_or_reset() instead of devm_add_action(), and check its return code. Signed-off-by: Guenter Roeck --- drivers/hwmon/tmp102.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index a942a2574a4d..8479ac5eb853 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c @@ -227,7 +227,9 @@ static int tmp102_probe(struct i2c_client *client, tmp102->config_orig = regval; - devm_add_action(dev, tmp102_restore_config, tmp102); + err = devm_add_action_or_reset(dev, tmp102_restore_config, tmp102); + if (err) + return err; regval &= ~TMP102_CONFIG_CLEAR; regval |= TMP102_CONFIG_SET; -- cgit v1.2.3 From 4c8702b3cd43322ca97fdc7f647e273a7388a0c6 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 25 Jul 2016 15:01:28 -0700 Subject: hwmon: (ftsteutates) Fix potential memory access error Using set_bit() to set a bit in an integer is not a good idea, since the function expects an unsigned long as argument, which can be 64 bit wide. Coverity reports this problem as >>> CID 1364488: Memory - illegal accesses (INCOMPATIBLE_CAST) >>> Pointer "&ret" points to an object whose effective type is "int" >>> (32 bits, signed) but is dereferenced as a wider "unsigned +long" (64 bits, unsigned). This may lead to memory corruption. 245 set_bit(1, (unsigned long *)&ret); Just use BIT instead. Cc: Thilo Cestonaro Fixes: 08426eda58e0 ("hwmon: Add driver for FTS BMC chip "Teutates"") Signed-off-by: Guenter Roeck --- drivers/hwmon/ftsteutates.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/ftsteutates.c b/drivers/hwmon/ftsteutates.c index 2b2ff67026be..48633e541dc3 100644 --- a/drivers/hwmon/ftsteutates.c +++ b/drivers/hwmon/ftsteutates.c @@ -242,7 +242,7 @@ static int fts_wd_set_resolution(struct fts_data *data, } if (resolution == seconds) - set_bit(1, (unsigned long *)&ret); + ret |= BIT(1); else ret &= ~BIT(1); -- cgit v1.2.3 From 5d17d3b4bbf3becb89fd48b74340a50a39736f6d Mon Sep 17 00:00:00 2001 From: Quentin Schulz Date: Tue, 26 Jul 2016 09:47:09 +0200 Subject: hwmon: (iio_hwmon) fix memory leak in name attribute The "name" variable's memory is now freed when the device is destructed thanks to devm function. Signed-off-by: Quentin Schulz Reported-by: Guenter Roeck Fixes: e0f8a24e0edfd ("staging:iio::hwmon interface client driver.") Fixes: 61bb53bcbdd86 ("hwmon: (iio_hwmon) Add support for humidity sensors") Signed-off-by: Guenter Roeck --- drivers/hwmon/iio_hwmon.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/iio_hwmon.c b/drivers/hwmon/iio_hwmon.c index b550ba5fa58a..89449871bca7 100644 --- a/drivers/hwmon/iio_hwmon.c +++ b/drivers/hwmon/iio_hwmon.c @@ -110,24 +110,24 @@ static int iio_hwmon_probe(struct platform_device *pdev) switch (type) { case IIO_VOLTAGE: - a->dev_attr.attr.name = kasprintf(GFP_KERNEL, - "in%d_input", - in_i++); + a->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, + "in%d_input", + in_i++); break; case IIO_TEMP: - a->dev_attr.attr.name = kasprintf(GFP_KERNEL, - "temp%d_input", - temp_i++); + a->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, + "temp%d_input", + temp_i++); break; case IIO_CURRENT: - a->dev_attr.attr.name = kasprintf(GFP_KERNEL, - "curr%d_input", - curr_i++); + a->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, + "curr%d_input", + curr_i++); break; case IIO_HUMIDITYRELATIVE: - a->dev_attr.attr.name = kasprintf(GFP_KERNEL, - "humidity%d_input", - humidity_i++); + a->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, + "humidity%d_input", + humidity_i++); break; default: ret = -EINVAL; -- cgit v1.2.3 From 601807bbb7b422012492611b283bdf3647d3742c Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Mon, 25 Jul 2016 11:12:05 +0200 Subject: hwmon: (adt7411) set sane values for CFG1 and CFG3 According to the datasheet we have to set some bits as 0 and others as 1. Make sure we do this for CFG1 and CFG3. Signed-off-by: Michael Walle Signed-off-by: Guenter Roeck --- drivers/hwmon/adt7411.c | 48 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c index a7f886961830..fc1e65a263a4 100644 --- a/drivers/hwmon/adt7411.c +++ b/drivers/hwmon/adt7411.c @@ -30,6 +30,7 @@ #define ADT7411_REG_CFG1 0x18 #define ADT7411_CFG1_START_MONITOR (1 << 0) +#define ADT7411_CFG1_RESERVED_BIT1 (1 << 1) #define ADT7411_CFG1_RESERVED_BIT3 (1 << 3) #define ADT7411_REG_CFG2 0x19 @@ -37,6 +38,9 @@ #define ADT7411_REG_CFG3 0x1a #define ADT7411_CFG3_ADC_CLK_225 (1 << 0) +#define ADT7411_CFG3_RESERVED_BIT1 (1 << 1) +#define ADT7411_CFG3_RESERVED_BIT2 (1 << 2) +#define ADT7411_CFG3_RESERVED_BIT3 (1 << 3) #define ADT7411_CFG3_REF_VDD (1 << 4) #define ADT7411_REG_DEVICE_ID 0x4d @@ -280,6 +284,45 @@ static int adt7411_detect(struct i2c_client *client, return 0; } +static int adt7411_init_device(struct adt7411_data *data) +{ + int ret; + u8 val; + + ret = i2c_smbus_read_byte_data(data->client, ADT7411_REG_CFG3); + if (ret < 0) + return ret; + + /* + * We must only write zero to bit 1 and bit 2 and only one to bit 3 + * according to the datasheet. + */ + val = ret; + val &= ~(ADT7411_CFG3_RESERVED_BIT1 | ADT7411_CFG3_RESERVED_BIT2); + val |= ADT7411_CFG3_RESERVED_BIT3; + + ret = i2c_smbus_write_byte_data(data->client, ADT7411_REG_CFG3, val); + if (ret < 0) + return ret; + + ret = i2c_smbus_read_byte_data(data->client, ADT7411_REG_CFG1); + if (ret < 0) + return ret; + + /* + * We must only write zero to bit 1 and only one to bit 3 according to + * the datasheet. + */ + val = ret; + val &= ~ADT7411_CFG1_RESERVED_BIT1; + val |= ADT7411_CFG1_RESERVED_BIT3; + + /* enable monitoring */ + val |= ADT7411_CFG1_START_MONITOR; + + return i2c_smbus_write_byte_data(data->client, ADT7411_REG_CFG1, val); +} + static int adt7411_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -297,10 +340,7 @@ static int adt7411_probe(struct i2c_client *client, mutex_init(&data->device_lock); mutex_init(&data->update_lock); - /* According to the datasheet, we must only write 1 to bit 3 */ - ret = adt7411_modify_bit(client, ADT7411_REG_CFG1, - ADT7411_CFG1_RESERVED_BIT3 - | ADT7411_CFG1_START_MONITOR, 1); + ret = adt7411_init_device(data); if (ret < 0) return ret; -- cgit v1.2.3