Devicetree
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Manaf Meethalavalappu Pallikunhi" <manaf.pallikunhi@oss.qualcomm.com>
Cc: mfd@lists.linux.dev, devicetree@vger.kernel.org, robh@kernel.org,
	linux-hwmon@vger.kernel.org, conor+dt@kernel.org, lee@kernel.org
Subject: Re: [PATCH v2 02/10] hwmon: Add Qualcomm PMIC BCL driver
Date: Tue, 21 Jul 2026 19:20:47 +0000	[thread overview]
Message-ID: <20260721192047.76EA01F00A3D@smtp.kernel.org> (raw)
In-Reply-To: <20260722-qcom-bcl-hwmon-v2-2-febe2805e17b@oss.qualcomm.com>

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] Uninitialized cache timestamps cause the driver to erroneously return cached 0 readings instead of hardware values for the first 5 minutes of system uptime.
- [High] Writing the maximum valid threshold value to certain sysfs attributes causes integer truncation when written to the hardware register, silently applying a dangerously low or zero limit.
- [Medium] Devres teardown ordering race allows the delayed polling work to re-enable `irq_wake` after it was disabled, causing an unbalanced wake count and triggering a kernel warning on driver unbind.
- [Medium] pmh0101_data is missing `.data_field_bits_size`, preventing voltage input readings from being exposed.
- [Low] Using `DIV_ROUND_CLOSEST` with a 64-bit signed dividend causes a link error on 32-bit architectures.
--

--- Patch [2]: [PATCH v2 02/10] hwmon: Add Qualcomm PMIC BCL driver ---
commit d1c02d33d76b0d05ddfd0d17bd163dd47036945c
Author: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
Subject: hwmon: Add Qualcomm PMIC BCL driver

This commit adds a new driver for Qualcomm SPMI PMIC Battery Current Limiting
(BCL). It exposes battery voltage and current monitoring through the hwmon
interface, including threshold-based alarms and interrupt notifications.

> diff --git a/drivers/hwmon/qcom-bcl-hwmon.c b/drivers/hwmon/qcom-bcl-hwmon.c
> new file mode 100644
> index 0000000000000..a21433b45482c
> --- /dev/null
> +++ b/drivers/hwmon/qcom-bcl-hwmon.c

[ ... ]

