* [PATCH 1/5] iio: humidity: hts221: report available values via read_avail()
2026-08-08 9:00 [PATCH 0/5] iio: humidity: hts221: update probe and logging implementations Adi Nata
@ 2026-08-08 9:00 ` Adi Nata
2026-08-10 0:09 ` Jonathan Cameron
2026-08-08 9:00 ` [PATCH 2/5] iio: humidity: hts221: Add a blank line after variable declarations Adi Nata
` (3 subsequent siblings)
4 siblings, 1 reply; 7+ messages in thread
From: Adi Nata @ 2026-08-08 9:00 UTC (permalink / raw)
To: lorenzo, jic23, dlechner, nuno.sa, andy, linux-iio, linux-kernel
Cc: linux-kernel-mentees, Adi Nata
Replace the custom oversampling_ratio_available sysfs attributes with
the standard IIO read_avail() callback. This lets the IIO core create
and format *_available attributes and exposes the lists to
in-kernel consumers.
Signed-off-by: Adi Nata <adinata.softwareengineer@gmail.com>
---
drivers/iio/humidity/hts221_core.c | 106 +++++++++++------------------
1 file changed, 40 insertions(+), 66 deletions(-)
diff --git a/drivers/iio/humidity/hts221_core.c b/drivers/iio/humidity/hts221_core.c
index bfeb0a60d3af..76a391f421f5 100644
--- a/drivers/iio/humidity/hts221_core.c
+++ b/drivers/iio/humidity/hts221_core.c
@@ -10,7 +10,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
-#include <linux/iio/sysfs.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/regmap.h>
@@ -49,7 +48,7 @@ struct hts221_odr {
struct hts221_avg {
u8 addr;
u8 mask;
- u16 avg_avl[HTS221_AVG_DEPTH];
+ int avg_avl[HTS221_AVG_DEPTH];
};
static const struct hts221_odr hts221_odr_table[] = {
@@ -58,6 +57,8 @@ static const struct hts221_odr hts221_odr_table[] = {
{ 13, 0x03 }, /* 12.5Hz */
};
+static const int hts221_odr_avail[] = { 1, 7, 13 };
+
static const struct hts221_avg hts221_avg_list[] = {
{
.addr = 0x10,
@@ -97,7 +98,11 @@ static const struct iio_chan_spec hts221_channels[] = {
BIT(IIO_CHAN_INFO_OFFSET) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
+ .info_mask_separate_available =
+ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+ .info_mask_shared_by_all_available =
+ BIT(IIO_CHAN_INFO_SAMP_FREQ),
.scan_index = 0,
.scan_type = {
.sign = 's',
@@ -113,7 +118,11 @@ static const struct iio_chan_spec hts221_channels[] = {
BIT(IIO_CHAN_INFO_OFFSET) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
+ .info_mask_separate_available =
+ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+ .info_mask_shared_by_all_available =
+ BIT(IIO_CHAN_INFO_SAMP_FREQ),
.scan_index = 1,
.scan_type = {
.sign = 's',
@@ -192,53 +201,35 @@ static int hts221_update_avg(struct hts221_hw *hw,
return 0;
}
-static ssize_t hts221_sysfs_sampling_freq(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- int i;
- ssize_t len = 0;
-
- for (i = 0; i < ARRAY_SIZE(hts221_odr_table); i++)
- len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
- hts221_odr_table[i].hz);
- buf[len - 1] = '\n';
-
- return len;
-}
-
-static ssize_t
-hts221_sysfs_rh_oversampling_avail(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- const struct hts221_avg *avg = &hts221_avg_list[HTS221_SENSOR_H];
- ssize_t len = 0;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(avg->avg_avl); i++)
- len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
- avg->avg_avl[i]);
- buf[len - 1] = '\n';
-
- return len;
-}
-
-static ssize_t
-hts221_sysfs_temp_oversampling_avail(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static int hts221_read_avail(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ const int **vals, int *type, int *length,
+ long mask)
{
- const struct hts221_avg *avg = &hts221_avg_list[HTS221_SENSOR_T];
- ssize_t len = 0;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(avg->avg_avl); i++)
- len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
- avg->avg_avl[i]);
- buf[len - 1] = '\n';
-
- return len;
+ switch (mask) {
+ case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+ switch (chan->type) {
+ case IIO_HUMIDITYRELATIVE:
+ *vals = hts221_avg_list[HTS221_SENSOR_H].avg_avl;
+ *length = ARRAY_SIZE(hts221_avg_list[HTS221_SENSOR_H].avg_avl);
+ break;
+ case IIO_TEMP:
+ *vals = hts221_avg_list[HTS221_SENSOR_T].avg_avl;
+ *length = ARRAY_SIZE(hts221_avg_list[HTS221_SENSOR_T].avg_avl);
+ break;
+ default:
+ return -EINVAL;
+ }
+ *type = IIO_VAL_INT;
+ return IIO_AVAIL_LIST;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *vals = hts221_odr_avail;
+ *type = IIO_VAL_INT;
+ *length = ARRAY_SIZE(hts221_odr_avail);
+ return IIO_AVAIL_LIST;
+ default:
+ return -EINVAL;
+ }
}
int hts221_set_enable(struct hts221_hw *hw, bool enable)
@@ -521,27 +512,10 @@ static int hts221_validate_trigger(struct iio_dev *iio_dev,
return hw->trig == trig ? 0 : -EINVAL;
}
-static IIO_DEVICE_ATTR(in_humidity_oversampling_ratio_available, S_IRUGO,
- hts221_sysfs_rh_oversampling_avail, NULL, 0);
-static IIO_DEVICE_ATTR(in_temp_oversampling_ratio_available, S_IRUGO,
- hts221_sysfs_temp_oversampling_avail, NULL, 0);
-static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hts221_sysfs_sampling_freq);
-
-static struct attribute *hts221_attributes[] = {
- &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
- &iio_dev_attr_in_humidity_oversampling_ratio_available.dev_attr.attr,
- &iio_dev_attr_in_temp_oversampling_ratio_available.dev_attr.attr,
- NULL,
-};
-
-static const struct attribute_group hts221_attribute_group = {
- .attrs = hts221_attributes,
-};
-
static const struct iio_info hts221_info = {
- .attrs = &hts221_attribute_group,
.read_raw = hts221_read_raw,
.write_raw = hts221_write_raw,
+ .read_avail = hts221_read_avail,
.validate_trigger = hts221_validate_trigger,
};
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH 1/5] iio: humidity: hts221: report available values via read_avail()
2026-08-08 9:00 ` [PATCH 1/5] iio: humidity: hts221: report available values via read_avail() Adi Nata
@ 2026-08-10 0:09 ` Jonathan Cameron
0 siblings, 0 replies; 7+ messages in thread
From: Jonathan Cameron @ 2026-08-10 0:09 UTC (permalink / raw)
To: Adi Nata
Cc: lorenzo, dlechner, nuno.sa, andy, linux-iio, linux-kernel,
linux-kernel-mentees
On Sat, 8 Aug 2026 17:00:22 +0800
Adi Nata <adinata.softwareengineer@gmail.com> wrote:
> Replace the custom oversampling_ratio_available sysfs attributes with
> the standard IIO read_avail() callback. This lets the IIO core create
> and format *_available attributes and exposes the lists to
> in-kernel consumers.
Sashiko points out that there is an ABI change in here as oddly
the driver uses
in_humidity_oversampling_ratio_available rather than
in_humidityrelative_oversampling_ratio_available
Which makes this an ABI fix. Therefore this should have a fixes
tag and be moved to the start of the set. Please check that logic
though as maybe I'm missing something.
J
>
> Signed-off-by: Adi Nata <adinata.softwareengineer@gmail.com>
> ---
> drivers/iio/humidity/hts221_core.c | 106 +++++++++++------------------
> 1 file changed, 40 insertions(+), 66 deletions(-)
>
> diff --git a/drivers/iio/humidity/hts221_core.c b/drivers/iio/humidity/hts221_core.c
> index bfeb0a60d3af..76a391f421f5 100644
> --- a/drivers/iio/humidity/hts221_core.c
> +++ b/drivers/iio/humidity/hts221_core.c
> @@ -10,7 +10,6 @@
> #include <linux/kernel.h>
> #include <linux/module.h>
> #include <linux/device.h>
> -#include <linux/iio/sysfs.h>
> #include <linux/delay.h>
> #include <linux/pm.h>
> #include <linux/regmap.h>
> @@ -49,7 +48,7 @@ struct hts221_odr {
> struct hts221_avg {
> u8 addr;
> u8 mask;
> - u16 avg_avl[HTS221_AVG_DEPTH];
> + int avg_avl[HTS221_AVG_DEPTH];
> };
>
> static const struct hts221_odr hts221_odr_table[] = {
> @@ -58,6 +57,8 @@ static const struct hts221_odr hts221_odr_table[] = {
> { 13, 0x03 }, /* 12.5Hz */
> };
>
> +static const int hts221_odr_avail[] = { 1, 7, 13 };
> +
> static const struct hts221_avg hts221_avg_list[] = {
> {
> .addr = 0x10,
> @@ -97,7 +98,11 @@ static const struct iio_chan_spec hts221_channels[] = {
> BIT(IIO_CHAN_INFO_OFFSET) |
> BIT(IIO_CHAN_INFO_SCALE) |
> BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
> + .info_mask_separate_available =
> + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
> .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
> + .info_mask_shared_by_all_available =
> + BIT(IIO_CHAN_INFO_SAMP_FREQ),
> .scan_index = 0,
> .scan_type = {
> .sign = 's',
> @@ -113,7 +118,11 @@ static const struct iio_chan_spec hts221_channels[] = {
> BIT(IIO_CHAN_INFO_OFFSET) |
> BIT(IIO_CHAN_INFO_SCALE) |
> BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
> + .info_mask_separate_available =
> + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
> .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
> + .info_mask_shared_by_all_available =
> + BIT(IIO_CHAN_INFO_SAMP_FREQ),
> .scan_index = 1,
> .scan_type = {
> .sign = 's',
> @@ -192,53 +201,35 @@ static int hts221_update_avg(struct hts221_hw *hw,
> return 0;
> }
>
> -static ssize_t hts221_sysfs_sampling_freq(struct device *dev,
> - struct device_attribute *attr,
> - char *buf)
> -{
> - int i;
> - ssize_t len = 0;
> -
> - for (i = 0; i < ARRAY_SIZE(hts221_odr_table); i++)
> - len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
> - hts221_odr_table[i].hz);
> - buf[len - 1] = '\n';
> -
> - return len;
> -}
> -
> -static ssize_t
> -hts221_sysfs_rh_oversampling_avail(struct device *dev,
> - struct device_attribute *attr,
> - char *buf)
> -{
> - const struct hts221_avg *avg = &hts221_avg_list[HTS221_SENSOR_H];
> - ssize_t len = 0;
> - int i;
> -
> - for (i = 0; i < ARRAY_SIZE(avg->avg_avl); i++)
> - len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
> - avg->avg_avl[i]);
> - buf[len - 1] = '\n';
> -
> - return len;
> -}
> -
> -static ssize_t
> -hts221_sysfs_temp_oversampling_avail(struct device *dev,
> - struct device_attribute *attr,
> - char *buf)
> +static int hts221_read_avail(struct iio_dev *indio_dev,
> + struct iio_chan_spec const *chan,
> + const int **vals, int *type, int *length,
> + long mask)
> {
> - const struct hts221_avg *avg = &hts221_avg_list[HTS221_SENSOR_T];
> - ssize_t len = 0;
> - int i;
> -
> - for (i = 0; i < ARRAY_SIZE(avg->avg_avl); i++)
> - len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
> - avg->avg_avl[i]);
> - buf[len - 1] = '\n';
> -
> - return len;
> + switch (mask) {
> + case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> + switch (chan->type) {
> + case IIO_HUMIDITYRELATIVE:
> + *vals = hts221_avg_list[HTS221_SENSOR_H].avg_avl;
> + *length = ARRAY_SIZE(hts221_avg_list[HTS221_SENSOR_H].avg_avl);
> + break;
> + case IIO_TEMP:
> + *vals = hts221_avg_list[HTS221_SENSOR_T].avg_avl;
> + *length = ARRAY_SIZE(hts221_avg_list[HTS221_SENSOR_T].avg_avl);
> + break;
> + default:
> + return -EINVAL;
> + }
> + *type = IIO_VAL_INT;
> + return IIO_AVAIL_LIST;
> + case IIO_CHAN_INFO_SAMP_FREQ:
> + *vals = hts221_odr_avail;
> + *type = IIO_VAL_INT;
> + *length = ARRAY_SIZE(hts221_odr_avail);
> + return IIO_AVAIL_LIST;
> + default:
> + return -EINVAL;
> + }
> }
>
> int hts221_set_enable(struct hts221_hw *hw, bool enable)
> @@ -521,27 +512,10 @@ static int hts221_validate_trigger(struct iio_dev *iio_dev,
> return hw->trig == trig ? 0 : -EINVAL;
> }
>
> -static IIO_DEVICE_ATTR(in_humidity_oversampling_ratio_available, S_IRUGO,
> - hts221_sysfs_rh_oversampling_avail, NULL, 0);
> -static IIO_DEVICE_ATTR(in_temp_oversampling_ratio_available, S_IRUGO,
> - hts221_sysfs_temp_oversampling_avail, NULL, 0);
> -static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hts221_sysfs_sampling_freq);
> -
> -static struct attribute *hts221_attributes[] = {
> - &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
> - &iio_dev_attr_in_humidity_oversampling_ratio_available.dev_attr.attr,
> - &iio_dev_attr_in_temp_oversampling_ratio_available.dev_attr.attr,
> - NULL,
> -};
> -
> -static const struct attribute_group hts221_attribute_group = {
> - .attrs = hts221_attributes,
> -};
> -
> static const struct iio_info hts221_info = {
> - .attrs = &hts221_attribute_group,
> .read_raw = hts221_read_raw,
> .write_raw = hts221_write_raw,
> + .read_avail = hts221_read_avail,
> .validate_trigger = hts221_validate_trigger,
> };
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/5] iio: humidity: hts221: Add a blank line after variable declarations
2026-08-08 9:00 [PATCH 0/5] iio: humidity: hts221: update probe and logging implementations Adi Nata
2026-08-08 9:00 ` [PATCH 1/5] iio: humidity: hts221: report available values via read_avail() Adi Nata
@ 2026-08-08 9:00 ` Adi Nata
2026-08-08 9:00 ` [PATCH 3/5] iio: humidity: hts221: Allow unknown whoami for DT fallback Adi Nata
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Adi Nata @ 2026-08-08 9:00 UTC (permalink / raw)
To: lorenzo, jic23, dlechner, nuno.sa, andy, linux-iio, linux-kernel
Cc: linux-kernel-mentees, Adi Nata
Improve code readability per checkpatch warning
Signed-off-by: Adi Nata <adinata.softwareengineer@gmail.com>
---
drivers/iio/humidity/hts221_buffer.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/iio/humidity/hts221_buffer.c b/drivers/iio/humidity/hts221_buffer.c
index 4d03db19063e..c868549d09c0 100644
--- a/drivers/iio/humidity/hts221_buffer.c
+++ b/drivers/iio/humidity/hts221_buffer.c
@@ -194,6 +194,7 @@ static irqreturn_t hts221_buffer_handler_thread(int irq, void *p)
int hts221_allocate_buffers(struct iio_dev *iio_dev)
{
struct hts221_hw *hw = iio_priv(iio_dev);
+
return devm_iio_triggered_buffer_setup(hw->dev, iio_dev,
NULL, hts221_buffer_handler_thread,
&hts221_buffer_ops);
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 3/5] iio: humidity: hts221: Allow unknown whoami for DT fallback
2026-08-08 9:00 [PATCH 0/5] iio: humidity: hts221: update probe and logging implementations Adi Nata
2026-08-08 9:00 ` [PATCH 1/5] iio: humidity: hts221: report available values via read_avail() Adi Nata
2026-08-08 9:00 ` [PATCH 2/5] iio: humidity: hts221: Add a blank line after variable declarations Adi Nata
@ 2026-08-08 9:00 ` Adi Nata
2026-08-08 9:00 ` [PATCH 4/5] iio: humidity: hts221: use dev_err_probe() in probe paths Adi Nata
2026-08-08 9:00 ` [PATCH 5/5] iio: humidity: hts221: fix division by zero in calibration parsing Adi Nata
4 siblings, 0 replies; 7+ messages in thread
From: Adi Nata @ 2026-08-08 9:00 UTC (permalink / raw)
To: lorenzo, jic23, dlechner, nuno.sa, andy, linux-iio, linux-kernel
Cc: linux-kernel-mentees, Adi Nata
The WHOAMI check currently returns -ENODEV when the chip ID is not
0xbc. That rejects Device Tree fallback compatibles.
Keep failing if the WHOAMI register cannot be read. On an unexpected
ID, log it and continue so OF fallback matching can work.
Use dev_err_probe() for the read-failure path.
Signed-off-by: Adi Nata <adinata.softwareengineer@gmail.com>
---
drivers/iio/humidity/hts221_core.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/iio/humidity/hts221_core.c b/drivers/iio/humidity/hts221_core.c
index 76a391f421f5..da773d2edc80 100644
--- a/drivers/iio/humidity/hts221_core.c
+++ b/drivers/iio/humidity/hts221_core.c
@@ -139,16 +139,13 @@ static int hts221_check_whoami(struct hts221_hw *hw)
int err, data;
err = regmap_read(hw->regmap, HTS221_REG_WHOAMI_ADDR, &data);
- if (err < 0) {
- dev_err(hw->dev, "failed to read whoami register\n");
- return err;
- }
+ if (err < 0)
+ return dev_err_probe(hw->dev, err,
+ "failed to read whoami register\n");
- if (data != HTS221_REG_WHOAMI_VAL) {
- dev_err(hw->dev, "wrong whoami {%02x vs %02x}\n",
- data, HTS221_REG_WHOAMI_VAL);
- return -ENODEV;
- }
+ if (data != HTS221_REG_WHOAMI_VAL)
+ dev_info(hw->dev,
+ "unexpected whoami 0x%02x, continuing\n", data);
return 0;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 4/5] iio: humidity: hts221: use dev_err_probe() in probe paths
2026-08-08 9:00 [PATCH 0/5] iio: humidity: hts221: update probe and logging implementations Adi Nata
` (2 preceding siblings ...)
2026-08-08 9:00 ` [PATCH 3/5] iio: humidity: hts221: Allow unknown whoami for DT fallback Adi Nata
@ 2026-08-08 9:00 ` Adi Nata
2026-08-08 9:00 ` [PATCH 5/5] iio: humidity: hts221: fix division by zero in calibration parsing Adi Nata
4 siblings, 0 replies; 7+ messages in thread
From: Adi Nata @ 2026-08-08 9:00 UTC (permalink / raw)
To: lorenzo, jic23, dlechner, nuno.sa, andy, linux-iio, linux-kernel
Cc: linux-kernel-mentees, Adi Nata
Convert remaining probe-time error logs to dev_err_probe() so the
errno is included and deferred probe failures stay quiet.
Signed-off-by: Adi Nata <adinata.softwareengineer@gmail.com>
---
drivers/iio/humidity/hts221_core.c | 30 ++++++++++++------------------
drivers/iio/humidity/hts221_i2c.c | 8 +++-----
drivers/iio/humidity/hts221_spi.c | 8 +++-----
3 files changed, 18 insertions(+), 28 deletions(-)
diff --git a/drivers/iio/humidity/hts221_core.c b/drivers/iio/humidity/hts221_core.c
index da773d2edc80..313c80df3f6e 100644
--- a/drivers/iio/humidity/hts221_core.c
+++ b/drivers/iio/humidity/hts221_core.c
@@ -579,33 +579,27 @@ int hts221_probe(struct device *dev, int irq, const char *name,
/* configure humidity sensor */
err = hts221_parse_rh_caldata(hw);
- if (err < 0) {
- dev_err(hw->dev, "failed to get rh calibration data\n");
- return err;
- }
+ if (err < 0)
+ return dev_err_probe(hw->dev, err,
+ "failed to get rh calibration data\n");
data = hts221_avg_list[HTS221_SENSOR_H].avg_avl[3];
err = hts221_update_avg(hw, HTS221_SENSOR_H, data);
- if (err < 0) {
- dev_err(hw->dev, "failed to set rh oversampling ratio\n");
- return err;
- }
+ if (err < 0)
+ return dev_err_probe(hw->dev, err,
+ "failed to set rh oversampling ratio\n");
/* configure temperature sensor */
err = hts221_parse_temp_caldata(hw);
- if (err < 0) {
- dev_err(hw->dev,
- "failed to get temperature calibration data\n");
- return err;
- }
+ if (err < 0)
+ return dev_err_probe(hw->dev, err,
+ "failed to get temperature calibration data\n");
data = hts221_avg_list[HTS221_SENSOR_T].avg_avl[3];
err = hts221_update_avg(hw, HTS221_SENSOR_T, data);
- if (err < 0) {
- dev_err(hw->dev,
- "failed to set temperature oversampling ratio\n");
- return err;
- }
+ if (err < 0)
+ return dev_err_probe(hw->dev, err,
+ "failed to set temperature oversampling ratio\n");
if (hw->irq > 0) {
err = hts221_allocate_buffers(iio_dev);
diff --git a/drivers/iio/humidity/hts221_i2c.c b/drivers/iio/humidity/hts221_i2c.c
index 40276abc5d2e..8f5fa7d3eaf5 100644
--- a/drivers/iio/humidity/hts221_i2c.c
+++ b/drivers/iio/humidity/hts221_i2c.c
@@ -29,11 +29,9 @@ static int hts221_i2c_probe(struct i2c_client *client)
struct regmap *regmap;
regmap = devm_regmap_init_i2c(client, &hts221_i2c_regmap_config);
- if (IS_ERR(regmap)) {
- dev_err(&client->dev, "Failed to register i2c regmap %ld\n",
- PTR_ERR(regmap));
- return PTR_ERR(regmap);
- }
+ if (IS_ERR(regmap))
+ return dev_err_probe(&client->dev, PTR_ERR(regmap),
+ "Failed to register i2c regmap\n");
return hts221_probe(&client->dev, client->irq,
client->name, regmap);
diff --git a/drivers/iio/humidity/hts221_spi.c b/drivers/iio/humidity/hts221_spi.c
index e6fef2acd523..916fe8481c4a 100644
--- a/drivers/iio/humidity/hts221_spi.c
+++ b/drivers/iio/humidity/hts221_spi.c
@@ -30,11 +30,9 @@ static int hts221_spi_probe(struct spi_device *spi)
struct regmap *regmap;
regmap = devm_regmap_init_spi(spi, &hts221_spi_regmap_config);
- if (IS_ERR(regmap)) {
- dev_err(&spi->dev, "Failed to register spi regmap %ld\n",
- PTR_ERR(regmap));
- return PTR_ERR(regmap);
- }
+ if (IS_ERR(regmap))
+ return dev_err_probe(&spi->dev, PTR_ERR(regmap),
+ "Failed to register spi regmap\n");
return hts221_probe(&spi->dev, spi->irq,
spi->modalias, regmap);
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 5/5] iio: humidity: hts221: fix division by zero in calibration parsing
2026-08-08 9:00 [PATCH 0/5] iio: humidity: hts221: update probe and logging implementations Adi Nata
` (3 preceding siblings ...)
2026-08-08 9:00 ` [PATCH 4/5] iio: humidity: hts221: use dev_err_probe() in probe paths Adi Nata
@ 2026-08-08 9:00 ` Adi Nata
4 siblings, 0 replies; 7+ messages in thread
From: Adi Nata @ 2026-08-08 9:00 UTC (permalink / raw)
To: lorenzo, jic23, dlechner, nuno.sa, andy, linux-iio, linux-kernel
Cc: linux-kernel-mentees, Adi Nata
hts221_parse_rh_caldata() and hts221_parse_temp_caldata() divide by
(cal_x1 - cal_x0) without checking that the two calibration points
differ can cause division by zero.
Reject zero divisor with -EINVAL, logging the offending calibration
values. A device with such calibration data cannot produce meaningful
scale or offset values anyway.
Signed-off-by: Adi Nata <adinata.softwareengineer@gmail.com>
---
drivers/iio/humidity/hts221_core.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/iio/humidity/hts221_core.c b/drivers/iio/humidity/hts221_core.c
index 313c80df3f6e..fd11cc881dbf 100644
--- a/drivers/iio/humidity/hts221_core.c
+++ b/drivers/iio/humidity/hts221_core.c
@@ -276,10 +276,20 @@ static int hts221_parse_temp_caldata(struct hts221_hw *hw)
return err;
cal_x1 = le16_to_cpu(val);
+ if (cal_x1 == cal_x0)
+ return dev_err_probe(hw->dev, -EINVAL,
+ "invalid temperature calibration points (x0 %d, x1 %d)\n",
+ cal_x0, cal_x1);
+
slope = &hw->sensors[HTS221_SENSOR_T].slope;
b_gen = &hw->sensors[HTS221_SENSOR_T].b_gen;
*slope = ((cal_y1 - cal_y0) * 8000) / (cal_x1 - cal_x0);
+ if (!*slope)
+ return dev_err_probe(hw->dev, -EINVAL,
+ "invalid temperature calibration slope (y0 %d, y1 %d)\n",
+ cal_y0, cal_y1);
+
*b_gen = (((s32)cal_x1 * cal_y0 - (s32)cal_x0 * cal_y1) * 1000) /
(cal_x1 - cal_x0);
*b_gen *= 8;
@@ -315,10 +325,20 @@ static int hts221_parse_rh_caldata(struct hts221_hw *hw)
return err;
cal_x1 = le16_to_cpu(val);
+ if (cal_x1 == cal_x0)
+ return dev_err_probe(hw->dev, -EINVAL,
+ "invalid rh calibration points (x0 %d, x1 %d)\n",
+ cal_x0, cal_x1);
+
slope = &hw->sensors[HTS221_SENSOR_H].slope;
b_gen = &hw->sensors[HTS221_SENSOR_H].b_gen;
*slope = ((cal_y1 - cal_y0) * 8000) / (cal_x1 - cal_x0);
+ if (!*slope)
+ return dev_err_probe(hw->dev, -EINVAL,
+ "invalid rh calibration slope (y0 %d, y1 %d)\n",
+ cal_y0, cal_y1);
+
*b_gen = (((s32)cal_x1 * cal_y0 - (s32)cal_x0 * cal_y1) * 1000) /
(cal_x1 - cal_x0);
*b_gen *= 8;
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread