From 691e79ffc42154a9c91dc3b7e96a307037b4be74 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan Date: Fri, 11 Oct 2024 17:55:12 +0800 Subject: [PATCH 01/13] iio: gts-helper: Fix memory leaks in iio_gts_build_avail_scale_table() modprobe iio-test-gts and rmmod it, then the following memory leak occurs: unreferenced object 0xffffff80c810be00 (size 64): comm "kunit_try_catch", pid 1654, jiffies 4294913981 hex dump (first 32 bytes): 02 00 00 00 08 00 00 00 20 00 00 00 40 00 00 00 ........ ...@... 80 00 00 00 00 02 00 00 00 04 00 00 00 08 00 00 ................ backtrace (crc a63d875e): [<0000000028c1b3c2>] kmemleak_alloc+0x34/0x40 [<000000001d6ecc87>] __kmalloc_noprof+0x2bc/0x3c0 [<00000000393795c1>] devm_iio_init_iio_gts+0x4b4/0x16f4 [<0000000071bb4b09>] 0xffffffdf052a62e0 [<000000000315bc18>] 0xffffffdf052a6488 [<00000000f9dc55b5>] kunit_try_run_case+0x13c/0x3ac [<00000000175a3fd4>] kunit_generic_run_threadfn_adapter+0x80/0xec [<00000000f505065d>] kthread+0x2e8/0x374 [<00000000bbfb0e5d>] ret_from_fork+0x10/0x20 unreferenced object 0xffffff80cbfe9e70 (size 16): comm "kunit_try_catch", pid 1658, jiffies 4294914015 hex dump (first 16 bytes): 10 00 00 00 40 00 00 00 80 00 00 00 00 00 00 00 ....@........... backtrace (crc 857f0cb4): [<0000000028c1b3c2>] kmemleak_alloc+0x34/0x40 [<000000001d6ecc87>] __kmalloc_noprof+0x2bc/0x3c0 [<00000000393795c1>] devm_iio_init_iio_gts+0x4b4/0x16f4 [<0000000071bb4b09>] 0xffffffdf052a62e0 [<000000007d089d45>] 0xffffffdf052a6864 [<00000000f9dc55b5>] kunit_try_run_case+0x13c/0x3ac [<00000000175a3fd4>] kunit_generic_run_threadfn_adapter+0x80/0xec [<00000000f505065d>] kthread+0x2e8/0x374 [<00000000bbfb0e5d>] ret_from_fork+0x10/0x20 ...... It includes 5*5 times "size 64" memory leaks, which correspond to 5 times test_init_iio_gain_scale() calls with gts_test_gains size 10 (10*size(int)) and gts_test_itimes size 5. It also includes 5*1 times "size 16" memory leak, which correspond to one time __test_init_iio_gain_scale() call with gts_test_gains_gain_low size 3 (3*size(int)) and gts_test_itimes size 5. The reason is that the per_time_gains[i] is not freed which is allocated in the "gts->num_itime" for loop in iio_gts_build_avail_scale_table(). Cc: stable@vger.kernel.org Fixes: 38416c28e168 ("iio: light: Add gain-time-scale helpers") Signed-off-by: Jinjie Ruan Reviewed-by: Matti Vaittinen Link: https://patch.msgid.link/20241011095512.3667549-1-ruanjinjie@huawei.com Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-gts-helper.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iio/industrialio-gts-helper.c b/drivers/iio/industrialio-gts-helper.c index 59d7615c0f56..7326c7949244 100644 --- a/drivers/iio/industrialio-gts-helper.c +++ b/drivers/iio/industrialio-gts-helper.c @@ -307,6 +307,8 @@ static int iio_gts_build_avail_scale_table(struct iio_gts *gts) if (ret) goto err_free_out; + for (i = 0; i < gts->num_itime; i++) + kfree(per_time_gains[i]); kfree(per_time_gains); gts->per_time_avail_scale_tables = per_time_scales; From 369f05688911b05216cfcd6ca74473bec87948d7 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan Date: Wed, 16 Oct 2024 09:24:53 +0800 Subject: [PATCH 02/13] iio: gts-helper: Fix memory leaks for the error path of iio_gts_build_avail_scale_table() If per_time_scales[i] or per_time_gains[i] kcalloc fails in the for loop of iio_gts_build_avail_scale_table(), the err_free_out will fail to call kfree() each time when i is reduced to 0, so all the per_time_scales[0] and per_time_gains[0] will not be freed, which will cause memory leaks. Fix it by checking if i >= 0. Cc: stable@vger.kernel.org Fixes: 38416c28e168 ("iio: light: Add gain-time-scale helpers") Reviewed-by: Matti Vaittinen Signed-off-by: Jinjie Ruan Link: https://patch.msgid.link/20241016012453.2013302-1-ruanjinjie@huawei.com Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-gts-helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/industrialio-gts-helper.c b/drivers/iio/industrialio-gts-helper.c index 7326c7949244..5f131bc1a01e 100644 --- a/drivers/iio/industrialio-gts-helper.c +++ b/drivers/iio/industrialio-gts-helper.c @@ -315,7 +315,7 @@ static int iio_gts_build_avail_scale_table(struct iio_gts *gts) return 0; err_free_out: - for (i--; i; i--) { + for (i--; i >= 0; i--) { kfree(per_time_scales[i]); kfree(per_time_gains[i]); } From 63dd163cd61dda6f38343776b42331cc6b7e56e0 Mon Sep 17 00:00:00 2001 From: Javier Carrasco Date: Wed, 16 Oct 2024 19:04:31 +0200 Subject: [PATCH 03/13] iio: light: veml6030: fix microlux value calculation The raw value conversion to obtain a measurement in lux as INT_PLUS_MICRO does not calculate the decimal part properly to display it as micro (in this case microlux). It only calculates the module to obtain the decimal part from a resolution that is 10000 times the provided in the datasheet (0.5376 lux/cnt for the veml6030). The resulting value must still be multiplied by 100 to make it micro. This bug was introduced with the original implementation of the driver. Only the illuminance channel is fixed becuase the scale is non sensical for the intensity channels anyway. Cc: stable@vger.kernel.org Fixes: 7b779f573c48 ("iio: light: add driver for veml6030 ambient light sensor") Signed-off-by: Javier Carrasco Link: https://patch.msgid.link/20241016-veml6030-fix-processed-micro-v1-1-4a5644796437@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/light/veml6030.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/light/veml6030.c b/drivers/iio/light/veml6030.c index 9630de1c578e..621428885455 100644 --- a/drivers/iio/light/veml6030.c +++ b/drivers/iio/light/veml6030.c @@ -522,7 +522,7 @@ static int veml6030_read_raw(struct iio_dev *indio_dev, } if (mask == IIO_CHAN_INFO_PROCESSED) { *val = (reg * data->cur_resolution) / 10000; - *val2 = (reg * data->cur_resolution) % 10000; + *val2 = (reg * data->cur_resolution) % 10000 * 100; return IIO_VAL_INT_PLUS_MICRO; } *val = reg; From fbe5956e8809f04e9121923db0b6d1b94f2b93ba Mon Sep 17 00:00:00 2001 From: Julien Stephan Date: Tue, 22 Oct 2024 15:22:36 +0200 Subject: [PATCH 04/13] dt-bindings: iio: adc: ad7380: fix ad7380-4 reference supply ad7380-4 is the only device from ad738x family that doesn't have an internal reference. Moreover its external reference is called REFIN in the datasheet while all other use REFIO as an optional external reference. If refio-supply is omitted the internal reference is used. Fix the binding by adding refin-supply and makes it required for ad7380-4 only. Fixes: 1a291cc8ee17 ("dt-bindings: iio: adc: ad7380: add support for ad738x-4 4 channels variants") Acked-by: Conor Dooley Reviewed-by: David Lechner Signed-off-by: Julien Stephan Link: https://patch.msgid.link/20241022-ad7380-fix-supplies-v3-1-f0cefe1b7fa6@baylibre.com Cc: Signed-off-by: Jonathan Cameron --- .../bindings/iio/adc/adi,ad7380.yaml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml index bd19abb867d9..0065d6508824 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml @@ -67,6 +67,10 @@ properties: A 2.5V to 3.3V supply for the external reference voltage. When omitted, the internal 2.5V reference is used. + refin-supply: + description: + A 2.5V to 3.3V supply for external reference voltage, for ad7380-4 only. + aina-supply: description: The common mode voltage supply for the AINA- pin on pseudo-differential @@ -135,6 +139,23 @@ allOf: ainc-supply: false aind-supply: false + # ad7380-4 uses refin-supply as external reference. + # All other chips from ad738x family use refio as optional external reference. + # When refio-supply is omitted, internal reference is used. + - if: + properties: + compatible: + enum: + - adi,ad7380-4 + then: + properties: + refio-supply: false + required: + - refin-supply + else: + properties: + refin-supply: false + examples: - | #include From 2ac6b2e823b52f7f4abf1d3a97d11889e22d0d16 Mon Sep 17 00:00:00 2001 From: Julien Stephan Date: Tue, 22 Oct 2024 15:22:37 +0200 Subject: [PATCH 05/13] iio: adc: ad7380: use devm_regulator_get_enable_read_voltage() Use devm_regulator_get_enable_read_voltage() to simplify the code. Reviewed-by: Nuno Sa Reviewed-by: David Lechner Signed-off-by: Julien Stephan Link: https://patch.msgid.link/20241022-ad7380-fix-supplies-v3-2-f0cefe1b7fa6@baylibre.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7380.c | 81 +++++++++++----------------------------- 1 file changed, 21 insertions(+), 60 deletions(-) diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c index e8bddfb0d07d..e033c7341911 100644 --- a/drivers/iio/adc/ad7380.c +++ b/drivers/iio/adc/ad7380.c @@ -956,7 +956,7 @@ static const struct iio_info ad7380_info = { .debugfs_reg_access = &ad7380_debugfs_reg_access, }; -static int ad7380_init(struct ad7380_state *st, struct regulator *vref) +static int ad7380_init(struct ad7380_state *st, bool external_ref_en) { int ret; @@ -968,13 +968,13 @@ static int ad7380_init(struct ad7380_state *st, struct regulator *vref) if (ret < 0) return ret; - /* select internal or external reference voltage */ - ret = regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG1, - AD7380_CONFIG1_REFSEL, - FIELD_PREP(AD7380_CONFIG1_REFSEL, - vref ? 1 : 0)); - if (ret < 0) - return ret; + if (external_ref_en) { + /* select external reference voltage */ + ret = regmap_set_bits(st->regmap, AD7380_REG_ADDR_CONFIG1, + AD7380_CONFIG1_REFSEL); + if (ret < 0) + return ret; + } /* This is the default value after reset. */ st->oversampling_ratio = 1; @@ -987,16 +987,11 @@ static int ad7380_init(struct ad7380_state *st, struct regulator *vref) FIELD_PREP(AD7380_CONFIG2_SDO, 1)); } -static void ad7380_regulator_disable(void *p) -{ - regulator_disable(p); -} - static int ad7380_probe(struct spi_device *spi) { struct iio_dev *indio_dev; struct ad7380_state *st; - struct regulator *vref; + bool external_ref_en; int ret, i; indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); @@ -1009,37 +1004,17 @@ static int ad7380_probe(struct spi_device *spi) if (!st->chip_info) return dev_err_probe(&spi->dev, -EINVAL, "missing match data\n"); - vref = devm_regulator_get_optional(&spi->dev, "refio"); - if (IS_ERR(vref)) { - if (PTR_ERR(vref) != -ENODEV) - return dev_err_probe(&spi->dev, PTR_ERR(vref), - "Failed to get refio regulator\n"); - - vref = NULL; - } - /* * If there is no REFIO supply, then it means that we are using * the internal 2.5V reference, otherwise REFIO is reference voltage. */ - if (vref) { - ret = regulator_enable(vref); - if (ret) - return ret; + ret = devm_regulator_get_enable_read_voltage(&spi->dev, "refio"); + if (ret < 0 && ret != -ENODEV) + return dev_err_probe(&spi->dev, ret, + "Failed to get refio regulator\n"); - ret = devm_add_action_or_reset(&spi->dev, - ad7380_regulator_disable, vref); - if (ret) - return ret; - - ret = regulator_get_voltage(vref); - if (ret < 0) - return ret; - - st->vref_mv = ret / 1000; - } else { - st->vref_mv = AD7380_INTERNAL_REF_MV; - } + external_ref_en = ret != -ENODEV; + st->vref_mv = external_ref_en ? ret / 1000 : AD7380_INTERNAL_REF_MV; if (st->chip_info->num_vcm_supplies > ARRAY_SIZE(st->vcm_mv)) return dev_err_probe(&spi->dev, -EINVAL, @@ -1050,27 +1025,13 @@ static int ad7380_probe(struct spi_device *spi) * input pin. */ for (i = 0; i < st->chip_info->num_vcm_supplies; i++) { - struct regulator *vcm; + const char *vcm = st->chip_info->vcm_supplies[i]; - vcm = devm_regulator_get(&spi->dev, - st->chip_info->vcm_supplies[i]); - if (IS_ERR(vcm)) - return dev_err_probe(&spi->dev, PTR_ERR(vcm), - "Failed to get %s regulator\n", - st->chip_info->vcm_supplies[i]); - - ret = regulator_enable(vcm); - if (ret) - return ret; - - ret = devm_add_action_or_reset(&spi->dev, - ad7380_regulator_disable, vcm); - if (ret) - return ret; - - ret = regulator_get_voltage(vcm); + ret = devm_regulator_get_enable_read_voltage(&spi->dev, vcm); if (ret < 0) - return ret; + return dev_err_probe(&spi->dev, ret, + "Failed to get %s regulator\n", + vcm); st->vcm_mv[i] = ret / 1000; } @@ -1135,7 +1096,7 @@ static int ad7380_probe(struct spi_device *spi) if (ret) return ret; - ret = ad7380_init(st, vref); + ret = ad7380_init(st, external_ref_en); if (ret) return ret; From 7ddbc2728728f9b832ade7b4c180efdc2f22e8b9 Mon Sep 17 00:00:00 2001 From: Julien Stephan Date: Tue, 22 Oct 2024 15:22:38 +0200 Subject: [PATCH 06/13] iio: adc: ad7380: add missing supplies vcc and vlogic are required but are not retrieved and enabled in the probe. Add them. In order to prepare support for additional parts requiring different supplies, add vcc and vlogic to the platform specific structures Reviewed-by: Nuno Sa Reviewed-by: David Lechner Signed-off-by: Julien Stephan Link: https://patch.msgid.link/20241022-ad7380-fix-supplies-v3-3-f0cefe1b7fa6@baylibre.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7380.c | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c index e033c7341911..b107d8e97ab3 100644 --- a/drivers/iio/adc/ad7380.c +++ b/drivers/iio/adc/ad7380.c @@ -75,6 +75,7 @@ #define T_CONVERT_NS 190 /* conversion time */ #define T_CONVERT_0_NS 10 /* 1st conversion start time (oversampling) */ #define T_CONVERT_X_NS 500 /* xth conversion start time (oversampling) */ +#define T_POWERUP_US 5000 /* Power up */ struct ad7380_timing_specs { const unsigned int t_csh_ns; /* CS minimum high time */ @@ -86,6 +87,8 @@ struct ad7380_chip_info { unsigned int num_channels; unsigned int num_simult_channels; bool has_mux; + const char * const *supplies; + unsigned int num_supplies; const char * const *vcm_supplies; unsigned int num_vcm_supplies; const unsigned long *available_scan_masks; @@ -243,6 +246,10 @@ DEFINE_AD7380_8_CHANNEL(ad7386_4_channels, 16, 0, u); DEFINE_AD7380_8_CHANNEL(ad7387_4_channels, 14, 0, u); DEFINE_AD7380_8_CHANNEL(ad7388_4_channels, 12, 0, u); +static const char * const ad7380_supplies[] = { + "vcc", "vlogic", +}; + static const char * const ad7380_2_channel_vcm_supplies[] = { "aina", "ainb", }; @@ -338,6 +345,8 @@ static const struct ad7380_chip_info ad7380_chip_info = { .channels = ad7380_channels, .num_channels = ARRAY_SIZE(ad7380_channels), .num_simult_channels = 2, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .available_scan_masks = ad7380_2_channel_scan_masks, .timing_specs = &ad7380_timing, }; @@ -347,6 +356,8 @@ static const struct ad7380_chip_info ad7381_chip_info = { .channels = ad7381_channels, .num_channels = ARRAY_SIZE(ad7381_channels), .num_simult_channels = 2, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .available_scan_masks = ad7380_2_channel_scan_masks, .timing_specs = &ad7380_timing, }; @@ -356,6 +367,8 @@ static const struct ad7380_chip_info ad7383_chip_info = { .channels = ad7383_channels, .num_channels = ARRAY_SIZE(ad7383_channels), .num_simult_channels = 2, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .vcm_supplies = ad7380_2_channel_vcm_supplies, .num_vcm_supplies = ARRAY_SIZE(ad7380_2_channel_vcm_supplies), .available_scan_masks = ad7380_2_channel_scan_masks, @@ -367,6 +380,8 @@ static const struct ad7380_chip_info ad7384_chip_info = { .channels = ad7384_channels, .num_channels = ARRAY_SIZE(ad7384_channels), .num_simult_channels = 2, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .vcm_supplies = ad7380_2_channel_vcm_supplies, .num_vcm_supplies = ARRAY_SIZE(ad7380_2_channel_vcm_supplies), .available_scan_masks = ad7380_2_channel_scan_masks, @@ -378,6 +393,8 @@ static const struct ad7380_chip_info ad7386_chip_info = { .channels = ad7386_channels, .num_channels = ARRAY_SIZE(ad7386_channels), .num_simult_channels = 2, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .has_mux = true, .available_scan_masks = ad7380_2x2_channel_scan_masks, .timing_specs = &ad7380_timing, @@ -388,6 +405,8 @@ static const struct ad7380_chip_info ad7387_chip_info = { .channels = ad7387_channels, .num_channels = ARRAY_SIZE(ad7387_channels), .num_simult_channels = 2, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .has_mux = true, .available_scan_masks = ad7380_2x2_channel_scan_masks, .timing_specs = &ad7380_timing, @@ -398,6 +417,8 @@ static const struct ad7380_chip_info ad7388_chip_info = { .channels = ad7388_channels, .num_channels = ARRAY_SIZE(ad7388_channels), .num_simult_channels = 2, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .has_mux = true, .available_scan_masks = ad7380_2x2_channel_scan_masks, .timing_specs = &ad7380_timing, @@ -408,6 +429,8 @@ static const struct ad7380_chip_info ad7380_4_chip_info = { .channels = ad7380_4_channels, .num_channels = ARRAY_SIZE(ad7380_4_channels), .num_simult_channels = 4, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .available_scan_masks = ad7380_4_channel_scan_masks, .timing_specs = &ad7380_4_timing, }; @@ -417,6 +440,8 @@ static const struct ad7380_chip_info ad7381_4_chip_info = { .channels = ad7381_4_channels, .num_channels = ARRAY_SIZE(ad7381_4_channels), .num_simult_channels = 4, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .available_scan_masks = ad7380_4_channel_scan_masks, .timing_specs = &ad7380_4_timing, }; @@ -426,6 +451,8 @@ static const struct ad7380_chip_info ad7383_4_chip_info = { .channels = ad7383_4_channels, .num_channels = ARRAY_SIZE(ad7383_4_channels), .num_simult_channels = 4, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .vcm_supplies = ad7380_4_channel_vcm_supplies, .num_vcm_supplies = ARRAY_SIZE(ad7380_4_channel_vcm_supplies), .available_scan_masks = ad7380_4_channel_scan_masks, @@ -437,6 +464,8 @@ static const struct ad7380_chip_info ad7384_4_chip_info = { .channels = ad7384_4_channels, .num_channels = ARRAY_SIZE(ad7384_4_channels), .num_simult_channels = 4, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .vcm_supplies = ad7380_4_channel_vcm_supplies, .num_vcm_supplies = ARRAY_SIZE(ad7380_4_channel_vcm_supplies), .available_scan_masks = ad7380_4_channel_scan_masks, @@ -448,6 +477,8 @@ static const struct ad7380_chip_info ad7386_4_chip_info = { .channels = ad7386_4_channels, .num_channels = ARRAY_SIZE(ad7386_4_channels), .num_simult_channels = 4, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .has_mux = true, .available_scan_masks = ad7380_2x4_channel_scan_masks, .timing_specs = &ad7380_4_timing, @@ -458,6 +489,8 @@ static const struct ad7380_chip_info ad7387_4_chip_info = { .channels = ad7387_4_channels, .num_channels = ARRAY_SIZE(ad7387_4_channels), .num_simult_channels = 4, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .has_mux = true, .available_scan_masks = ad7380_2x4_channel_scan_masks, .timing_specs = &ad7380_4_timing, @@ -468,6 +501,8 @@ static const struct ad7380_chip_info ad7388_4_chip_info = { .channels = ad7388_4_channels, .num_channels = ARRAY_SIZE(ad7388_4_channels), .num_simult_channels = 4, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .has_mux = true, .available_scan_masks = ad7380_2x4_channel_scan_masks, .timing_specs = &ad7380_4_timing, @@ -1004,6 +1039,14 @@ static int ad7380_probe(struct spi_device *spi) if (!st->chip_info) return dev_err_probe(&spi->dev, -EINVAL, "missing match data\n"); + ret = devm_regulator_bulk_get_enable(&spi->dev, st->chip_info->num_supplies, + st->chip_info->supplies); + + if (ret) + return dev_err_probe(&spi->dev, ret, + "Failed to enable power supplies\n"); + fsleep(T_POWERUP_US); + /* * If there is no REFIO supply, then it means that we are using * the internal 2.5V reference, otherwise REFIO is reference voltage. From 05f9c67179c9a8d66dee175fb4b17f380908a26f Mon Sep 17 00:00:00 2001 From: Julien Stephan Date: Tue, 22 Oct 2024 15:22:39 +0200 Subject: [PATCH 07/13] iio: adc: ad7380: fix supplies for ad7380-4 ad7380-4 is the only device in the family that does not have an internal reference. It uses "refin" as a required external reference. All other devices in the family use "refio"" as an optional external reference. Fixes: 737413da8704 ("iio: adc: ad7380: add support for ad738x-4 4 channels variants") Reviewed-by: Nuno Sa Reviewed-by: David Lechner Signed-off-by: Julien Stephan Link: https://patch.msgid.link/20241022-ad7380-fix-supplies-v3-4-f0cefe1b7fa6@baylibre.com Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7380.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c index b107d8e97ab3..fb728570debe 100644 --- a/drivers/iio/adc/ad7380.c +++ b/drivers/iio/adc/ad7380.c @@ -89,6 +89,7 @@ struct ad7380_chip_info { bool has_mux; const char * const *supplies; unsigned int num_supplies; + bool external_ref_only; const char * const *vcm_supplies; unsigned int num_vcm_supplies; const unsigned long *available_scan_masks; @@ -431,6 +432,7 @@ static const struct ad7380_chip_info ad7380_4_chip_info = { .num_simult_channels = 4, .supplies = ad7380_supplies, .num_supplies = ARRAY_SIZE(ad7380_supplies), + .external_ref_only = true, .available_scan_masks = ad7380_4_channel_scan_masks, .timing_specs = &ad7380_4_timing, }; @@ -1047,17 +1049,31 @@ static int ad7380_probe(struct spi_device *spi) "Failed to enable power supplies\n"); fsleep(T_POWERUP_US); - /* - * If there is no REFIO supply, then it means that we are using - * the internal 2.5V reference, otherwise REFIO is reference voltage. - */ - ret = devm_regulator_get_enable_read_voltage(&spi->dev, "refio"); - if (ret < 0 && ret != -ENODEV) - return dev_err_probe(&spi->dev, ret, - "Failed to get refio regulator\n"); + if (st->chip_info->external_ref_only) { + ret = devm_regulator_get_enable_read_voltage(&spi->dev, + "refin"); + if (ret < 0) + return dev_err_probe(&spi->dev, ret, + "Failed to get refin regulator\n"); - external_ref_en = ret != -ENODEV; - st->vref_mv = external_ref_en ? ret / 1000 : AD7380_INTERNAL_REF_MV; + st->vref_mv = ret / 1000; + + /* these chips don't have a register bit for this */ + external_ref_en = false; + } else { + /* + * If there is no REFIO supply, then it means that we are using + * the internal reference, otherwise REFIO is reference voltage. + */ + ret = devm_regulator_get_enable_read_voltage(&spi->dev, + "refio"); + if (ret < 0 && ret != -ENODEV) + return dev_err_probe(&spi->dev, ret, + "Failed to get refio regulator\n"); + + external_ref_en = ret != -ENODEV; + st->vref_mv = external_ref_en ? ret / 1000 : AD7380_INTERNAL_REF_MV; + } if (st->chip_info->num_vcm_supplies > ARRAY_SIZE(st->vcm_mv)) return dev_err_probe(&spi->dev, -EINVAL, From 795114e849ddfd48150eb0135d04748a8c81cec5 Mon Sep 17 00:00:00 2001 From: Julien Stephan Date: Tue, 22 Oct 2024 15:22:40 +0200 Subject: [PATCH 08/13] docs: iio: ad7380: fix supply for ad7380-4 ad7380-4 is the only device from ad738x family that doesn't have an internal reference. Moreover it's external reference is called REFIN in the datasheet while all other use REFIO as an optional external reference. Update documentation to highlight this. Fixes: 3e82dfc82f38 ("docs: iio: new docs for ad7380 driver") Reviewed-by: David Lechner Signed-off-by: Julien Stephan Link: https://patch.msgid.link/20241022-ad7380-fix-supplies-v3-5-f0cefe1b7fa6@baylibre.com Cc: Signed-off-by: Jonathan Cameron --- Documentation/iio/ad7380.rst | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Documentation/iio/ad7380.rst b/Documentation/iio/ad7380.rst index 9c784c1e652e..6f70b49b9ef2 100644 --- a/Documentation/iio/ad7380.rst +++ b/Documentation/iio/ad7380.rst @@ -41,13 +41,22 @@ supports only 1 SDO line. Reference voltage ----------------- -2 possible reference voltage sources are supported: +ad7380-4 +~~~~~~~~ + +ad7380-4 supports only an external reference voltage (2.5V to 3.3V). It must be +declared in the device tree as ``refin-supply``. + +All other devices from ad738x family +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +All other devices from ad738x support 2 possible reference voltage sources: - Internal reference (2.5V) - External reference (2.5V to 3.3V) The source is determined by the device tree. If ``refio-supply`` is present, -then the external reference is used, else the internal reference is used. +then it is used as external reference, else the internal reference is used. Oversampling and resolution boost --------------------------------- From 6bd301819f8f69331a55ae2336c8b111fc933f3d Mon Sep 17 00:00:00 2001 From: Zicheng Qu Date: Tue, 22 Oct 2024 13:43:54 +0000 Subject: [PATCH 09/13] staging: iio: frequency: ad9832: fix division by zero in ad9832_calc_freqreg() In the ad9832_write_frequency() function, clk_get_rate() might return 0. This can lead to a division by zero when calling ad9832_calc_freqreg(). The check if (fout > (clk_get_rate(st->mclk) / 2)) does not protect against the case when fout is 0. The ad9832_write_frequency() function is called from ad9832_write(), and fout is derived from a text buffer, which can contain any value. Link: https://lore.kernel.org/all/2024100904-CVE-2024-47663-9bdc@gregkh/ Fixes: ea707584bac1 ("Staging: IIO: DDS: AD9832 / AD9835 driver") Cc: stable@vger.kernel.org Signed-off-by: Zicheng Qu Reviewed-by: Nuno Sa Reviewed-by: Dan Carpenter Link: https://patch.msgid.link/20241022134354.574614-1-quzicheng@huawei.com Signed-off-by: Jonathan Cameron --- drivers/staging/iio/frequency/ad9832.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c index 6c390c4eb26d..492612e8f8ba 100644 --- a/drivers/staging/iio/frequency/ad9832.c +++ b/drivers/staging/iio/frequency/ad9832.c @@ -129,12 +129,15 @@ static unsigned long ad9832_calc_freqreg(unsigned long mclk, unsigned long fout) static int ad9832_write_frequency(struct ad9832_state *st, unsigned int addr, unsigned long fout) { + unsigned long clk_freq; unsigned long regval; - if (fout > (clk_get_rate(st->mclk) / 2)) + clk_freq = clk_get_rate(st->mclk); + + if (!clk_freq || fout > (clk_freq / 2)) return -EINVAL; - regval = ad9832_calc_freqreg(clk_get_rate(st->mclk), fout); + regval = ad9832_calc_freqreg(clk_freq, fout); st->freq_data[0] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) | (addr << ADD_SHIFT) | From efa353ae1b0541981bc96dbf2e586387d0392baa Mon Sep 17 00:00:00 2001 From: Zicheng Qu Date: Tue, 22 Oct 2024 13:43:30 +0000 Subject: [PATCH 10/13] iio: adc: ad7124: fix division by zero in ad7124_set_channel_odr() In the ad7124_write_raw() function, parameter val can potentially be zero. This may lead to a division by zero when DIV_ROUND_CLOSEST() is called within ad7124_set_channel_odr(). The ad7124_write_raw() function is invoked through the sequence: iio_write_channel_raw() -> iio_write_channel_attribute() -> iio_channel_write(), with no checks in place to ensure val is non-zero. Cc: stable@vger.kernel.org Fixes: 7b8d045e497a ("iio: adc: ad7124: allow more than 8 channels") Signed-off-by: Zicheng Qu Reviewed-by: Nuno Sa Link: https://patch.msgid.link/20241022134330.574601-1-quzicheng@huawei.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7124.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c index a5d91933f505..b79c48d46ccc 100644 --- a/drivers/iio/adc/ad7124.c +++ b/drivers/iio/adc/ad7124.c @@ -637,7 +637,7 @@ static int ad7124_write_raw(struct iio_dev *indio_dev, switch (info) { case IIO_CHAN_INFO_SAMP_FREQ: - if (val2 != 0) { + if (val2 != 0 || val == 0) { ret = -EINVAL; break; } From 7bd4923940c8d67d9f3f3fde8d7c067e9e804fc6 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan Date: Thu, 24 Oct 2024 09:55:53 +0800 Subject: [PATCH 11/13] iio: dac: Kconfig: Fix build error for ltc2664 If REGMAP_SPI is n and LTC2664 is y, the following build error occurs: riscv64-unknown-linux-gnu-ld: drivers/iio/dac/ltc2664.o: in function `ltc2664_probe': ltc2664.c:(.text+0x714): undefined reference to `__devm_regmap_init_spi' Select REGMAP_SPI instead of REGMAP for LTC2664 to fix it. Fixes: 4cc2fc445d2e ("iio: dac: ltc2664: Add driver for LTC2664 and LTC2672") Reviewed-by: Nuno Sa Signed-off-by: Jinjie Ruan Link: https://patch.msgid.link/20241024015553.1111253-1-ruanjinjie@huawei.com Signed-off-by: Jonathan Cameron --- drivers/iio/dac/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 45e337c6d256..9f5d5ebb8653 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -380,7 +380,7 @@ config LTC2632 config LTC2664 tristate "Analog Devices LTC2664 and LTC2672 DAC SPI driver" depends on SPI - select REGMAP + select REGMAP_SPI help Say yes here to build support for Analog Devices LTC2664 and LTC2672 converters (DAC). From cb617e148bb3d50dfbbd44db81227edcee2cd4bc Mon Sep 17 00:00:00 2001 From: Abylay Ospan Date: Wed, 23 Oct 2024 16:34:25 +0000 Subject: [PATCH 12/13] MAINTAINERS: add netup_unidvb maintainer Adding/restoring maintainership for the following drivers: F: drivers/media/pci/netup_unidvb/* F: drivers/media/dvb-frontends/helene* F: drivers/media/dvb-frontends/horus3a* F: drivers/media/dvb-frontends/lnbh25* F: drivers/media/dvb-frontends/ascot2e* F: drivers/media/dvb-frontends/cxd2841er* Signed-off-by: Abylay Ospan Link: https://lore.kernel.org/r/20241023163425.30492-1-aospan@amazon.com Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index e9659a5a7fb3..332ab5fd4b59 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14140,6 +14140,15 @@ S: Maintained T: git git://linuxtv.org/media_tree.git F: drivers/media/platform/nxp/imx-pxp.[ch] +MEDIA DRIVERS FOR ASCOT2E +M: Abylay Ospan +L: linux-media@vger.kernel.org +S: Supported +W: https://linuxtv.org +W: http://netup.tv/ +T: git git://linuxtv.org/media_tree.git +F: drivers/media/dvb-frontends/ascot2e* + MEDIA DRIVERS FOR CXD2099AR CI CONTROLLERS M: Jasmin Jessich L: linux-media@vger.kernel.org @@ -14148,6 +14157,15 @@ W: https://linuxtv.org T: git git://linuxtv.org/media_tree.git F: drivers/media/dvb-frontends/cxd2099* +MEDIA DRIVERS FOR CXD2841ER +M: Abylay Ospan +L: linux-media@vger.kernel.org +S: Supported +W: https://linuxtv.org +W: http://netup.tv/ +T: git git://linuxtv.org/media_tree.git +F: drivers/media/dvb-frontends/cxd2841er* + MEDIA DRIVERS FOR CXD2880 M: Yasunari Takiguchi L: linux-media@vger.kernel.org @@ -14192,6 +14210,33 @@ F: drivers/media/platform/nxp/imx-mipi-csis.c F: drivers/media/platform/nxp/imx7-media-csi.c F: drivers/media/platform/nxp/imx8mq-mipi-csi2.c +MEDIA DRIVERS FOR HELENE +M: Abylay Ospan +L: linux-media@vger.kernel.org +S: Supported +W: https://linuxtv.org +W: http://netup.tv/ +T: git git://linuxtv.org/media_tree.git +F: drivers/media/dvb-frontends/helene* + +MEDIA DRIVERS FOR HORUS3A +M: Abylay Ospan +L: linux-media@vger.kernel.org +S: Supported +W: https://linuxtv.org +W: http://netup.tv/ +T: git git://linuxtv.org/media_tree.git +F: drivers/media/dvb-frontends/horus3a* + +MEDIA DRIVERS FOR LNBH25 +M: Abylay Ospan +L: linux-media@vger.kernel.org +S: Supported +W: https://linuxtv.org +W: http://netup.tv/ +T: git git://linuxtv.org/media_tree.git +F: drivers/media/dvb-frontends/lnbh25* + MEDIA DRIVERS FOR MXL5XX TUNER DEMODULATORS L: linux-media@vger.kernel.org S: Orphan @@ -14199,6 +14244,15 @@ W: https://linuxtv.org T: git git://linuxtv.org/media_tree.git F: drivers/media/dvb-frontends/mxl5xx* +MEDIA DRIVERS FOR NETUP PCI UNIVERSAL DVB devices +M: Abylay Ospan +L: linux-media@vger.kernel.org +S: Supported +W: https://linuxtv.org +W: http://netup.tv/ +T: git git://linuxtv.org/media_tree.git +F: drivers/media/pci/netup_unidvb/* + MEDIA DRIVERS FOR NVIDIA TEGRA - VDE M: Dmitry Osipenko L: linux-media@vger.kernel.org From 4adf613e01bf99e1739f6ff3e162ad5b7d578d1a Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Tue, 15 Oct 2024 15:31:57 +0300 Subject: [PATCH 13/13] mei: use kvmalloc for read buffer Read buffer is allocated according to max message size, reported by the firmware and may reach 64K in systems with pxp client. Contiguous 64k allocation may fail under memory pressure. Read buffer is used as in-driver message storage and not required to be contiguous. Use kvmalloc to allow kernel to allocate non-contiguous memory. Fixes: 3030dc056459 ("mei: add wrapper for queuing control commands.") Cc: stable Reported-by: Rohit Agarwal Closes: https://lore.kernel.org/all/20240813084542.2921300-1-rohiagar@chromium.org/ Tested-by: Brian Geffon Signed-off-by: Alexander Usyskin Acked-by: Tomas Winkler Link: https://lore.kernel.org/r/20241015123157.2337026-1-alexander.usyskin@intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 9d090fa07516..be011cef12e5 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -321,7 +321,7 @@ void mei_io_cb_free(struct mei_cl_cb *cb) return; list_del(&cb->list); - kfree(cb->buf.data); + kvfree(cb->buf.data); kfree(cb->ext_hdr); kfree(cb); } @@ -497,7 +497,7 @@ struct mei_cl_cb *mei_cl_alloc_cb(struct mei_cl *cl, size_t length, if (length == 0) return cb; - cb->buf.data = kmalloc(roundup(length, MEI_SLOT_SIZE), GFP_KERNEL); + cb->buf.data = kvmalloc(roundup(length, MEI_SLOT_SIZE), GFP_KERNEL); if (!cb->buf.data) { mei_io_cb_free(cb); return NULL;