> +static const struct bcl_desc pmh0101_data = {
> +	.reg_fields = bcl_pmh0101_reg_fields,
> +	.num_reg_fields = F_CURR_MON_EN + 1,
> +	.thresh_field_bits_size = 8,
> +	.battery_config_field = REG_FIELD(0, 0, 0),
> +	.channel_cfg[BCL_BATT_1S][CHANNEL_IN] = {

[Severity: Medium]
Is the pmh0101_data descriptor missing a .data_field_bits_size initialization?

This descriptor defines F_IN_INPUT and F_IN_INPUT1 for 16-bit reads but
omits .data_field_bits_size. Since it zero-initializes to 0,
bcl_build_hwmon_info() will treat the input reading feature as disabled and
skip initializing the sensor, hiding the hardware functionality.

[ ... ]

> +static int bcl_convert_raw_to_milliunit(const struct bcl_device *bcl,
> +					s32 raw_val,
> +					enum bcl_channel type,
> +					u8 field_width)
> +{
> +	const struct bcl_desc *desc = bcl->desc;
> +	u32 def_scale = desc->channel_cfg[bcl->batt_config][type].default_scale_nu;
> +	u32 scaling_factor = (field_width > 8) ? def_scale : (def_scale << field_width);
> +
> +	return DIV_ROUND_CLOSEST((s64)raw_val * scaling_factor, 1000000);
> +}

[Severity: Low]
Will this cause a build failure on 32-bit architectures?

Using DIV_ROUND_CLOSEST with a 64-bit signed dividend utilizes the standard
division operator, which translates to a 64-bit signed division instruction.
Since the kernel does not implement __divdi3 for 32-bit architectures,
should div_s64() be used instead to prevent link errors?

[ ... ]

> +static int bcl_curr_thresh_write(struct bcl_device *bcl, long value, enum bcl_limit_alarm lvl)
> +{
> +	const struct bcl_desc *desc = bcl->desc;
> +	u32 raw_val;
> +
> +	int thresh = clamp_val(value, 0, desc->channel_cfg[bcl->batt_config][CHANNEL_CURR].max);
> +
> +	if (desc->channel_cfg[bcl->batt_config][CHANNEL_CURR].thresh_type[lvl] == THRESH_TYPE_ADC)
> +		raw_val = bcl_convert_milliunit_to_raw(bcl, thresh, CHANNEL_CURR,
> +						       desc->thresh_field_bits_size);
> +	else
> +		raw_val = bcl_convert_milliunit_to_index(bcl, thresh, CHANNEL_CURR);
> +
> +	return regmap_field_write(bcl->fields[F_CURR_H0_THR + lvl], raw_val);
> +}

[Severity: High]
Can writing the maximum valid threshold value to the sysfs attributes cause
integer truncation when written to the hardware register?

For the pm7250b_data variant, the maximum threshold is set to 10000, which
translates to a raw value of 256. When regmap_field_write() writes this to
an 8-bit field, it gets masked to 0, silently applying a 0 mA threshold
instead of the maximum.

Similarly for smb2360_data, the max voltage is 8400, which translates to
index 78. This masks to 14 in a 6-bit field, setting a 5200mV threshold.
Could the driver verify the value fits in the destination regmap field
before writing?

[ ... ]

> +static int bcl_curr_input_read(struct bcl_device *bcl, long *out)
> +{
> +	int ret;
> +	u32 raw_val = 0, msb = 0;
> +	s32 signed_val;
> +	const struct bcl_desc *desc = bcl->desc;
> +
> +	/* Return cached value if read too soon after last update */
> +	if (time_before(jiffies, bcl->last_curr_updated + HZ)) {
> +		*out = bcl->last_curr_input;
> +		return 0;
> +	}

[Severity: High]
Will this erroneously return cached 0 readings for the first 5 minutes of
system uptime?

The last_curr_updated timestamp is zero-initialized by devm_kzalloc(). The
kernel initializes jiffies to INITIAL_JIFFIES (typically 5 minutes before
wrap-around, e.g., -300 * HZ). Due to unsigned wrap-around comparison
semantics, time_before(jiffies, bcl->last_curr_updated + HZ) will evaluate
to true until jiffies reaches HZ.

This causes the driver to bypass hardware reads entirely and return the
uninitialized 0 value across all channels.

[ ... ]

> +static int bcl_alarm_irq_init(struct platform_device *pdev,
> +			      struct bcl_device *bcl)
> +{

[ ... ]

> +		ret = devm_request_threaded_irq(&pdev->dev, irq_num, NULL,
> +						bcl_handle_alarm, IRQF_ONESHOT,
> +						bcl_int_names[i], alarm);
> +		if (ret)
> +			return ret;
> +
> +		ret = devm_add_action_or_reset(&pdev->dev, bcl_alarm_work_cleanup_action,
> +					       alarm);
> +		if (ret)
> +			return ret;
> +
> +		if (!enable_irq_wake(irq_num))
> +			alarm->irq_wake_enabled = true;
> +
> +		ret = devm_add_action_or_reset(&pdev->dev, bcl_alarm_wake_cleanup_action,
> +					       alarm);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}

[Severity: Medium]
Does this devres teardown ordering allow the delayed polling work to
re-enable irq_wake after it was already disabled?

Since bcl_alarm_work_cleanup_action is registered before
bcl_alarm_wake_cleanup_action, the LIFO teardown executes the wake cleanup
first, disabling irq_wake.

Concurrently, the uncancelled alarm_poll_work can race to execute
bcl_alarm_enable_poll() and re-enable irq_wake before the work cleanup
action runs to cancel the work queue. Could this cause an unbalanced wake
count and trigger a kernel warning on driver unbind?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260722-qcom-bcl-hwmon-v2-0-febe2805e17b@oss.qualcomm.com?part=2

  reply	other threads:[~2026-07-21 19:20 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-21 18:30 [PATCH v2 00/10] hwmon: Add Qualcomm SPMI BCL driver Manaf Meethalavalappu Pallikunhi
2026-07-21 18:30 ` [PATCH v2 01/10] dt-bindings: hwmon: Describe Qualcomm BCL hardware Manaf Meethalavalappu Pallikunhi
2026-07-21 18:36   ` sashiko-bot
2026-07-21 18:30 ` [PATCH v2 02/10] hwmon: Add Qualcomm PMIC BCL driver Manaf Meethalavalappu Pallikunhi
2026-07-21 19:20   ` sashiko-bot [this message]
2026-07-21 20:44   ` Guenter Roeck
2026-07-21 18:30 ` [PATCH v2 03/10] arm64: dts: qcom: pm7250b: Enable BCL sensor node Manaf Meethalavalappu Pallikunhi
2026-07-21 19:13   ` sashiko-bot
2026-07-21 18:30 ` [PATCH v2 04/10] arm64: dts: qcom: hamoa-pmic: " Manaf Meethalavalappu Pallikunhi
2026-07-21 18:37   ` sashiko-bot
2026-07-21 18:30 ` [PATCH v2 05/10] arm64: dts: qcom: pm8350c: " Manaf Meethalavalappu Pallikunhi
2026-07-21 19:14   ` sashiko-bot
2026-07-21 18:30 ` [PATCH v2 06/10] arm64: dts: qcom: pmh0101: " Manaf Meethalavalappu Pallikunhi
2026-07-21 19:17   ` sashiko-bot
2026-07-21 18:30 ` [PATCH v2 07/10] arm64: dts: qcom: pm8550: " Manaf Meethalavalappu Pallikunhi
2026-07-21 19:14   ` sashiko-bot
2026-07-21 18:30 ` [PATCH v2 08/10] arm64: dts: qcom: pmih0108-kaanapali: " Manaf Meethalavalappu Pallikunhi
2026-07-21 19:17   ` sashiko-bot
2026-07-21 18:30 ` [PATCH v2 09/10] arm64: dts: qcom: pmih0108: " Manaf Meethalavalappu Pallikunhi
2026-07-21 19:16   ` sashiko-bot
2026-07-21 18:30 ` [PATCH v2 10/10] arm64: dts: qcom: smb2370: " Manaf Meethalavalappu Pallikunhi
2026-07-21 19:17   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260721192047.76EA01F00A3D@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=lee@kernel.org \
    --cc=linux-hwmon@vger.kernel.org \
    --cc=manaf.pallikunhi@oss.qualcomm.com \
    --cc=mfd@lists.linux.dev \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox