Linux Hardware Monitor development
 help / color / mirror / Atom feed
* [PATCH v3 00/12] hwmon: Add Qualcomm SPMI BCL driver
@ 2026-09-29 13:09 Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:09 ` [PATCH v3 01/12] dt-bindings: hwmon: Describe Qualcomm BCL hardware Manaf Meethalavalappu Pallikunhi
                   ` (11 more replies)
  0 siblings, 12 replies; 38+ messages in thread
From: Manaf Meethalavalappu Pallikunhi @ 2026-09-29 13:09 UTC (permalink / raw)
  To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa
  Cc: linux-hwmon, linux-arm-msm, devicetree, linux-kernel, mfd,
	Gaurav Kohli, Manaf Meethalavalappu Pallikunhi

This series introduces support for the Qualcomm SPMI PMIC Battery Current
Limiting (BCL) hardware monitor present in various Qualcomm PMICs.

The BCL hardware ensures robust battery protection by monitoring battery
conditions in real time and triggering interrupts when predefined
thresholds are crossed. These alerts allow the system to respond
proactively, preventing battery degradation and preserving system
reliability under adverse power conditions.

The driver integrates with the standard hwmon subsystem, exposing battery
measurements and configurable alarm thresholds. This design enables
seamless integration with existing system monitoring tools and thermal
management frameworks.

Key features:
- Battery/system under voltage and over current monitoring support
- Real-time voltage and current readings support
- Configurable threshold-based alarms (warning, critical and emergency)
- Interrupt-driven notifications for threshold violations
- Automatic threshold management with polling-based recovery
- Hardware-specific scaling factors and threshold representations

Voltage and current monitoring can be independently enabled/disabled
by firmware, and the driver automatically detects the enabled features
at probe time.

Dependencies:
- This series depends on the following patch, which is currently present
  in linux-next but is not yet in the mainline tree:
  https://lore.kernel.org/all/20260813211433.879638-1-linux@roeck-us.net/

Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
---
Changes in v3:
- Rebased series and added 3rd alarm (emergency limit alarm) support for all PMICs
- Used static hwmon info building instead of dynamic info (Guenter)
- Removed unnecessary generic labels sysfs (Guenter)
- Renamed struct bcl_channel_cfg fields with _mu suffix for clarity
- Removed linux/mod_devicetable.h include (Uwe)
- Fixed uninitialized cache timestamps (sashiko ai)
- Fixed Integer truncation in threshold writes(sashiko ai)
- Fixed Missing data_field_bits_size in pmh0101_data (sashiko ai)
- Fixed DIV_ROUND_CLOSEST 32-bit architecture issue (sashiko ai)
- Fixed CHANNEL_CURR max_mu values using correct formula
- Fixed critical teardown race conditions
- Added device tree nodes for PM7550 and PM7550BA on Eliza platform
- Link to v2: https://lore.kernel.org/r/20260722-qcom-bcl-hwmon-v2-0-febe2805e17b@oss.qualcomm.com

Changes in v2:
- Reworked the binding from the generic qcom,bcl-hwmon.yaml schema to a
  PMIC-specific qcom,pm7250b-bcl.yaml schema using exact compatible strings.(Krzysztof)
- Dropped the DT-configured overcurrent-thresholds-milliamp property.(Konrad)
- Renamed interrupt names from "bcl-max-min"/"bcl-critical" to
  "max-min"/"critical".(Krzysztof)
- Limited the binding and driver match table to the supported PMICs:
  PM7250B, PM8350C, PM8550, PMH0101, PMIH0108, SMB2360 and SMB2370.(Daniel)
- Folded qcom-bcl-hwmon.h into qcom-bcl-hwmon.c and removed the
  macro-generated alarm mapping helpers.(Krzysztof/Bjorn/Daniel)
- Reworked the driver around per-PMIC register descriptors instead of
  generic BCL generation/mode descriptors.(Krzysztof/Bjorn)
- Added support for 16-bit voltage/current input registers and
  SMB2360/SMB2370 2S/3S battery configuration based scaling.
- Build hwmon channel information dynamically from hardware enable state
  instead of registering static voltage/current channel sets.(Daniel)
- Improved alarm IRQ handling with per-alarm locking, wake state tracking,
  shutdown guards, and explicit delayed-work cleanup.
- Switched probe/error paths to dev_err_probe() and tightened BCL enable,
  regmap-field, and hwmon registration handling.
- Link to v1: https://lore.kernel.org/r/20260206-qcom-bcl-hwmon-v1-0-7b426f0b77a1@oss.qualcomm.com

---
Manaf Meethalavalappu Pallikunhi (12):
      dt-bindings: hwmon: Describe Qualcomm BCL hardware
      hwmon: Add Qualcomm PMIC BCL driver
      arm64: dts: qcom: hamoa-pmic: Enable BCL sensor node
      arm64: dts: qcom: pm7250b: Enable BCL sensor node
      arm64: dts: qcom: pm7550-eliza: Enable BCL sensor node
      arm64: dts: qcom: pm7550ba-eliza: Enable BCL sensor node
      arm64: dts: qcom: pm8350c: Enable BCL sensor node
      arm64: dts: qcom: pm8550: Enable BCL sensor node
      arm64: dts: qcom: pmh0101: Enable BCL sensor node
      arm64: dts: qcom: pmih0108-kaanapali: Enable BCL sensor node
      arm64: dts: qcom: pmih0108: Enable BCL sensor node
      arm64: dts: qcom: smb2370: Enable BCL sensor node

 .../bindings/hwmon/qcom,pm7250b-bcl.yaml           |   69 +
 .../devicetree/bindings/mfd/qcom,spmi-pmic.yaml    |    4 +
 MAINTAINERS                                        |    8 +
 arch/arm64/boot/dts/qcom/hamoa-pmics.dtsi          |   22 +
 arch/arm64/boot/dts/qcom/pm7250b.dtsi              |   11 +
 arch/arm64/boot/dts/qcom/pm7550-eliza.dtsi         |   11 +
 arch/arm64/boot/dts/qcom/pm7550ba-eliza.dtsi       |   11 +
 arch/arm64/boot/dts/qcom/pm8350c.dtsi              |   12 +
 arch/arm64/boot/dts/qcom/pm8550.dtsi               |   11 +
 arch/arm64/boot/dts/qcom/pmh0101.dtsi              |   11 +
 arch/arm64/boot/dts/qcom/pmih0108-kaanapali.dtsi   |   11 +
 arch/arm64/boot/dts/qcom/pmih0108.dtsi             |   11 +
 arch/arm64/boot/dts/qcom/smb2370.dtsi              |   11 +
 drivers/hwmon/Kconfig                              |   11 +
 drivers/hwmon/Makefile                             |    1 +
 drivers/hwmon/qcom-bcl-hwmon.c                     | 1440 ++++++++++++++++++++
 16 files changed, 1655 insertions(+)
---
base-commit: 6375e61c01e93e35ee7acd336a689ac1fae4b509
change-id: 20260720-qcom-bcl-hwmon-6d602c195eab
prerequisite-patch-id: 1db32e67cbec8d818eeed046d68022414227d2d5

Best regards,
-- 
Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>


^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 01/12] dt-bindings: hwmon: Describe Qualcomm BCL hardware
  2026-09-29 13:09 [PATCH v3 00/12] hwmon: Add Qualcomm SPMI BCL driver Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:09 ` Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:15   ` sashiko-bot
  2026-09-29 13:09 ` [PATCH v3 02/12] hwmon: Add Qualcomm PMIC BCL driver Manaf Meethalavalappu Pallikunhi
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 38+ messages in thread
From: Manaf Meethalavalappu Pallikunhi @ 2026-09-29 13:09 UTC (permalink / raw)
  To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa
  Cc: linux-hwmon, linux-arm-msm, devicetree, linux-kernel, mfd,
	Gaurav Kohli, Manaf Meethalavalappu Pallikunhi

Qualcomm SPMI PMIC BCL (Battery Current Limiting) is a safety feature
that monitors battery or system voltage and current to alert system
for overcurrent or undervoltage conditions.

It provides:
- Real-time voltage and current monitoring
- Configurable thresholds per channel
- Hardware interrupts when thresholds are violated

Add a devicetree binding to describe the BCL on Qualcomm's PMICs.

Add sensor type to SPMI device list for BCL device.

Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
---
 .../bindings/hwmon/qcom,pm7250b-bcl.yaml           | 69 ++++++++++++++++++++++
 .../devicetree/bindings/mfd/qcom,spmi-pmic.yaml    |  4 ++
 MAINTAINERS                                        |  7 +++
 3 files changed, 80 insertions(+)

diff --git a/Documentation/devicetree/bindings/hwmon/qcom,pm7250b-bcl.yaml b/Documentation/devicetree/bindings/hwmon/qcom,pm7250b-bcl.yaml
new file mode 100644
index 000000000000..a9e3525cf099
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/qcom,pm7250b-bcl.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwmon/qcom,pm7250b-bcl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SPMI PMIC Battery Current Limiting (BCL) Hardware Monitor
+
+maintainers:
+  - Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
+
+description:
+  SPMI PMIC Battery Current Limiting (BCL) hardware provides monitoring and
+  alarm functionality for battery overcurrent and battery or system under
+  voltage conditions. It monitors battery voltage and current, and
+  can trigger interrupts when configurable thresholds are exceeded.
+
+properties:
+  compatible:
+    enum:
+      - qcom,pm7250b-bcl
+      - qcom,pm7550-bcl
+      - qcom,pm7550ba-bcl
+      - qcom,pm8350c-bcl
+      - qcom,pm8550-bcl
+      - qcom,pmh0101-bcl
+      - qcom,pmih0108-bcl
+      - qcom,smb2360-bcl
+      - qcom,smb2370-bcl
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 3
+
+  interrupt-names:
+    items:
+      - const: max-min
+      - const: critical
+      - const: emergency
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    pmic {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        sensor@1d00 {
+            compatible = "qcom,pm7250b-bcl";
+            reg = <0x1d00>;
+            interrupts = <0x2 0x1d 0x0 IRQ_TYPE_EDGE_RISING>,
+                         <0x2 0x1d 0x1 IRQ_TYPE_EDGE_RISING>,
+                         <0x2 0x1d 0x2 IRQ_TYPE_EDGE_RISING>;
+            interrupt-names = "max-min",
+                              "critical",
+                              "emergency";
+        };
+    };
diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
index f6534e9e9912..48dc437b3889 100644
--- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
+++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
@@ -195,6 +195,10 @@ patternProperties:
     type: object
     $ref: /schemas/rtc/qcom-pm8xxx-rtc.yaml#
 
+  "^sensor@[0-9a-f]+$":
+    type: object
+    $ref: /schemas/hwmon/qcom,pm7250b-bcl.yaml#
+
   "^temp-alarm@[0-9a-f]+$":
     type: object
     $ref: /schemas/thermal/qcom,spmi-temp-alarm.yaml#
diff --git a/MAINTAINERS b/MAINTAINERS
index 1c02b919d6ae..7cc16f7ccd66 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22657,6 +22657,13 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/net/qcom,bam-dmux.yaml
 F:	drivers/net/wwan/qcom_bam_dmux.c
 
+QUALCOMM BCL HARDWARE MONITOR DRIVER
+M:	Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
+L:	linux-hwmon@vger.kernel.org
+L:	linux-arm-msm@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/hwmon/qcom,pm7250b-bcl.yaml
+
 QUALCOMM BLUETOOTH DRIVER
 M:	Bartosz Golaszewski <brgl@kernel.org>
 L:	linux-arm-msm@vger.kernel.org

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v3 02/12] hwmon: Add Qualcomm PMIC BCL driver
  2026-09-29 13:09 [PATCH v3 00/12] hwmon: Add Qualcomm SPMI BCL driver Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:09 ` [PATCH v3 01/12] dt-bindings: hwmon: Describe Qualcomm BCL hardware Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:09 ` Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:21   ` sashiko-bot
  2026-09-29 13:09 ` [PATCH v3 03/12] arm64: dts: qcom: hamoa-pmic: Enable BCL sensor node Manaf Meethalavalappu Pallikunhi
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 38+ messages in thread
From: Manaf Meethalavalappu Pallikunhi @ 2026-09-29 13:09 UTC (permalink / raw)
  To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa
  Cc: linux-hwmon, linux-arm-msm, devicetree, linux-kernel, mfd,
	Gaurav Kohli, Manaf Meethalavalappu Pallikunhi

Add driver for Qualcomm SPMI PMIC Battery Current Limiting (BCL)
hardware monitor. The driver exposes battery voltage and current
monitoring through hwmon interface.

The BCL driver provides
- Real-time voltage and current readings
- Configurable threshold-based alarms
- Interrupt-driven notifications when thresholds are exceeded
- Automatic threshold management with polling-based recovery
- Hardware-specific scaling factors and threshold representations

Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
---
 MAINTAINERS                    |    1 +
 drivers/hwmon/Kconfig          |   11 +
 drivers/hwmon/Makefile         |    1 +
 drivers/hwmon/qcom-bcl-hwmon.c | 1440 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 1453 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 7cc16f7ccd66..9c96049f6c60 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22663,6 +22663,7 @@ L:	linux-hwmon@vger.kernel.org
 L:	linux-arm-msm@vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/hwmon/qcom,pm7250b-bcl.yaml
+F:	drivers/hwmon/qcom-bcl-hwmon.c
 
 QUALCOMM BLUETOOTH DRIVER
 M:	Bartosz Golaszewski <brgl@kernel.org>
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 18c682e1a475..8b5a490217c9 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1999,6 +1999,17 @@ config SENSORS_PWM_FAN
 	  This driver can also be built as a module. If so, the module
 	  will be called pwm-fan.
 
+config SENSORS_QCOM_SPMI_BCL
+	tristate "Qualcomm SPMI BCL hardware monitoring"
+	depends on SPMI
+	select REGMAP_SPMI
+	help
+	  Say yes here to enable support for Qualcomm battery over current
+	  and under voltage alarms monitor.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called qcom-bcl-hwmon.
+
 config SENSORS_QNAP_MCU_HWMON
 	tristate "QNAP MCU hardware monitoring"
 	depends on MFD_QNAP_MCU
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index d4c345ed7261..ef19ddf52789 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -209,6 +209,7 @@ obj-$(CONFIG_SENSORS_POWR1220)  += powr1220.o
 obj-$(CONFIG_SENSORS_PROM21_XHCI)	+= prom21-xhci.o
 obj-$(CONFIG_SENSORS_PT5161L)	+= pt5161l.o
 obj-$(CONFIG_SENSORS_PWM_FAN)	+= pwm-fan.o
+obj-$(CONFIG_SENSORS_QCOM_SPMI_BCL)	+= qcom-bcl-hwmon.o
 obj-$(CONFIG_SENSORS_QNAP_MCU_HWMON)	+= qnap-mcu-hwmon.o
 obj-$(CONFIG_SENSORS_RASPBERRYPI_HWMON)	+= raspberrypi-hwmon.o
 obj-$(CONFIG_SENSORS_SBTSI)	+= sbtsi_temp.o
diff --git a/drivers/hwmon/qcom-bcl-hwmon.c b/drivers/hwmon/qcom-bcl-hwmon.c
new file mode 100644
index 000000000000..eb6bfa7ff18f
--- /dev/null
+++ b/drivers/hwmon/qcom-bcl-hwmon.c
@@ -0,0 +1,1440 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Qualcomm pmic BCL driver for battery overcurrent and
+ * battery or system under voltage monitor
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/devm-helpers.h>
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/workqueue.h>
+
+/* BCL common regmap offset */
+#define REVISION1			0x0
+#define REVISION2			0x1
+#define STATUS				0x8
+#define INT_RT_STS			0x10
+#define EN_CTL1				0x46
+
+/* BCL GEN1 regmap offsets */
+#define VADC_L0_THR			0x48
+#define VCMP_L1_THR			0x49
+#define VCMP_L2_THR			0x4a
+#define IADC_H0_THR			0x4b
+#define IADC_H1_THR			0x4c
+#define VADC_DATA1			0x76
+#define IADC_DATA1			0x86
+
+/* BCL GEN3 regmap offsets */
+#define VCMP_L0_THR			0x47
+#define IADC_H1_THR_GEN3		0x4d
+
+#define BCL_ALARM_POLLING_MS		50
+
+/**
+ * enum bcl_limit_alarm - BCL alarm threshold levels
+ * @BCL_LIMIT_ALARM_LVL0: Level 0 alarm threshold
+ * @BCL_LIMIT_ALARM_LVL1: Level 1 alarm threshold
+ * @BCL_LIMIT_ALARM_LVL2: Level 2 alarm threshold
+ * @BCL_LIMIT_ALARM_MAX: sentinel value
+ *
+ * Defines the threshold levels for BCL monitoring. Each level corresponds
+ * to different severity of in or curr conditions.
+ */
+enum bcl_limit_alarm {
+	BCL_LIMIT_ALARM_LVL0,
+	BCL_LIMIT_ALARM_LVL1,
+	BCL_LIMIT_ALARM_LVL2,
+
+	BCL_LIMIT_ALARM_MAX,
+};
+
+/**
+ * enum bcl_channel - BCL supported sensor channel type
+ * @CHANNEL_IN: in (voltage) channel
+ * @CHANNEL_CURR: curr (current) channel
+ * @CHANNEL_MAX: sentinel value
+ *
+ * Defines the supported channel types for bcl.
+ */
+enum bcl_channel {
+	CHANNEL_IN,
+	CHANNEL_CURR,
+
+	CHANNEL_MAX,
+};
+
+/**
+ * enum bcl_thresh_type - voltage or current threshold representation type
+ * @THRESH_TYPE_ADC: Raw ADC value representation
+ * @THRESH_TYPE_INDEX: Index-based voltage or current representation
+ *
+ * Specifies how voltage or current thresholds are stored and interpreted in
+ * registers. Some PMICs use raw ADC values while others use indexed values.
+ */
+enum bcl_thresh_type {
+	THRESH_TYPE_ADC,
+	THRESH_TYPE_INDEX,
+};
+
+/**
+ * enum bcl_battery_config - Battery configuration types
+ * @BCL_BATT_1S: Single cell battery
+ * @BCL_BATT_2S: Two cells in series
+ * @BCL_BATT_3S: Three cells in series
+ */
+enum bcl_battery_config {
+	BCL_BATT_1S,
+	BCL_BATT_2S,
+	BCL_BATT_3S,
+};
+
+/**
+ * enum bcl_fields - BCL register field identifiers
+ * @F_V_MAJOR: Major revision info field
+ * @F_V_MINOR: Minor revision info field
+ * @F_CTL_EN: Monitor enable control field
+ * @F_LVL0_ALARM: Level 0 alarm status field
+ * @F_LVL1_ALARM: Level 1 alarm status field
+ * @F_LVL2_ALARM: Level 2 alarm status field
+ * @F_IN_L0_THR: voltage level 0 threshold field
+ * @F_IN_L1_THR: voltage level 1 threshold field
+ * @F_IN_L2_THR: voltage level 2 threshold field
+ * @F_IN_INPUT: voltage input data field (LSB for 16-bit data)
+ * @F_IN_INPUT1: voltage input data MSB for 16-bit voltage data
+ * @F_CURR_H0_THR: current level 0 threshold field
+ * @F_CURR_H1_THR: current level 1 threshold field
+ * @F_CURR_INPUT: current input data field (LSB for 16-bit data)
+ * @F_CURR_INPUT1: current input data MSB for 16-bit current data
+ * @F_MAX_FIELDS: sentinel value
+ *
+ * Enumeration of all register fields used by the BCL driver for accessing
+ * registers through regmap fields.
+ */
+enum bcl_fields {
+	/* Common fields - present in all BCL variants */
+	F_V_MAJOR,
+	F_V_MINOR,
+	F_CTL_EN,
+	F_LVL0_ALARM,
+	F_LVL1_ALARM,
+	F_LVL2_ALARM,
+
+	/* Voltage monitoring fields */
+	F_IN_L0_THR,
+	F_IN_L1_THR,
+	F_IN_L2_THR,
+	F_IN_INPUT,
+	F_IN_INPUT1,	/* MSB for 16-bit voltage data */
+
+	/* Current monitoring fields */
+	F_CURR_H0_THR,
+	F_CURR_H1_THR,
+	F_CURR_INPUT,
+	F_CURR_INPUT1,	/* MSB for 16-bit current data */
+
+	F_MAX_FIELDS
+};
+
+/**
+ * struct bcl_channel_cfg - BCL channel related configuration
+ * @default_scale_nu:  Default scaling factor in nano unit
+ * @base_mu: Base threshold value in milli unit
+ * @max_mu: Maximum threshold value in milli unit
+ * @step_mu: step increment value between two indexed threshold value in milli unit
+ * @thresh_type: Array specifying threshold representation type for each alarm level
+ *
+ * Contains hardware-specific configuration and scaling parameters for different
+ * channels (voltage and current).
+ */
+struct bcl_channel_cfg {
+	u32 default_scale_nu;
+	u32 base_mu;
+	u32 max_mu;
+	u32 step_mu;
+	u8 thresh_type[BCL_LIMIT_ALARM_MAX];
+};
+
+/**
+ * struct bcl_desc - BCL device descriptor
+ * @reg_fields: Array of register field definitions for this device variant
+ * @channel_cfg: Array of channel configurations indexed by battery config
+ *               PMICs without battery detection: only [BCL_BATT_1S] is defined
+ *               PMICs with battery detection: [BCL_BATT_2S], [BCL_BATT_3S]
+ * @battery_config_field: Register field for battery configuration detection
+ *                        NOTE: This is an ABSOLUTE address, not relative to BCL base
+ *                        Set to REG_FIELD(0, 0, 0) if not used
+ * @num_reg_fields: Number of register field definitions for this device variant
+ * @data_field_bits_size: data read register bit size
+ * @thresh_field_bits_size: lsb bit size those are not included in threshold register
+ * @in_mon_enabled: Voltage monitoring enabled at boot
+ * @in_input_enabled: Voltage input reading enabled at boot
+ * @curr_mon_enabled: Current monitoring enabled at boot
+ *
+ * Contains hardware-specific configuration and scaling parameters for different
+ * BCL variants. Each PMIC model may have different register layouts and
+ * conversion factors.
+ */
+struct bcl_desc {
+	const struct reg_field *reg_fields;
+	struct bcl_channel_cfg channel_cfg[BCL_BATT_3S + 1][CHANNEL_MAX];
+	const struct reg_field battery_config_field;
+	u8 num_reg_fields;
+	u8 data_field_bits_size;
+	u8 thresh_field_bits_size;
+	bool in_mon_enabled;
+	bool in_input_enabled;
+	bool curr_mon_enabled;
+};
+
+/**
+ * struct bcl_alarm_data - BCL alarm interrupt data
+ * @irq: IRQ number assigned to this alarm
+ * @irq_enabled: Flag indicating if IRQ is enabled
+ * @irq_wake_enabled: Flag indicating if IRQ wake is enabled
+ * @shutting_down: Flag preventing work from re-enabling IRQ during teardown
+ * @type: Alarm level type (LVL0, or LVL1)
+ * @device: Pointer to parent BCL device structure
+ * @a_lock: Mutex for protecting alarm state
+ * @alarm_poll_work: delayed_work to poll alarm status
+ *
+ * Stores interrupt-related information for each alarm threshold level.
+ * Used by the IRQ handler to identify which alarm triggered.
+ */
+struct bcl_alarm_data {
+	int			irq;
+	bool			irq_enabled;
+	bool			irq_wake_enabled;
+	bool			shutting_down;
+	enum bcl_limit_alarm	type;
+	void			*device;
+	/* Protects alarm IRQ enable/disable state */
+	struct mutex		a_lock;
+	struct delayed_work	alarm_poll_work;
+};
+
+/**
+ * struct bcl_device - Main BCL device structure
+ * @dev: Pointer to device structure
+ * @regmap: Regmap for accessing PMIC registers
+ * @base: the BCL regbase offset from regmap
+ * @fields: Array of regmap fields for register access
+ * @bcl_alarms: Array of alarm data structures for each threshold level
+ * @lock: Mutex for protecting concurrent hardware access
+ * @last_in_input: Last valid voltage input reading in millivolts
+ * @last_curr_input: Last valid current input reading in milliamps
+ * @last_in_updated: Timestamp of last voltage input update
+ * @last_curr_updated: Timestamp of last current input update
+ * @desc: Pointer to device descriptor with hardware-specific parameters
+ * @hwmon_dev: Pointer to registered hwmon device
+ * @hwmon_name: Sanitized name for hwmon device
+ * @batt_config: Detected battery configuration (only for SMB2360/2370)
+ * @batt_config_regfield: Regmap field for battery configuration register
+ *
+ * Main driver structure containing all state and configuration for a BCL
+ * monitoring instance. Manages voltage and current monitoring, thresholds,
+ * and alarm handling.
+ */
+struct bcl_device {
+	struct device		*dev;
+	struct regmap		*regmap;
+	u16			base;
+	struct regmap_field	*fields[F_MAX_FIELDS];
+	struct bcl_alarm_data	bcl_alarms[BCL_LIMIT_ALARM_MAX];
+	/* Protects hardware register access and device state */
+	struct mutex		lock;
+	u32			last_in_input;
+	s32			last_curr_input;
+	unsigned long		last_in_updated;
+	unsigned long		last_curr_updated;
+	const struct bcl_desc	*desc;
+	struct device		*hwmon_dev;
+	char			*hwmon_name;
+	enum bcl_battery_config	batt_config;
+	struct regmap_field	*batt_config_regfield;
+};
+
+static const u8 in_attr_to_lvl_map[] = {
+	[hwmon_in_min] = BCL_LIMIT_ALARM_LVL0,
+	[hwmon_in_lcrit] = BCL_LIMIT_ALARM_LVL1,
+	[hwmon_in_lemergency] = BCL_LIMIT_ALARM_LVL2,
+	[hwmon_in_min_alarm] = BCL_LIMIT_ALARM_LVL0,
+	[hwmon_in_lcrit_alarm] = BCL_LIMIT_ALARM_LVL1,
+	[hwmon_in_lemergency_alarm] = BCL_LIMIT_ALARM_LVL2,
+};
+
+static const u8 in_lvl_to_attr_map[BCL_LIMIT_ALARM_MAX] = {
+	[BCL_LIMIT_ALARM_LVL0] = hwmon_in_min_alarm,
+	[BCL_LIMIT_ALARM_LVL1] = hwmon_in_lcrit_alarm,
+	[BCL_LIMIT_ALARM_LVL2] = hwmon_in_lemergency_alarm,
+};
+
+static const u8 curr_attr_to_lvl_map[] = {
+	[hwmon_curr_max] = BCL_LIMIT_ALARM_LVL0,
+	[hwmon_curr_crit] = BCL_LIMIT_ALARM_LVL1,
+	[hwmon_curr_max_alarm] = BCL_LIMIT_ALARM_LVL0,
+	[hwmon_curr_crit_alarm] = BCL_LIMIT_ALARM_LVL1,
+	[hwmon_curr_emergency_alarm] = BCL_LIMIT_ALARM_LVL2,
+};
+
+static const u8 curr_lvl_to_attr_map[BCL_LIMIT_ALARM_MAX] = {
+	[BCL_LIMIT_ALARM_LVL0] = hwmon_curr_max_alarm,
+	[BCL_LIMIT_ALARM_LVL1] = hwmon_curr_crit_alarm,
+	[BCL_LIMIT_ALARM_LVL2] = hwmon_curr_emergency_alarm,
+};
+
+/* Interrupt names for each alarm level */
+static const char * const bcl_int_names[BCL_LIMIT_ALARM_MAX] = {
+	[BCL_LIMIT_ALARM_LVL0] = "max-min",
+	[BCL_LIMIT_ALARM_LVL1] = "critical",
+	[BCL_LIMIT_ALARM_LVL2] = "emergency",
+};
+
+static const struct reg_field bcl_pm7250b_reg_fields[] = {
+	[F_V_MAJOR]	= REG_FIELD(REVISION2, 0, 7),
+	[F_V_MINOR]	= REG_FIELD(REVISION1, 0, 7),
+	[F_CTL_EN]	= REG_FIELD(EN_CTL1, 7, 7),
+	[F_LVL0_ALARM]	= REG_FIELD(STATUS, 0, 0),
+	[F_LVL1_ALARM]	= REG_FIELD(STATUS, 1, 1),
+	[F_LVL2_ALARM]	= REG_FIELD(STATUS, 2, 2),
+	[F_IN_L0_THR]	= REG_FIELD(VADC_L0_THR, 0, 7),
+	[F_IN_L1_THR]	= REG_FIELD(VCMP_L1_THR, 0, 5),
+	[F_IN_L2_THR]	= REG_FIELD(VCMP_L2_THR, 0, 5),
+	[F_IN_INPUT]	= REG_FIELD(VADC_DATA1, 0, 7),
+	[F_CURR_H0_THR]	= REG_FIELD(IADC_H0_THR, 0, 7),
+	[F_CURR_H1_THR]	= REG_FIELD(IADC_H1_THR, 0, 7),
+	[F_CURR_INPUT]	= REG_FIELD(IADC_DATA1, 0, 7),
+};
+
+static const struct reg_field bcl_pm7550ba_reg_fields[] = {
+	[F_V_MAJOR]	= REG_FIELD(REVISION2, 0, 7),
+	[F_V_MINOR]	= REG_FIELD(REVISION1, 0, 7),
+	[F_CTL_EN]	= REG_FIELD(EN_CTL1, 7, 7),
+	[F_LVL0_ALARM]	= REG_FIELD(STATUS, 0, 0),
+	[F_LVL1_ALARM]	= REG_FIELD(STATUS, 1, 1),
+	[F_LVL2_ALARM]	= REG_FIELD(STATUS, 2, 2),
+	[F_IN_L0_THR]	= REG_FIELD(VADC_L0_THR, 0, 7),
+	[F_IN_L1_THR]	= REG_FIELD(VCMP_L1_THR, 0, 5),
+	[F_IN_L2_THR]	= REG_FIELD(VCMP_L2_THR, 0, 5),
+	[F_IN_INPUT]	= REG_FIELD(VADC_DATA1, 0, 7),
+	[F_CURR_H0_THR]	= REG_FIELD(IADC_H0_THR, 0, 7),
+	[F_CURR_H1_THR]	= REG_FIELD(IADC_H1_THR_GEN3, 0, 7),
+	[F_CURR_INPUT]	= REG_FIELD(IADC_DATA1, 0, 7),
+};
+
+static const struct reg_field bcl_pm8350c_reg_fields[] = {
+	[F_V_MAJOR]	= REG_FIELD(REVISION2, 0, 7),
+	[F_V_MINOR]	= REG_FIELD(REVISION1, 0, 7),
+	[F_CTL_EN]	= REG_FIELD(EN_CTL1, 7, 7),
+	[F_LVL0_ALARM]	= REG_FIELD(STATUS, 0, 0),
+	[F_LVL1_ALARM]	= REG_FIELD(STATUS, 1, 1),
+	[F_LVL2_ALARM]	= REG_FIELD(STATUS, 2, 2),
+	[F_IN_L0_THR]	= REG_FIELD(VADC_L0_THR, 0, 7),
+	[F_IN_L1_THR]	= REG_FIELD(VCMP_L1_THR, 0, 5),
+	[F_IN_L2_THR]	= REG_FIELD(VCMP_L2_THR, 0, 5),
+};
+
+static const struct reg_field bcl_pm8550_reg_fields[] = {
+	[F_V_MAJOR]	= REG_FIELD(REVISION2, 0, 7),
+	[F_V_MINOR]	= REG_FIELD(REVISION1, 0, 7),
+	[F_CTL_EN]	= REG_FIELD(EN_CTL1, 7, 7),
+	[F_LVL0_ALARM]	= REG_FIELD(STATUS, 0, 0),
+	[F_LVL1_ALARM]	= REG_FIELD(STATUS, 1, 1),
+	[F_LVL2_ALARM]	= REG_FIELD(STATUS, 2, 2),
+	[F_IN_L0_THR]	= REG_FIELD(VCMP_L0_THR, 0, 5),
+	[F_IN_L1_THR]	= REG_FIELD(VCMP_L1_THR, 0, 5),
+	[F_IN_L2_THR]	= REG_FIELD(VCMP_L2_THR, 0, 5),
+};
+
+static const struct reg_field bcl_pmh0101_reg_fields[] = {
+	[F_V_MAJOR]	= REG_FIELD(REVISION2, 0, 7),
+	[F_V_MINOR]	= REG_FIELD(REVISION1, 0, 7),
+	[F_CTL_EN]	= REG_FIELD(EN_CTL1, 7, 7),
+	[F_LVL0_ALARM]	= REG_FIELD(STATUS, 0, 0),
+	[F_LVL1_ALARM]	= REG_FIELD(STATUS, 1, 1),
+	[F_LVL2_ALARM]	= REG_FIELD(STATUS, 2, 2),
+	[F_IN_L0_THR]	= REG_FIELD(VCMP_L0_THR, 0, 6),
+	[F_IN_L1_THR]	= REG_FIELD(VCMP_L1_THR, 0, 6),
+	[F_IN_L2_THR]	= REG_FIELD(VCMP_L2_THR, 0, 6),
+};
+
+static const struct reg_field bcl_pmih0108_reg_fields[] = {
+	[F_V_MAJOR]	= REG_FIELD(REVISION2, 0, 7),
+	[F_V_MINOR]	= REG_FIELD(REVISION1, 0, 7),
+	[F_CTL_EN]	= REG_FIELD(EN_CTL1, 7, 7),
+	[F_LVL0_ALARM]	= REG_FIELD(STATUS, 0, 0),
+	[F_LVL1_ALARM]	= REG_FIELD(STATUS, 1, 1),
+	[F_LVL2_ALARM]	= REG_FIELD(STATUS, 2, 2),
+	[F_IN_L0_THR]	= REG_FIELD(VADC_L0_THR, 0, 7),
+	[F_IN_L1_THR]	= REG_FIELD(VCMP_L1_THR, 0, 5),
+	[F_IN_L2_THR]	= REG_FIELD(VCMP_L2_THR, 0, 5),
+	[F_IN_INPUT]	= REG_FIELD(VADC_DATA1, 0, 7),
+	[F_IN_INPUT1]	= REG_FIELD(VADC_DATA1 + 1, 0, 7),
+	[F_CURR_H0_THR]	= REG_FIELD(IADC_H0_THR, 0, 7),
+	[F_CURR_H1_THR]	= REG_FIELD(IADC_H1_THR_GEN3, 0, 7),
+	[F_CURR_INPUT]	= REG_FIELD(IADC_DATA1, 0, 7),
+	[F_CURR_INPUT1]	= REG_FIELD(IADC_DATA1 + 1, 0, 7),
+};
+
+static const struct reg_field bcl_smb2360_reg_fields[] = {
+	[F_V_MAJOR]	= REG_FIELD(REVISION2, 0, 7),
+	[F_V_MINOR]	= REG_FIELD(REVISION1, 0, 7),
+	[F_CTL_EN]	= REG_FIELD(EN_CTL1, 7, 7),
+	[F_LVL0_ALARM]	= REG_FIELD(STATUS, 0, 0),
+	[F_LVL1_ALARM]	= REG_FIELD(STATUS, 1, 1),
+	[F_LVL2_ALARM]	= REG_FIELD(STATUS, 2, 2),
+	[F_IN_L0_THR]	= REG_FIELD(VADC_L0_THR, 0, 7),
+	[F_IN_L1_THR]	= REG_FIELD(VCMP_L1_THR, 0, 5),
+	[F_IN_L2_THR]	= REG_FIELD(VCMP_L2_THR, 0, 5),
+	[F_IN_INPUT]	= REG_FIELD(VADC_DATA1, 0, 7),
+	[F_CURR_H0_THR]	= REG_FIELD(IADC_H0_THR, 0, 7),
+	[F_CURR_H1_THR]	= REG_FIELD(IADC_H1_THR_GEN3, 0, 7),
+	[F_CURR_INPUT]	= REG_FIELD(IADC_DATA1, 0, 7),
+};
+
+static const struct reg_field bcl_smb2370_reg_fields[] = {
+	[F_V_MAJOR]	= REG_FIELD(REVISION2, 0, 7),
+	[F_V_MINOR]	= REG_FIELD(REVISION1, 0, 7),
+	[F_CTL_EN]	= REG_FIELD(EN_CTL1, 7, 7),
+	[F_LVL0_ALARM]	= REG_FIELD(STATUS, 0, 0),
+	[F_LVL1_ALARM]	= REG_FIELD(STATUS, 1, 1),
+	[F_LVL2_ALARM]	= REG_FIELD(STATUS, 2, 2),
+	[F_IN_L0_THR]	= REG_FIELD(VADC_L0_THR, 0, 7),
+	[F_IN_L1_THR]	= REG_FIELD(VCMP_L1_THR, 0, 5),
+	[F_IN_L2_THR]	= REG_FIELD(VCMP_L2_THR, 0, 5),
+	[F_IN_INPUT]	= REG_FIELD(VADC_DATA1, 0, 7),
+	[F_IN_INPUT1]	= REG_FIELD(VADC_DATA1 + 1, 0, 7),
+	[F_CURR_H0_THR]	= REG_FIELD(IADC_H0_THR, 0, 7),
+	[F_CURR_H1_THR]	= REG_FIELD(IADC_H1_THR_GEN3, 0, 7),
+	[F_CURR_INPUT]	= REG_FIELD(IADC_DATA1, 0, 7),
+	[F_CURR_INPUT1]	= REG_FIELD(IADC_DATA1 + 1, 0, 7),
+};
+
+static const struct bcl_desc pm7250b_data = {
+	.reg_fields = bcl_pm7250b_reg_fields,
+	.num_reg_fields = F_CURR_INPUT + 1,
+	.data_field_bits_size = 8,
+	.thresh_field_bits_size = 7,
+	.battery_config_field = REG_FIELD(0, 0, 0),
+	.in_mon_enabled = true,
+	.in_input_enabled = true,
+	.curr_mon_enabled = true,
+	.channel_cfg[BCL_BATT_1S][CHANNEL_IN] = {
+		.base_mu = 2250,
+		.max_mu = 3600,
+		.step_mu = 25,
+		.default_scale_nu = 194637,
+		.thresh_type = {THRESH_TYPE_ADC, THRESH_TYPE_INDEX, THRESH_TYPE_INDEX},
+	},
+	.channel_cfg[BCL_BATT_1S][CHANNEL_CURR] = {
+		.max_mu = 9918,
+		.default_scale_nu = 305180,
+		.thresh_type = {THRESH_TYPE_ADC, THRESH_TYPE_ADC},
+	},
+};
+
+static const struct bcl_desc pm8350c_data = {
+	.reg_fields = bcl_pm8350c_reg_fields,
+	.num_reg_fields = F_IN_L2_THR + 1,
+	.data_field_bits_size = 0,
+	.thresh_field_bits_size = 8,
+	.battery_config_field = REG_FIELD(0, 0, 0),
+	.in_mon_enabled = true,
+	.in_input_enabled = false,
+	.curr_mon_enabled = false,
+	.channel_cfg[BCL_BATT_1S][CHANNEL_IN] = {
+		.base_mu = 2250,
+		.max_mu = 3600,
+		.step_mu = 25,
+		.default_scale_nu = 194637,
+		.thresh_type = {THRESH_TYPE_ADC, THRESH_TYPE_INDEX, THRESH_TYPE_INDEX},
+	},
+};
+
+static const struct bcl_desc pm7550ba_data = {
+	.reg_fields = bcl_pm7550ba_reg_fields,
+	.num_reg_fields = F_CURR_INPUT + 1,
+	.data_field_bits_size = 8,
+	.thresh_field_bits_size = 8,
+	.battery_config_field = REG_FIELD(0, 0, 0),
+	.in_mon_enabled = true,
+	.in_input_enabled = true,
+	.curr_mon_enabled = true,
+	.channel_cfg[BCL_BATT_1S][CHANNEL_IN] = {
+		.base_mu = 2250,
+		.max_mu = 3600,
+		.step_mu = 25,
+		.default_scale_nu = 194637,
+		.thresh_type = {THRESH_TYPE_ADC, THRESH_TYPE_INDEX, THRESH_TYPE_INDEX},
+	},
+	.channel_cfg[BCL_BATT_1S][CHANNEL_CURR] = {
+		.max_mu = 11901,
+		.default_scale_nu = 366220,
+		.thresh_type = {THRESH_TYPE_ADC, THRESH_TYPE_ADC},
+	},
+};
+
+static const struct bcl_desc pm8550_data = {
+	.reg_fields = bcl_pm8550_reg_fields,
+	.num_reg_fields = F_IN_L2_THR + 1,
+	.data_field_bits_size = 0,
+	.thresh_field_bits_size = 6,
+	.battery_config_field = REG_FIELD(0, 0, 0),
+	.in_mon_enabled = true,
+	.in_input_enabled = false,
+	.curr_mon_enabled = false,
+	.channel_cfg[BCL_BATT_1S][CHANNEL_IN] = {
+		.base_mu = 2250,
+		.max_mu = 3600,
+		.step_mu = 25,
+		.thresh_type = {THRESH_TYPE_INDEX, THRESH_TYPE_INDEX, THRESH_TYPE_INDEX},
+	},
+};
+
+static const struct bcl_desc pmih0108_data = {
+	.reg_fields = bcl_pmih0108_reg_fields,
+	.num_reg_fields = F_MAX_FIELDS,
+	.data_field_bits_size = 16,
+	.thresh_field_bits_size = 8,
+	.battery_config_field = REG_FIELD(0, 0, 0),
+	.in_mon_enabled = true,
+	.in_input_enabled = true,
+	.curr_mon_enabled = true,
+	.channel_cfg[BCL_BATT_1S][CHANNEL_IN] = {
+		.base_mu = 2250,
+		.max_mu = 3600,
+		.step_mu = 25,
+		.default_scale_nu = 194637,
+		.thresh_type = {THRESH_TYPE_ADC, THRESH_TYPE_INDEX, THRESH_TYPE_INDEX},
+	},
+	.channel_cfg[BCL_BATT_1S][CHANNEL_CURR] = {
+		.max_mu = 19836,
+		.default_scale_nu = 610370,
+		.thresh_type = {THRESH_TYPE_ADC, THRESH_TYPE_ADC},
+	},
+};
+
+static const struct bcl_desc pmh0101_data = {
+	.reg_fields = bcl_pmh0101_reg_fields,
+	.num_reg_fields = F_IN_L2_THR + 1,
+	.thresh_field_bits_size = 7,
+	.battery_config_field = REG_FIELD(0, 0, 0),
+	.in_mon_enabled = true,
+	.in_input_enabled = false,
+	.curr_mon_enabled = false,
+	.channel_cfg[BCL_BATT_1S][CHANNEL_IN] = {
+		.base_mu = 1500,
+		.max_mu = 4000,
+		.step_mu = 25,
+		.thresh_type = {THRESH_TYPE_INDEX, THRESH_TYPE_INDEX, THRESH_TYPE_INDEX},
+	},
+};
+
+/* Register 0x2a50 mapping: 0 -> 2S, 1 -> 3S */
+static const struct bcl_desc smb2360_data = {
+	.reg_fields = bcl_smb2360_reg_fields,
+	.num_reg_fields = F_CURR_INPUT + 1,
+	.data_field_bits_size = 8,
+	.thresh_field_bits_size = 8,
+	.battery_config_field = REG_FIELD(0x2a50, 0, 1),
+	.in_mon_enabled = true,
+	.in_input_enabled = true,
+	.curr_mon_enabled = true,
+	.channel_cfg[BCL_BATT_2S][CHANNEL_IN] = {
+		.base_mu = 4500,
+		.max_mu = 8400,
+		.step_mu = 50,
+		.default_scale_nu = 432918,
+		.thresh_type = {THRESH_TYPE_ADC, THRESH_TYPE_INDEX, THRESH_TYPE_INDEX},
+	},
+	.channel_cfg[BCL_BATT_2S][CHANNEL_CURR] = {
+		.max_mu = 17575,
+		.default_scale_nu = 540679,
+		.thresh_type = {THRESH_TYPE_ADC, THRESH_TYPE_ADC},
+	},
+	.channel_cfg[BCL_BATT_3S][CHANNEL_IN] = {
+		.base_mu = 6750,
+		.max_mu = 12600,
+		.step_mu = 75,
+		.default_scale_nu = 648790,
+		.thresh_type = {THRESH_TYPE_ADC, THRESH_TYPE_INDEX, THRESH_TYPE_INDEX},
+	},
+	.channel_cfg[BCL_BATT_3S][CHANNEL_CURR] = {
+		.max_mu = 17575,
+		.default_scale_nu = 540679,
+		.thresh_type = {THRESH_TYPE_ADC, THRESH_TYPE_ADC},
+	},
+};
+
+static const struct bcl_desc smb2370_data = {
+	.reg_fields = bcl_smb2370_reg_fields,
+	.num_reg_fields = F_MAX_FIELDS,
+	.data_field_bits_size = 16,
+	.thresh_field_bits_size = 8,
+	.battery_config_field = REG_FIELD(0x2a50, 0, 1),
+	.in_mon_enabled = true,
+	.in_input_enabled = true,
+	.curr_mon_enabled = true,
+	.channel_cfg[BCL_BATT_2S][CHANNEL_IN] = {
+		.base_mu = 4500,
+		.max_mu = 8400,
+		.step_mu = 50,
+		.default_scale_nu = 432918,
+		.thresh_type = {THRESH_TYPE_ADC, THRESH_TYPE_INDEX, THRESH_TYPE_INDEX},
+	},
+	.channel_cfg[BCL_BATT_2S][CHANNEL_CURR] = {
+		.max_mu = 46852,
+		.default_scale_nu = 1441603,
+		.thresh_type = {THRESH_TYPE_ADC, THRESH_TYPE_ADC},
+	},
+	.channel_cfg[BCL_BATT_3S][CHANNEL_IN] = {
+		.base_mu = 6750,
+		.max_mu = 12600,
+		.step_mu = 75,
+		.default_scale_nu = 648790,
+		.thresh_type = {THRESH_TYPE_ADC, THRESH_TYPE_INDEX, THRESH_TYPE_INDEX},
+	},
+	.channel_cfg[BCL_BATT_3S][CHANNEL_CURR] = {
+		.max_mu = 46852,
+		.default_scale_nu = 1441603,
+		.thresh_type = {THRESH_TYPE_ADC, THRESH_TYPE_ADC},
+	},
+};
+
+/**
+ * bcl_convert_raw_to_milliunit - Convert raw value to milli unit
+ * @bcl: BCL device structure
+ * @raw_val: Raw ADC value from hardware (signed for current, unsigned for voltage)
+ * @type: type of the channel, in or curr
+ * @field_width: bits size for data or threshold field
+ *
+ * Return: value in milli unit
+ */
+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_s64((s64)raw_val * scaling_factor + 500000, 1000000);
+}
+
+/**
+ * bcl_convert_milliunit_to_raw - Convert milli unit to raw value
+ * @bcl: BCL device structure
+ * @mval: threshold value in milli unit
+ * @type: type of the channel, in or curr
+ * @field_width: bits size for data or threshold field
+ *
+ * Return: Raw ADC value for hardware
+ */
+static unsigned int bcl_convert_milliunit_to_raw(const struct bcl_device *bcl,
+						 int mval,
+						 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_ULL((u64)mval * 1000000, scaling_factor);
+}
+
+/**
+ * bcl_convert_milliunit_to_index - Convert milliunit to in or curr index
+ * @bcl: BCL device structure
+ * @val: in or curr value in milli unit
+ * @type: type of the channel, in or curr
+ *
+ * Converts a value in milli unit to an index for BCL that use indexed thresholds.
+ *
+ * Return: Index value
+ */
+static unsigned int bcl_convert_milliunit_to_index(const struct bcl_device *bcl,
+						   int val,
+						   enum bcl_channel type)
+{
+	const struct bcl_desc *desc = bcl->desc;
+	const struct bcl_channel_cfg *cfg = &desc->channel_cfg[bcl->batt_config][type];
+	u64 diff = (u64)val - cfg->base_mu;
+
+	return DIV_ROUND_CLOSEST_ULL(diff, cfg->step_mu);
+}
+
+/**
+ * bcl_convert_index_to_milliunit - Convert in or curr index to milli unit
+ * @bcl: BCL device structure
+ * @val: index value
+ * @type: type of the channel, in or curr
+ *
+ * Converts an index value to milli unit for BCL that use indexed thresholds.
+ *
+ * Return: Value in millivolts or milliamps
+ */
+static unsigned int bcl_convert_index_to_milliunit(const struct bcl_device *bcl,
+						   int val,
+						   enum bcl_channel type)
+{
+	const struct bcl_desc *desc = bcl->desc;
+	const struct bcl_channel_cfg *cfg = &desc->channel_cfg[bcl->batt_config][type];
+
+	return cfg->base_mu + val * cfg->step_mu;
+}
+
+static int bcl_validate_threshold_fits(const struct bcl_device *bcl,
+				       const struct reg_field *reg_field,
+				       u32 raw_val,
+				       long thresh,
+				       const char *unit)
+{
+	unsigned int field_width;
+	unsigned int field_mask;
+
+	if (WARN_ON(reg_field->msb < reg_field->lsb))
+		return -EINVAL;
+
+	field_width = reg_field->msb - reg_field->lsb + 1;
+	field_mask = GENMASK(field_width - 1, 0);
+
+	if (raw_val > field_mask) {
+		dev_err(bcl->dev,
+			"Threshold value %ld %s (raw: %u) exceeds field capacity (max: %u)\n",
+			thresh, unit, raw_val, field_mask);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int bcl_in_thresh_write(struct bcl_device *bcl, long value, enum bcl_limit_alarm lvl)
+{
+	const struct bcl_desc *desc = bcl->desc;
+	struct regmap_field *field = bcl->fields[F_IN_L0_THR + lvl];
+	u32 raw_val;
+	int ret;
+
+	int thresh = clamp_val(value, desc->channel_cfg[bcl->batt_config][CHANNEL_IN].base_mu,
+			       desc->channel_cfg[bcl->batt_config][CHANNEL_IN].max_mu);
+
+	if (desc->channel_cfg[bcl->batt_config][CHANNEL_IN].thresh_type[lvl] == THRESH_TYPE_ADC)
+		raw_val = bcl_convert_milliunit_to_raw(bcl, thresh, CHANNEL_IN,
+						       desc->thresh_field_bits_size);
+	else
+		raw_val = bcl_convert_milliunit_to_index(bcl, thresh, CHANNEL_IN);
+
+	ret = bcl_validate_threshold_fits(bcl, &desc->reg_fields[F_IN_L0_THR + lvl],
+					  raw_val, thresh, "mV");
+	if (ret)
+		return ret;
+
+	return regmap_field_write(field, raw_val);
+}
+
+static int bcl_curr_thresh_write(struct bcl_device *bcl, long value, enum bcl_limit_alarm lvl)
+{
+	const struct bcl_desc *desc = bcl->desc;
+	struct regmap_field *field = bcl->fields[F_CURR_H0_THR + lvl];
+	u32 raw_val;
+	int ret;
+
+	int thresh = clamp_val(value, 0, desc->channel_cfg[bcl->batt_config][CHANNEL_CURR].max_mu);
+
+	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);
+
+	ret = bcl_validate_threshold_fits(bcl, &desc->reg_fields[F_CURR_H0_THR + lvl],
+					  raw_val, thresh, "mA");
+	if (ret)
+		return ret;
+
+	return regmap_field_write(field, raw_val);
+}
+
+static int bcl_in_thresh_read(struct bcl_device *bcl, enum bcl_limit_alarm lvl, long *out)
+{
+	int ret, thresh;
+	u32 raw_val = 0;
+	const struct bcl_desc *desc = bcl->desc;
+
+	ret = regmap_field_read(bcl->fields[F_IN_L0_THR + lvl], &raw_val);
+	if (ret)
+		return ret;
+
+	if (desc->channel_cfg[bcl->batt_config][CHANNEL_IN].thresh_type[lvl] == THRESH_TYPE_ADC)
+		thresh = bcl_convert_raw_to_milliunit(bcl, raw_val, CHANNEL_IN,
+						      desc->thresh_field_bits_size);
+	else
+		thresh = bcl_convert_index_to_milliunit(bcl, raw_val, CHANNEL_IN);
+
+	*out = thresh;
+
+	return 0;
+}
+
+static int bcl_curr_thresh_read(struct bcl_device *bcl, enum bcl_limit_alarm lvl, long *out)
+{
+	int ret, thresh;
+	u32 raw_val = 0;
+	const struct bcl_desc *desc = bcl->desc;
+
+	ret = regmap_field_read(bcl->fields[F_CURR_H0_THR + lvl], &raw_val);
+	if (ret)
+		return ret;
+
+	if (desc->channel_cfg[bcl->batt_config][CHANNEL_CURR].thresh_type[lvl] == THRESH_TYPE_ADC)
+		thresh = bcl_convert_raw_to_milliunit(bcl, raw_val, CHANNEL_CURR,
+						      desc->thresh_field_bits_size);
+	else
+		thresh = bcl_convert_index_to_milliunit(bcl, raw_val, CHANNEL_CURR);
+
+	*out = thresh;
+
+	return 0;
+}
+
+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 (bcl->last_curr_updated &&
+	    time_before(jiffies, bcl->last_curr_updated + HZ)) {
+		*out = bcl->last_curr_input;
+		return 0;
+	}
+
+	ret = regmap_field_read(bcl->fields[F_CURR_INPUT], &raw_val);
+	if (ret)
+		return ret;
+
+	/* For 16-bit data, read MSB and combine with LSB */
+	if (desc->data_field_bits_size == 16) {
+		ret = regmap_field_read(bcl->fields[F_CURR_INPUT1], &msb);
+		if (ret)
+			return ret;
+		raw_val |= FIELD_PREP(GENMASK(15, 8), msb);
+	}
+
+	/*
+	 * Current ADC reading is in 2's complement form.
+	 * Sign extend the value based on data field bit size.
+	 */
+	signed_val = sign_extend32(raw_val, desc->data_field_bits_size - 1);
+
+	bcl->last_curr_input =
+		bcl_convert_raw_to_milliunit(bcl, signed_val, CHANNEL_CURR,
+					     desc->data_field_bits_size);
+	bcl->last_curr_updated = jiffies;
+
+	*out = bcl->last_curr_input;
+
+	return 0;
+}
+
+static int bcl_in_input_read(struct bcl_device *bcl, long *out)
+{
+	int ret;
+	u32 raw_val = 0, msb = 0;
+	const struct bcl_desc *desc = bcl->desc;
+
+	/* Return cached value if read too soon after last update */
+	if (bcl->last_in_updated &&
+	    time_before(jiffies, bcl->last_in_updated + HZ)) {
+		*out = bcl->last_in_input;
+		return 0;
+	}
+
+	ret = regmap_field_read(bcl->fields[F_IN_INPUT], &raw_val);
+	if (ret)
+		return ret;
+
+	/* For 16-bit data, read MSB and combine with LSB */
+	if (desc->data_field_bits_size == 16) {
+		ret = regmap_field_read(bcl->fields[F_IN_INPUT1], &msb);
+		if (ret)
+			return ret;
+		raw_val |= FIELD_PREP(GENMASK(15, 8), msb);
+	}
+
+	bcl->last_in_input =
+		bcl_convert_raw_to_milliunit(bcl, raw_val, CHANNEL_IN,
+					     desc->data_field_bits_size);
+	bcl->last_in_updated = jiffies;
+
+	*out = bcl->last_in_input;
+
+	return 0;
+}
+
+static int bcl_read_alarm_status(struct bcl_device *bcl,
+				 enum bcl_limit_alarm lvl, long *status)
+{
+	int ret;
+	u32 raw_val = 0;
+
+	ret = regmap_field_read(bcl->fields[F_LVL0_ALARM + lvl], &raw_val);
+	if (ret)
+		return ret;
+
+	*status = raw_val;
+
+	return 0;
+}
+
+static unsigned int bcl_get_version_major(const struct bcl_device *bcl)
+{
+	u32 raw_val = 0;
+
+	regmap_field_read(bcl->fields[F_V_MAJOR], &raw_val);
+
+	return raw_val;
+}
+
+static unsigned int bcl_get_version_minor(const struct bcl_device *bcl)
+{
+	u32 raw_val = 0;
+
+	regmap_field_read(bcl->fields[F_V_MINOR], &raw_val);
+
+	return raw_val;
+}
+
+static void bcl_hwmon_notify_event(struct bcl_device *bcl, enum bcl_limit_alarm alarm)
+{
+	if (bcl->desc->in_mon_enabled)
+		hwmon_notify_event(bcl->hwmon_dev, hwmon_in,
+				   in_lvl_to_attr_map[alarm], 0);
+
+	if (bcl->desc->curr_mon_enabled)
+		hwmon_notify_event(bcl->hwmon_dev, hwmon_curr,
+				   curr_lvl_to_attr_map[alarm], 0);
+}
+
+static void bcl_alarm_enable_poll(struct work_struct *work)
+{
+	struct bcl_alarm_data *alarm = container_of(work, struct bcl_alarm_data,
+							 alarm_poll_work.work);
+	struct bcl_device *bcl = (struct bcl_device *)alarm->device;
+	long status;
+	int ret;
+
+	scoped_guard(mutex, &bcl->lock)
+		ret = bcl_read_alarm_status(bcl, alarm->type, &status);
+
+	/* If read failed or shutting down, reschedule */
+	if (ret || READ_ONCE(alarm->shutting_down)) {
+		if (!READ_ONCE(alarm->shutting_down))
+			schedule_delayed_work(&alarm->alarm_poll_work,
+					      msecs_to_jiffies(BCL_ALARM_POLLING_MS));
+		return;
+	}
+
+	/* Check if alarm cleared and IRQ needs re-enabling */
+	scoped_guard(mutex, &alarm->a_lock) {
+		if (alarm->shutting_down)
+			return;
+
+		if (!status && !alarm->irq_enabled) {
+			alarm->irq_enabled = true;
+			enable_irq(alarm->irq);
+
+			if (!alarm->irq_wake_enabled && !enable_irq_wake(alarm->irq))
+				alarm->irq_wake_enabled = true;
+
+			bcl_hwmon_notify_event(bcl, alarm->type);
+			return;
+		}
+	}
+
+	/* Alarm still active, reschedule polling */
+	if (!READ_ONCE(alarm->shutting_down))
+		schedule_delayed_work(&alarm->alarm_poll_work,
+				      msecs_to_jiffies(BCL_ALARM_POLLING_MS));
+}
+
+static irqreturn_t bcl_handle_alarm(int irq, void *data)
+{
+	struct bcl_alarm_data *alarm = data;
+	struct bcl_device *bcl = (struct bcl_device *)alarm->device;
+	long status;
+
+	if (READ_ONCE(alarm->shutting_down))
+		return IRQ_HANDLED;
+
+	guard(mutex)(&bcl->lock);
+
+	if (bcl_read_alarm_status(bcl, alarm->type, &status) || !status)
+		return IRQ_HANDLED;
+
+	bcl_hwmon_notify_event(bcl, alarm->type);
+
+	guard(mutex)(&alarm->a_lock);
+	if (alarm->shutting_down)
+		return IRQ_HANDLED;
+
+	if (alarm->irq_enabled) {
+		alarm->irq_enabled = false;
+		disable_irq_nosync(alarm->irq);
+	}
+
+	if (alarm->irq_wake_enabled) {
+		disable_irq_wake(alarm->irq);
+		alarm->irq_wake_enabled = false;
+	}
+
+	schedule_delayed_work(&alarm->alarm_poll_work,
+			      msecs_to_jiffies(BCL_ALARM_POLLING_MS));
+
+	return IRQ_HANDLED;
+}
+
+static umode_t bcl_hwmon_is_visible(const void *data,
+				    enum hwmon_sensor_types type,
+				    u32 attr, int channel)
+{
+	const struct bcl_device *bcl = data;
+
+	switch (type) {
+	case hwmon_in:
+		if (!bcl->desc->in_mon_enabled)
+			return 0;
+
+		switch (attr) {
+		case hwmon_in_input:
+			return bcl->desc->in_input_enabled ? 0444 : 0;
+		case hwmon_in_min_alarm:
+		case hwmon_in_lcrit_alarm:
+		case hwmon_in_lemergency_alarm:
+			return 0444;
+		case hwmon_in_min:
+		case hwmon_in_lcrit:
+		case hwmon_in_lemergency:
+			return 0644;
+		default:
+			return 0;
+		}
+	case hwmon_curr:
+		if (!bcl->desc->curr_mon_enabled)
+			return 0;
+
+		switch (attr) {
+		case hwmon_curr_input:
+		case hwmon_curr_max_alarm:
+		case hwmon_curr_crit_alarm:
+		case hwmon_curr_emergency_alarm:
+			return 0444;
+		case hwmon_curr_max:
+		case hwmon_curr_crit:
+			return 0644;
+		default:
+			return 0;
+		}
+	default:
+		return 0;
+	}
+}
+
+static int bcl_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
+			   u32 attr, int channel, long val)
+{
+	struct bcl_device *bcl = dev_get_drvdata(dev);
+
+	guard(mutex)(&bcl->lock);
+
+	switch (type) {
+	case hwmon_in:
+		switch (attr) {
+		case hwmon_in_min:
+		case hwmon_in_lcrit:
+		case hwmon_in_lemergency:
+			return bcl_in_thresh_write(bcl, val, in_attr_to_lvl_map[attr]);
+		default:
+			return -EOPNOTSUPP;
+		}
+	case hwmon_curr:
+		switch (attr) {
+		case hwmon_curr_max:
+		case hwmon_curr_crit:
+			return bcl_curr_thresh_write(bcl, val, curr_attr_to_lvl_map[attr]);
+		default:
+			return -EOPNOTSUPP;
+		}
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int bcl_in_read(struct bcl_device *bcl, u32 attr, long *value)
+{
+	guard(mutex)(&bcl->lock);
+
+	switch (attr) {
+	case hwmon_in_input:
+		return bcl_in_input_read(bcl, value);
+	case hwmon_in_min:
+	case hwmon_in_lcrit:
+	case hwmon_in_lemergency:
+		return bcl_in_thresh_read(bcl, in_attr_to_lvl_map[attr], value);
+	case hwmon_in_min_alarm:
+	case hwmon_in_lcrit_alarm:
+	case hwmon_in_lemergency_alarm:
+		return bcl_read_alarm_status(bcl, in_attr_to_lvl_map[attr], value);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int bcl_curr_read(struct bcl_device *bcl, u32 attr, long *value)
+{
+	guard(mutex)(&bcl->lock);
+
+	switch (attr) {
+	case hwmon_curr_input:
+		return bcl_curr_input_read(bcl, value);
+	case hwmon_curr_max:
+	case hwmon_curr_crit:
+		return bcl_curr_thresh_read(bcl, curr_attr_to_lvl_map[attr], value);
+	case hwmon_curr_max_alarm:
+	case hwmon_curr_crit_alarm:
+	case hwmon_curr_emergency_alarm:
+		return bcl_read_alarm_status(bcl, curr_attr_to_lvl_map[attr], value);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int bcl_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
+			  u32 attr, int channel, long *value)
+{
+	struct bcl_device *bcl = dev_get_drvdata(dev);
+
+	switch (type) {
+	case hwmon_in:
+		return bcl_in_read(bcl, attr, value);
+	case hwmon_curr:
+		return bcl_curr_read(bcl, attr, value);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static const struct hwmon_ops bcl_hwmon_ops = {
+	.is_visible	= bcl_hwmon_is_visible,
+	.read		= bcl_hwmon_read,
+	.write		= bcl_hwmon_write,
+};
+
+static const struct hwmon_channel_info * const bcl_hwmon_info[] = {
+	HWMON_CHANNEL_INFO(in,
+			   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_LCRIT |
+			   HWMON_I_LEMERGENCY |
+			   HWMON_I_MIN_ALARM | HWMON_I_LCRIT_ALARM |
+			   HWMON_I_LEMERGENCY_ALARM),
+	HWMON_CHANNEL_INFO(curr,
+			   HWMON_C_INPUT | HWMON_C_MAX | HWMON_C_CRIT |
+			   HWMON_C_MAX_ALARM | HWMON_C_CRIT_ALARM |
+			   HWMON_C_EMERGENCY_ALARM),
+	NULL
+};
+
+static const struct hwmon_chip_info bcl_chip_info = {
+	.ops = &bcl_hwmon_ops,
+	.info = bcl_hwmon_info,
+};
+
+static int bcl_detect_battery_config(struct bcl_device *bcl)
+{
+	u32 reg_val = 0;
+	int ret;
+
+	ret = regmap_field_read(bcl->batt_config_regfield, &reg_val);
+	if (ret) {
+		dev_err(bcl->dev, "Failed to read battery config register: %d\n", ret);
+		return ret;
+	}
+
+	/*
+	 * Map register value to battery configuration.
+	 * As per hardware documentation:
+	 * 0 -> 2S, 1 -> 3S, 2 -> 4S (unsupported)
+	 */
+	switch (reg_val) {
+	case 0:
+		bcl->batt_config = BCL_BATT_2S;
+		return 0;
+	case 1:
+		bcl->batt_config = BCL_BATT_3S;
+		return 0;
+	default:
+		dev_err(bcl->dev, "Unsupported battery configuration: 0x%x\n",
+			reg_val);
+		return -EINVAL;
+	}
+}
+
+static int bcl_update_scaling_factors(struct bcl_device *bcl)
+{
+	const struct bcl_desc *desc = bcl->desc;
+	int ret;
+
+	/* Check if battery detection is supported */
+	if (desc->battery_config_field.reg == 0) {
+		/* No battery detection - use BCL_BATT_1S */
+		bcl->batt_config = BCL_BATT_1S;
+		dev_dbg(bcl->dev, "Using default 1S battery configuration\n");
+		return 0;
+	}
+
+	bcl->batt_config_regfield = devm_regmap_field_alloc(bcl->dev,
+							    bcl->regmap,
+							    desc->battery_config_field);
+	if (IS_ERR(bcl->batt_config_regfield)) {
+		dev_err(bcl->dev, "Failed to allocate battery config regmap field\n");
+		return PTR_ERR(bcl->batt_config_regfield);
+	}
+
+	ret = bcl_detect_battery_config(bcl);
+	if (ret < 0)
+		return ret;
+
+	dev_dbg(bcl->dev,
+		"%dS battery: BASE=%u mV,MAX=%u mV,STEP=%u mV,V_SCALE=%u nV, I_SCALE=%u nA\n",
+		bcl->batt_config + 1,
+		desc->channel_cfg[bcl->batt_config][CHANNEL_IN].base_mu,
+		desc->channel_cfg[bcl->batt_config][CHANNEL_IN].max_mu,
+		desc->channel_cfg[bcl->batt_config][CHANNEL_IN].step_mu,
+		desc->channel_cfg[bcl->batt_config][CHANNEL_IN].default_scale_nu,
+		desc->channel_cfg[bcl->batt_config][CHANNEL_CURR].default_scale_nu);
+
+	return 0;
+}
+
+static void bcl_alarm_work_cleanup_action(void *data)
+{
+	struct bcl_alarm_data *alarm = data;
+
+	/* Set shutting_down flag to prevent work from being rescheduled */
+	scoped_guard(mutex, &alarm->a_lock)
+		WRITE_ONCE(alarm->shutting_down, true);
+
+	cancel_delayed_work_sync(&alarm->alarm_poll_work);
+}
+
+static void bcl_alarm_wake_cleanup_action(void *data)
+{
+	struct bcl_alarm_data *alarm = data;
+
+	guard(mutex)(&alarm->a_lock);
+	if (alarm->irq_wake_enabled) {
+		disable_irq_wake(alarm->irq);
+		alarm->irq_wake_enabled = false;
+	}
+}
+
+static int bcl_alarm_irq_init(struct platform_device *pdev,
+			      struct bcl_device *bcl)
+{
+	int ret, irq_num, i;
+	struct bcl_alarm_data *alarm;
+
+	for (i = 0; i < ARRAY_SIZE(bcl->bcl_alarms); i++) {
+		alarm = &bcl->bcl_alarms[i];
+		alarm->type = i;
+		alarm->device = bcl;
+		ret = devm_mutex_init(bcl->dev, &alarm->a_lock);
+		if (ret)
+			return ret;
+
+		/* Initialize work before IRQ request */
+		INIT_DELAYED_WORK(&alarm->alarm_poll_work, bcl_alarm_enable_poll);
+
+		irq_num = platform_get_irq_byname(pdev, bcl_int_names[i]);
+		if (irq_num < 0)
+			return irq_num;
+
+		alarm->irq = irq_num;
+		alarm->irq_enabled = true;
+
+		ret = devm_request_threaded_irq(&pdev->dev, irq_num, NULL,
+						bcl_handle_alarm, IRQF_ONESHOT,
+						bcl_int_names[i], 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;
+
+		ret = devm_add_action_or_reset(&pdev->dev, bcl_alarm_work_cleanup_action,
+					       alarm);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int bcl_regmap_field_init(struct device *dev, struct bcl_device *bcl,
+				 const struct bcl_desc *data)
+{
+	int i;
+
+	/*
+	 * Note: We use a mutable local copy of struct reg_field (not const)
+	 * because we need to modify the .reg field to add the BCL base offset.
+	 */
+	for (i = 0; i < data->num_reg_fields; i++) {
+		struct reg_field field = data->reg_fields[i];
+
+		/* Skip uninitialized fields */
+		if (field.reg == 0 && field.lsb == 0 && field.msb == 0)
+			continue;
+
+		field.reg += bcl->base;
+
+		bcl->fields[i] = devm_regmap_field_alloc(dev, bcl->regmap, field);
+		if (IS_ERR(bcl->fields[i]))
+			return PTR_ERR(bcl->fields[i]);
+	}
+
+	return 0;
+}
+
+static int bcl_probe(struct platform_device *pdev)
+{
+	struct bcl_device *bcl;
+	int ret;
+	u32 reg;
+
+	bcl = devm_kzalloc(&pdev->dev, sizeof(*bcl), GFP_KERNEL);
+	if (!bcl)
+		return -ENOMEM;
+
+	bcl->dev = &pdev->dev;
+	bcl->desc = device_get_match_data(&pdev->dev);
+	if (!bcl->desc)
+		return dev_err_probe(&pdev->dev, -EINVAL, "Failed to get device match data\n");
+
+	ret = devm_mutex_init(bcl->dev, &bcl->lock);
+	if (ret)
+		return ret;
+
+	bcl->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!bcl->regmap)
+		return dev_err_probe(&pdev->dev, -EINVAL, "Couldn't get parent's regmap\n");
+
+	ret = device_property_read_u32(&pdev->dev, "reg", &reg);
+	if (ret < 0)
+		return dev_err_probe(&pdev->dev, ret, "Failed to read 'reg' property\n");
+
+	bcl->base = reg;
+
+	ret = bcl_regmap_field_init(bcl->dev, bcl, bcl->desc);
+	if (ret < 0)
+		return dev_err_probe(&pdev->dev, ret, "Unable to allocate regmap fields\n");
+
+	ret = regmap_field_read(bcl->fields[F_CTL_EN], &reg);
+	if (ret < 0)
+		return dev_err_probe(&pdev->dev, ret, "Failed to read BCL enable status\n");
+
+	if (!reg)
+		return dev_err_probe(&pdev->dev, -ENODEV, "BCL is not enabled by bootloader\n");
+
+	ret = bcl_update_scaling_factors(bcl);
+	if (ret < 0)
+		return dev_err_probe(&pdev->dev, ret, "Failed to update scaling factors\n");
+
+	dev_set_drvdata(&pdev->dev, bcl);
+
+	bcl->hwmon_name = devm_hwmon_sanitize_name(&pdev->dev,
+						   dev_name(bcl->dev));
+	if (IS_ERR(bcl->hwmon_name))
+		return PTR_ERR(bcl->hwmon_name);
+
+	bcl->hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev,
+							      bcl->hwmon_name,
+							      bcl,
+							      &bcl_chip_info,
+							      NULL);
+	if (IS_ERR(bcl->hwmon_dev))
+		return dev_err_probe(&pdev->dev, PTR_ERR(bcl->hwmon_dev),
+				     "Failed to register hwmon device\n");
+
+	ret = bcl_alarm_irq_init(pdev, bcl);
+	if (ret < 0)
+		return dev_err_probe(&pdev->dev, ret, "Failed to initialize alarm IRQs\n");
+
+	dev_dbg(&pdev->dev, "BCL hwmon device with version: %u.%u registered\n",
+		bcl_get_version_major(bcl), bcl_get_version_minor(bcl));
+
+	return 0;
+}
+
+static const struct of_device_id bcl_match[] = {
+	{
+		.compatible = "qcom,pm7250b-bcl",
+		.data = &pm7250b_data,
+	}, {
+		.compatible = "qcom,pm7550-bcl",
+		.data = &pm8550_data,
+	}, {
+		.compatible = "qcom,pm7550ba-bcl",
+		.data = &pm7550ba_data,
+	}, {
+		.compatible = "qcom,pm8350c-bcl",
+		.data = &pm8350c_data,
+	}, {
+		.compatible = "qcom,pm8550-bcl",
+		.data = &pm8550_data,
+	}, {
+		.compatible = "qcom,pmh0101-bcl",
+		.data = &pmh0101_data,
+	}, {
+		.compatible = "qcom,pmih0108-bcl",
+		.data = &pmih0108_data,
+	}, {
+		.compatible = "qcom,smb2360-bcl",
+		.data = &smb2360_data,
+	}, {
+		.compatible = "qcom,smb2370-bcl",
+		.data = &smb2370_data,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, bcl_match);
+
+static struct platform_driver bcl_driver = {
+	.probe	= bcl_probe,
+	.driver	= {
+		.name		= "qcom-bcl-hwmon",
+		.of_match_table	= bcl_match,
+	},
+};
+
+module_platform_driver(bcl_driver);
+
+MODULE_DESCRIPTION("Qualcomm SPMI BCL HWMON driver");
+MODULE_LICENSE("GPL");

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v3 03/12] arm64: dts: qcom: hamoa-pmic: Enable BCL sensor node
  2026-09-29 13:09 [PATCH v3 00/12] hwmon: Add Qualcomm SPMI BCL driver Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:09 ` [PATCH v3 01/12] dt-bindings: hwmon: Describe Qualcomm BCL hardware Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:09 ` [PATCH v3 02/12] hwmon: Add Qualcomm PMIC BCL driver Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:09 ` Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:15   ` sashiko-bot
  2026-09-29 13:17   ` Abel Vesa
  2026-09-29 13:09 ` [PATCH v3 04/12] arm64: dts: qcom: pm7250b: " Manaf Meethalavalappu Pallikunhi
                   ` (8 subsequent siblings)
  11 siblings, 2 replies; 38+ messages in thread
From: Manaf Meethalavalappu Pallikunhi @ 2026-09-29 13:09 UTC (permalink / raw)
  To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa
  Cc: linux-hwmon, linux-arm-msm, devicetree, linux-kernel, mfd,
	Gaurav Kohli, Manaf Meethalavalappu Pallikunhi

Add Battery Current Limiting (BCL) hardware monitor node for
hamoa-pmic. The BCL monitors battery voltage and current, providing
hardware interrupts when configurable thresholds are violated.

Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/hamoa-pmics.dtsi | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/hamoa-pmics.dtsi b/arch/arm64/boot/dts/qcom/hamoa-pmics.dtsi
index 7fad4a9b92fa..6b17d568188e 100644
--- a/arch/arm64/boot/dts/qcom/hamoa-pmics.dtsi
+++ b/arch/arm64/boot/dts/qcom/hamoa-pmics.dtsi
@@ -426,6 +426,17 @@ pm8550_temp_alarm: temp-alarm@a00 {
 			io-channel-names = "thermal";
 		};
 
+		sensor@4700 {
+			compatible = "qcom,pm8550-bcl";
+			reg = <0x4700>;
+			interrupts = <0x1 0x47 0x0 IRQ_TYPE_EDGE_RISING>,
+				     <0x1 0x47 0x1 IRQ_TYPE_EDGE_RISING>,
+				     <0x1 0x47 0x2 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "max-min",
+					  "critical",
+					  "emergency";
+		};
+
 		pm8550_gpios: gpio@8800 {
 			compatible = "qcom,pm8550-gpio", "qcom,spmi-gpio";
 			reg = <0x8800>;
@@ -674,6 +685,17 @@ smb2360_0: pmic@7 {
 
 		status = "disabled";
 
+		sensor@4700 {
+			compatible = "qcom,smb2360-bcl";
+			reg = <0x4700>;
+			interrupts = <0x7 0x47 0x0 IRQ_TYPE_EDGE_RISING>,
+				     <0x7 0x47 0x1 IRQ_TYPE_EDGE_RISING>,
+				     <0x7 0x47 0x2 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "max-min",
+					  "critical",
+					  "emergency";
+		};
+
 		smb2360_0_eusb2_repeater: phy@fd00 {
 			compatible = "qcom,smb2360-eusb2-repeater";
 			reg = <0xfd00>;

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v3 04/12] arm64: dts: qcom: pm7250b: Enable BCL sensor node
  2026-09-29 13:09 [PATCH v3 00/12] hwmon: Add Qualcomm SPMI BCL driver Manaf Meethalavalappu Pallikunhi
                   ` (2 preceding siblings ...)
  2026-09-29 13:09 ` [PATCH v3 03/12] arm64: dts: qcom: hamoa-pmic: Enable BCL sensor node Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:09 ` Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:17   ` sashiko-bot
  2026-09-29 13:17   ` Abel Vesa
  2026-09-29 13:09 ` [PATCH v3 05/12] arm64: dts: qcom: pm7550-eliza: " Manaf Meethalavalappu Pallikunhi
                   ` (7 subsequent siblings)
  11 siblings, 2 replies; 38+ messages in thread
From: Manaf Meethalavalappu Pallikunhi @ 2026-09-29 13:09 UTC (permalink / raw)
  To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa
  Cc: linux-hwmon, linux-arm-msm, devicetree, linux-kernel, mfd,
	Gaurav Kohli, Manaf Meethalavalappu Pallikunhi

Add Battery Current Limiting (BCL) hardware monitor node for pm7250b
PMIC. The BCL monitors battery voltage and current, providing hardware
interrupts when configurable thresholds are violated.

Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/pm7250b.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/pm7250b.dtsi b/arch/arm64/boot/dts/qcom/pm7250b.dtsi
index 43cab07126c5..76d0481914e4 100644
--- a/arch/arm64/boot/dts/qcom/pm7250b.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm7250b.dtsi
@@ -89,6 +89,17 @@ pm7250b_typec: typec@1500 {
 			status = "disabled";
 		};
 
+		sensor@1d00 {
+			compatible = "qcom,pm7250b-bcl";
+			reg = <0x1d00>;
+			interrupts = <PM7250B_SID 0x1d 0x0 IRQ_TYPE_EDGE_RISING>,
+				     <PM7250B_SID 0x1d 0x1 IRQ_TYPE_EDGE_RISING>,
+				     <PM7250B_SID 0x1d 0x2 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "max-min",
+					  "critical",
+					  "emergency";
+		};
+
 		pm7250b_temp: temp-alarm@2400 {
 			compatible = "qcom,spmi-temp-alarm";
 			reg = <0x2400>;

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v3 05/12] arm64: dts: qcom: pm7550-eliza: Enable BCL sensor node
  2026-09-29 13:09 [PATCH v3 00/12] hwmon: Add Qualcomm SPMI BCL driver Manaf Meethalavalappu Pallikunhi
                   ` (3 preceding siblings ...)
  2026-09-29 13:09 ` [PATCH v3 04/12] arm64: dts: qcom: pm7250b: " Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:09 ` Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:18   ` Abel Vesa
  2026-09-29 13:23   ` sashiko-bot
  2026-09-29 13:09 ` [PATCH v3 06/12] arm64: dts: qcom: pm7550ba-eliza: " Manaf Meethalavalappu Pallikunhi
                   ` (6 subsequent siblings)
  11 siblings, 2 replies; 38+ messages in thread
From: Manaf Meethalavalappu Pallikunhi @ 2026-09-29 13:09 UTC (permalink / raw)
  To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa
  Cc: linux-hwmon, linux-arm-msm, devicetree, linux-kernel, mfd,
	Gaurav Kohli, Manaf Meethalavalappu Pallikunhi

Add Battery Current Limiting (BCL) hardware monitor node for
pm7550-eliza. The BCL monitors battery voltage and current, providing
hardware interrupts when configurable thresholds are violated.

Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/pm7550-eliza.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/pm7550-eliza.dtsi b/arch/arm64/boot/dts/qcom/pm7550-eliza.dtsi
index 9b907f69264b..9cc734001a68 100644
--- a/arch/arm64/boot/dts/qcom/pm7550-eliza.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm7550-eliza.dtsi
@@ -48,6 +48,17 @@ pm7550_temp_alarm: temp-alarm@a00 {
 			#thermal-sensor-cells = <0>;
 		};
 
+		sensor@4700 {
+			compatible = "qcom,pm7550-bcl";
+			reg = <0x4700>;
+			interrupts = <0x1 0x47 0x0 IRQ_TYPE_EDGE_RISING>,
+				     <0x1 0x47 0x1 IRQ_TYPE_EDGE_RISING>,
+				     <0x1 0x47 0x2 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "max-min",
+					  "critical",
+					  "emergency";
+		};
+
 		pm7550_gpios: gpio@8800 {
 			compatible = "qcom,pm7550-gpio", "qcom,spmi-gpio";
 			reg = <0x8800>;

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v3 06/12] arm64: dts: qcom: pm7550ba-eliza: Enable BCL sensor node
  2026-09-29 13:09 [PATCH v3 00/12] hwmon: Add Qualcomm SPMI BCL driver Manaf Meethalavalappu Pallikunhi
                   ` (4 preceding siblings ...)
  2026-09-29 13:09 ` [PATCH v3 05/12] arm64: dts: qcom: pm7550-eliza: " Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:09 ` Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:18   ` Abel Vesa
  2026-09-29 13:20   ` sashiko-bot
  2026-09-29 13:09 ` [PATCH v3 07/12] arm64: dts: qcom: pm8350c: " Manaf Meethalavalappu Pallikunhi
                   ` (5 subsequent siblings)
  11 siblings, 2 replies; 38+ messages in thread
From: Manaf Meethalavalappu Pallikunhi @ 2026-09-29 13:09 UTC (permalink / raw)
  To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa
  Cc: linux-hwmon, linux-arm-msm, devicetree, linux-kernel, mfd,
	Gaurav Kohli, Manaf Meethalavalappu Pallikunhi

Add Battery Current Limiting (BCL) hardware monitor node for
pm7550ba-eliza. The BCL monitors battery voltage and current, providing
hardware interrupts when configurable thresholds are violated.

Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/pm7550ba-eliza.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/pm7550ba-eliza.dtsi b/arch/arm64/boot/dts/qcom/pm7550ba-eliza.dtsi
index 18692893ca41..f0c252a386ee 100644
--- a/arch/arm64/boot/dts/qcom/pm7550ba-eliza.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm7550ba-eliza.dtsi
@@ -50,6 +50,17 @@ pm7550ba_temp_alarm: temp-alarm@a00 {
 			#thermal-sensor-cells = <0>;
 		};
 
+		sensor@4700 {
+			compatible = "qcom,pm7550ba-bcl";
+			reg = <0x4700>;
+			interrupts = <0x7 0x47 0x0 IRQ_TYPE_EDGE_RISING>,
+				     <0x7 0x47 0x1 IRQ_TYPE_EDGE_RISING>,
+				     <0x7 0x47 0x2 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "max-min",
+					  "critical",
+					  "emergency";
+		};
+
 		pm7550ba_gpios: gpio@8800 {
 			compatible = "qcom,pm7550ba-gpio", "qcom,spmi-gpio";
 			reg = <0x8800>;

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v3 07/12] arm64: dts: qcom: pm8350c: Enable BCL sensor node
  2026-09-29 13:09 [PATCH v3 00/12] hwmon: Add Qualcomm SPMI BCL driver Manaf Meethalavalappu Pallikunhi
                   ` (5 preceding siblings ...)
  2026-09-29 13:09 ` [PATCH v3 06/12] arm64: dts: qcom: pm7550ba-eliza: " Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:09 ` Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:15   ` Abel Vesa
  2026-09-29 13:22   ` sashiko-bot
  2026-09-29 13:09 ` [PATCH v3 08/12] arm64: dts: qcom: pm8550: " Manaf Meethalavalappu Pallikunhi
                   ` (4 subsequent siblings)
  11 siblings, 2 replies; 38+ messages in thread
From: Manaf Meethalavalappu Pallikunhi @ 2026-09-29 13:09 UTC (permalink / raw)
  To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa
  Cc: linux-hwmon, linux-arm-msm, devicetree, linux-kernel, mfd,
	Gaurav Kohli, Manaf Meethalavalappu Pallikunhi

Add Battery Current Limiting (BCL) hardware monitor node for pm8350c
PMIC. The BCL monitors battery voltage and current, providing hardware
interrupts when configurable thresholds are violated.

Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/pm8350c.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/pm8350c.dtsi b/arch/arm64/boot/dts/qcom/pm8350c.dtsi
index 1a24e6439e36..52b5fc1ef9a3 100644
--- a/arch/arm64/boot/dts/qcom/pm8350c.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8350c.dtsi
@@ -20,6 +20,17 @@ pm8350c_temp_alarm: temp-alarm@a00 {
 			#thermal-sensor-cells = <0>;
 		};
 
+		sensor@4700 {
+			compatible = "qcom,pm8350c-bcl";
+			reg = <0x4700>;
+			interrupts = <0x2 0x47 0x0 IRQ_TYPE_EDGE_RISING>,
+				     <0x2 0x47 0x1 IRQ_TYPE_EDGE_RISING>,
+				     <0x2 0x47 0x2 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "max-min",
+					  "critical",
+					  "emergency";
+		};
+
 		pm8350c_gpios: gpio@8800 {
 			compatible = "qcom,pm8350c-gpio", "qcom,spmi-gpio";
 			reg = <0x8800>;
@@ -41,6 +52,7 @@ pm8350c_pwm: pwm {
 			#pwm-cells = <2>;
 			status = "disabled";
 		};
+
 	};
 };
 

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v3 08/12] arm64: dts: qcom: pm8550: Enable BCL sensor node
  2026-09-29 13:09 [PATCH v3 00/12] hwmon: Add Qualcomm SPMI BCL driver Manaf Meethalavalappu Pallikunhi
                   ` (6 preceding siblings ...)
  2026-09-29 13:09 ` [PATCH v3 07/12] arm64: dts: qcom: pm8350c: " Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:09 ` Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:19   ` Abel Vesa
                     ` (2 more replies)
  2026-09-29 13:09 ` [PATCH v3 09/12] arm64: dts: qcom: pmh0101: " Manaf Meethalavalappu Pallikunhi
                   ` (3 subsequent siblings)
  11 siblings, 3 replies; 38+ messages in thread
From: Manaf Meethalavalappu Pallikunhi @ 2026-09-29 13:09 UTC (permalink / raw)
  To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa
  Cc: linux-hwmon, linux-arm-msm, devicetree, linux-kernel, mfd,
	Gaurav Kohli, Manaf Meethalavalappu Pallikunhi

Add Battery Current Limiting (BCL) hardware monitor node for pm8550
PMIC. The BCL monitors battery voltage and current, providing hardware
interrupts when configurable thresholds are violated.

Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/pm8550.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/pm8550.dtsi b/arch/arm64/boot/dts/qcom/pm8550.dtsi
index 896bcacb6490..c4a575af7bb6 100644
--- a/arch/arm64/boot/dts/qcom/pm8550.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8550.dtsi
@@ -45,6 +45,17 @@ pm8550_temp_alarm: temp-alarm@a00 {
 			#thermal-sensor-cells = <0>;
 		};
 
+		sensor@4700 {
+			compatible = "qcom,pm8550-bcl";
+			reg = <0x4700>;
+			interrupts = <0x1 0x47 0x0 IRQ_TYPE_EDGE_RISING>,
+				     <0x1 0x47 0x1 IRQ_TYPE_EDGE_RISING>,
+				     <0x1 0x47 0x2 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "max-min",
+					  "critical",
+					  "emergency";
+		};
+
 		pm8550_gpios: gpio@8800 {
 			compatible = "qcom,pm8550-gpio", "qcom,spmi-gpio";
 			reg = <0x8800>;

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v3 09/12] arm64: dts: qcom: pmh0101: Enable BCL sensor node
  2026-09-29 13:09 [PATCH v3 00/12] hwmon: Add Qualcomm SPMI BCL driver Manaf Meethalavalappu Pallikunhi
                   ` (7 preceding siblings ...)
  2026-09-29 13:09 ` [PATCH v3 08/12] arm64: dts: qcom: pm8550: " Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:09 ` Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:19   ` Abel Vesa
                     ` (2 more replies)
  2026-09-29 13:09 ` [PATCH v3 10/12] arm64: dts: qcom: pmih0108-kaanapali: " Manaf Meethalavalappu Pallikunhi
                   ` (2 subsequent siblings)
  11 siblings, 3 replies; 38+ messages in thread
From: Manaf Meethalavalappu Pallikunhi @ 2026-09-29 13:09 UTC (permalink / raw)
  To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa
  Cc: linux-hwmon, linux-arm-msm, devicetree, linux-kernel, mfd,
	Gaurav Kohli, Manaf Meethalavalappu Pallikunhi

Add Battery Current Limiting (BCL) hardware monitor node for pmh0101
PMIC. The BCL monitors battery voltage and current, providing hardware
interrupts when configurable thresholds are violated.

Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/pmh0101.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/pmh0101.dtsi b/arch/arm64/boot/dts/qcom/pmh0101.dtsi
index b1ec41325958..5635ed350f38 100644
--- a/arch/arm64/boot/dts/qcom/pmh0101.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmh0101.dtsi
@@ -43,6 +43,17 @@ pmh0101_temp_alarm: temp-alarm@a00 {
 			#thermal-sensor-cells = <0>;
 		};
 
+		sensor@4700 {
+			compatible = "qcom,pmh0101-bcl";
+			reg = <0x4700>;
+			interrupts = <0x1 0x47 0x0 IRQ_TYPE_EDGE_RISING>,
+				     <0x1 0x47 0x1 IRQ_TYPE_EDGE_RISING>,
+				     <0x1 0x47 0x2 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "max-min",
+					  "critical",
+					  "emergency";
+		};
+
 		pmh0101_gpios: gpio@8800 {
 			compatible = "qcom,pmh0101-gpio", "qcom,spmi-gpio";
 			reg = <0x8800>;

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v3 10/12] arm64: dts: qcom: pmih0108-kaanapali: Enable BCL sensor node
  2026-09-29 13:09 [PATCH v3 00/12] hwmon: Add Qualcomm SPMI BCL driver Manaf Meethalavalappu Pallikunhi
                   ` (8 preceding siblings ...)
  2026-09-29 13:09 ` [PATCH v3 09/12] arm64: dts: qcom: pmh0101: " Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:09 ` Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:20   ` Abel Vesa
  2026-09-29 13:25   ` sashiko-bot
  2026-09-29 13:09 ` [PATCH v3 11/12] arm64: dts: qcom: pmih0108: " Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:09 ` [PATCH v3 12/12] arm64: dts: qcom: smb2370: " Manaf Meethalavalappu Pallikunhi
  11 siblings, 2 replies; 38+ messages in thread
From: Manaf Meethalavalappu Pallikunhi @ 2026-09-29 13:09 UTC (permalink / raw)
  To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa
  Cc: linux-hwmon, linux-arm-msm, devicetree, linux-kernel, mfd,
	Gaurav Kohli, Manaf Meethalavalappu Pallikunhi

Add Battery Current Limiting (BCL) hardware monitor node for pmih0108
PMIC. The BCL monitors battery voltage and current, providing hardware
interrupts when configurable thresholds are violated.

Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/pmih0108-kaanapali.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/pmih0108-kaanapali.dtsi b/arch/arm64/boot/dts/qcom/pmih0108-kaanapali.dtsi
index b73b0e82c3d3..9f6bef6087cf 100644
--- a/arch/arm64/boot/dts/qcom/pmih0108-kaanapali.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmih0108-kaanapali.dtsi
@@ -49,6 +49,17 @@ pmih0108_e1_temp_alarm: temp-alarm@a00 {
 			#thermal-sensor-cells = <0>;
 		};
 
+		sensor@4700 {
+			compatible = "qcom,pmih0108-bcl";
+			reg = <0x4700>;
+			interrupts = <0x7 0x47 0x0 IRQ_TYPE_EDGE_RISING>,
+				     <0x7 0x47 0x1 IRQ_TYPE_EDGE_RISING>,
+				     <0x7 0x47 0x2 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "max-min",
+					  "critical",
+					  "emergency";
+		};
+
 		pmih0108_e1_gpios: gpio@8800 {
 			compatible = "qcom,pmih0108-gpio", "qcom,spmi-gpio";
 			reg = <0x8800>;

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v3 11/12] arm64: dts: qcom: pmih0108: Enable BCL sensor node
  2026-09-29 13:09 [PATCH v3 00/12] hwmon: Add Qualcomm SPMI BCL driver Manaf Meethalavalappu Pallikunhi
                   ` (9 preceding siblings ...)
  2026-09-29 13:09 ` [PATCH v3 10/12] arm64: dts: qcom: pmih0108-kaanapali: " Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:09 ` Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:21   ` Abel Vesa
  2026-09-29 13:26   ` sashiko-bot
  2026-09-29 13:09 ` [PATCH v3 12/12] arm64: dts: qcom: smb2370: " Manaf Meethalavalappu Pallikunhi
  11 siblings, 2 replies; 38+ messages in thread
From: Manaf Meethalavalappu Pallikunhi @ 2026-09-29 13:09 UTC (permalink / raw)
  To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa
  Cc: linux-hwmon, linux-arm-msm, devicetree, linux-kernel, mfd,
	Gaurav Kohli, Manaf Meethalavalappu Pallikunhi

Add Battery Current Limiting (BCL) hardware monitor node for pmih0108
PMIC. The BCL monitors battery voltage and current, providing hardware
interrupts when configurable thresholds are violated.

Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/pmih0108.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/pmih0108.dtsi b/arch/arm64/boot/dts/qcom/pmih0108.dtsi
index 1c875995d881..e8af3e5d583c 100644
--- a/arch/arm64/boot/dts/qcom/pmih0108.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmih0108.dtsi
@@ -49,6 +49,17 @@ pmih0108_temp_alarm: temp-alarm@a00 {
 			#thermal-sensor-cells = <0>;
 		};
 
+		sensor@4700 {
+			compatible = "qcom,pmih0108-bcl";
+			reg = <0x4700>;
+			interrupts = <0x7 0x47 0x0 IRQ_TYPE_EDGE_RISING>,
+				     <0x7 0x47 0x1 IRQ_TYPE_EDGE_RISING>,
+				     <0x7 0x47 0x2 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "max-min",
+					  "critical",
+					  "emergency";
+		};
+
 		pmih0108_gpios: gpio@8800 {
 			compatible = "qcom,pmih0108-gpio", "qcom,spmi-gpio";
 			reg = <0x8800>;

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v3 12/12] arm64: dts: qcom: smb2370: Enable BCL sensor node
  2026-09-29 13:09 [PATCH v3 00/12] hwmon: Add Qualcomm SPMI BCL driver Manaf Meethalavalappu Pallikunhi
                   ` (10 preceding siblings ...)
  2026-09-29 13:09 ` [PATCH v3 11/12] arm64: dts: qcom: pmih0108: " Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:09 ` Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:29   ` sashiko-bot
  11 siblings, 1 reply; 38+ messages in thread
From: Manaf Meethalavalappu Pallikunhi @ 2026-09-29 13:09 UTC (permalink / raw)
  To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa
  Cc: linux-hwmon, linux-arm-msm, devicetree, linux-kernel, mfd,
	Gaurav Kohli, Manaf Meethalavalappu Pallikunhi

Add Battery Current Limiting (BCL) hardware monitor node for smb2370
PMIC. The BCL monitors battery voltage and current, providing hardware
interrupts when configurable thresholds are violated.

Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/smb2370.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/smb2370.dtsi b/arch/arm64/boot/dts/qcom/smb2370.dtsi
index 1e02578e4ee3..4809b3d8cfe2 100644
--- a/arch/arm64/boot/dts/qcom/smb2370.dtsi
+++ b/arch/arm64/boot/dts/qcom/smb2370.dtsi
@@ -10,6 +10,17 @@ smb2370_j_e2: pmic@9 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 
+		sensor@4700 {
+			compatible = "qcom,smb2370-bcl";
+			reg = <0x4700>;
+			interrupts = <0x9 0x47 0x0 IRQ_TYPE_EDGE_RISING>,
+				     <0x9 0x47 0x1 IRQ_TYPE_EDGE_RISING>,
+				     <0x9 0x47 0x2 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "max-min",
+					  "critical",
+					  "emergency";
+		};
+
 		smb2370_j_e2_eusb2_repeater: phy@fd00 {
 			compatible = "qcom,smb2370-eusb2-repeater";
 			reg = <0xfd00>;

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 03/12] arm64: dts: qcom: hamoa-pmic: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 03/12] arm64: dts: qcom: hamoa-pmic: Enable BCL sensor node Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:15   ` sashiko-bot
  2026-09-29 13:17   ` Abel Vesa
  1 sibling, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-29 13:15 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: linux-hwmon, conor+dt, devicetree, lee, robh, mfd

> Add Battery Current Limiting (BCL) hardware monitor node for
> hamoa-pmic. The BCL monitors battery voltage and current, providing
> hardware interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260929-qcom-bcl-hwmon-v3-0-f5ca00889cf7@oss.qualcomm.com?part=3


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 01/12] dt-bindings: hwmon: Describe Qualcomm BCL hardware
  2026-09-29 13:09 ` [PATCH v3 01/12] dt-bindings: hwmon: Describe Qualcomm BCL hardware Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:15   ` sashiko-bot
  0 siblings, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-29 13:15 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: conor+dt, lee, mfd, linux-hwmon, devicetree, robh

> Qualcomm SPMI PMIC BCL (Battery Current Limiting) is a safety feature
> that monitors battery or system voltage and current to alert system
> for overcurrent or undervoltage conditions.
> 
> It provides:
> - Real-time voltage and current monitoring
> - Configurable thresholds per channel
> - Hardware interrupts when thresholds are violated
> 
> Add a devicetree binding to describe the BCL on Qualcomm's PMICs.
> 
> Add sensor type to SPMI device list for BCL device.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260929-qcom-bcl-hwmon-v3-0-f5ca00889cf7@oss.qualcomm.com?part=1


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 07/12] arm64: dts: qcom: pm8350c: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 07/12] arm64: dts: qcom: pm8350c: " Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:15   ` Abel Vesa
  2026-09-30 10:02     ` Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:22   ` sashiko-bot
  1 sibling, 1 reply; 38+ messages in thread
From: Abel Vesa @ 2026-09-29 13:15 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa, linux-hwmon, linux-arm-msm, devicetree,
	linux-kernel, mfd, Gaurav Kohli

On 26-09-29 18:39:39, Manaf Meethalavalappu Pallikunhi wrote:
> Add Battery Current Limiting (BCL) hardware monitor node for pm8350c
> PMIC. The BCL monitors battery voltage and current, providing hardware
> interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
> ---
>  arch/arm64/boot/dts/qcom/pm8350c.dtsi | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/pm8350c.dtsi b/arch/arm64/boot/dts/qcom/pm8350c.dtsi
> index 1a24e6439e36..52b5fc1ef9a3 100644
> --- a/arch/arm64/boot/dts/qcom/pm8350c.dtsi
> +++ b/arch/arm64/boot/dts/qcom/pm8350c.dtsi
> @@ -20,6 +20,17 @@ pm8350c_temp_alarm: temp-alarm@a00 {
>  			#thermal-sensor-cells = <0>;
>  		};
>  
> +		sensor@4700 {
> +			compatible = "qcom,pm8350c-bcl";
> +			reg = <0x4700>;
> +			interrupts = <0x2 0x47 0x0 IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x47 0x1 IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x47 0x2 IRQ_TYPE_EDGE_RISING>;
> +			interrupt-names = "max-min",
> +					  "critical",
> +					  "emergency";
> +		};
> +
>  		pm8350c_gpios: gpio@8800 {
>  			compatible = "qcom,pm8350c-gpio", "qcom,spmi-gpio";
>  			reg = <0x8800>;
> @@ -41,6 +52,7 @@ pm8350c_pwm: pwm {
>  			#pwm-cells = <2>;
>  			status = "disabled";
>  		};
> +

Drop this new empty line.

>  	};
>  };
>  
> 
> -- 
> 2.43.0
> 

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 03/12] arm64: dts: qcom: hamoa-pmic: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 03/12] arm64: dts: qcom: hamoa-pmic: Enable BCL sensor node Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:15   ` sashiko-bot
@ 2026-09-29 13:17   ` Abel Vesa
  1 sibling, 0 replies; 38+ messages in thread
From: Abel Vesa @ 2026-09-29 13:17 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa, linux-hwmon, linux-arm-msm, devicetree,
	linux-kernel, mfd, Gaurav Kohli

On 26-09-29 18:39:35, Manaf Meethalavalappu Pallikunhi wrote:
> Add Battery Current Limiting (BCL) hardware monitor node for
> hamoa-pmic. The BCL monitors battery voltage and current, providing
> hardware interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 04/12] arm64: dts: qcom: pm7250b: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 04/12] arm64: dts: qcom: pm7250b: " Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:17   ` sashiko-bot
  2026-09-29 13:17   ` Abel Vesa
  1 sibling, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-29 13:17 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: devicetree, linux-hwmon, lee, robh, mfd, conor+dt

> Add Battery Current Limiting (BCL) hardware monitor node for pm7250b
> PMIC. The BCL monitors battery voltage and current, providing hardware
> interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260929-qcom-bcl-hwmon-v3-0-f5ca00889cf7@oss.qualcomm.com?part=4


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 04/12] arm64: dts: qcom: pm7250b: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 04/12] arm64: dts: qcom: pm7250b: " Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:17   ` sashiko-bot
@ 2026-09-29 13:17   ` Abel Vesa
  1 sibling, 0 replies; 38+ messages in thread
From: Abel Vesa @ 2026-09-29 13:17 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa, linux-hwmon, linux-arm-msm, devicetree,
	linux-kernel, mfd, Gaurav Kohli

On 26-09-29 18:39:36, Manaf Meethalavalappu Pallikunhi wrote:
> Add Battery Current Limiting (BCL) hardware monitor node for pm7250b
> PMIC. The BCL monitors battery voltage and current, providing hardware
> interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 05/12] arm64: dts: qcom: pm7550-eliza: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 05/12] arm64: dts: qcom: pm7550-eliza: " Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:18   ` Abel Vesa
  2026-09-29 13:23   ` sashiko-bot
  1 sibling, 0 replies; 38+ messages in thread
From: Abel Vesa @ 2026-09-29 13:18 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa, linux-hwmon, linux-arm-msm, devicetree,
	linux-kernel, mfd, Gaurav Kohli

On 26-09-29 18:39:37, Manaf Meethalavalappu Pallikunhi wrote:
> Add Battery Current Limiting (BCL) hardware monitor node for
> pm7550-eliza. The BCL monitors battery voltage and current, providing
> hardware interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 06/12] arm64: dts: qcom: pm7550ba-eliza: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 06/12] arm64: dts: qcom: pm7550ba-eliza: " Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:18   ` Abel Vesa
  2026-09-29 13:20   ` sashiko-bot
  1 sibling, 0 replies; 38+ messages in thread
From: Abel Vesa @ 2026-09-29 13:18 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa, linux-hwmon, linux-arm-msm, devicetree,
	linux-kernel, mfd, Gaurav Kohli

On 26-09-29 18:39:38, Manaf Meethalavalappu Pallikunhi wrote:
> Add Battery Current Limiting (BCL) hardware monitor node for
> pm7550ba-eliza. The BCL monitors battery voltage and current, providing
> hardware interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 08/12] arm64: dts: qcom: pm8550: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 08/12] arm64: dts: qcom: pm8550: " Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:19   ` Abel Vesa
  2026-09-29 13:20   ` Abel Vesa
  2026-09-29 13:24   ` sashiko-bot
  2 siblings, 0 replies; 38+ messages in thread
From: Abel Vesa @ 2026-09-29 13:19 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa, linux-hwmon, linux-arm-msm, devicetree,
	linux-kernel, mfd, Gaurav Kohli

On 26-09-29 18:39:40, Manaf Meethalavalappu Pallikunhi wrote:
> Add Battery Current Limiting (BCL) hardware monitor node for pm8550
> PMIC. The BCL monitors battery voltage and current, providing hardware
> interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 09/12] arm64: dts: qcom: pmh0101: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 09/12] arm64: dts: qcom: pmh0101: " Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:19   ` Abel Vesa
  2026-09-29 13:20   ` Abel Vesa
  2026-09-29 13:27   ` sashiko-bot
  2 siblings, 0 replies; 38+ messages in thread
From: Abel Vesa @ 2026-09-29 13:19 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa, linux-hwmon, linux-arm-msm, devicetree,
	linux-kernel, mfd, Gaurav Kohli

On 26-09-29 18:39:41, Manaf Meethalavalappu Pallikunhi wrote:
> Add Battery Current Limiting (BCL) hardware monitor node for pmh0101
> PMIC. The BCL monitors battery voltage and current, providing hardware
> interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 08/12] arm64: dts: qcom: pm8550: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 08/12] arm64: dts: qcom: pm8550: " Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:19   ` Abel Vesa
@ 2026-09-29 13:20   ` Abel Vesa
  2026-09-29 13:24   ` sashiko-bot
  2 siblings, 0 replies; 38+ messages in thread
From: Abel Vesa @ 2026-09-29 13:20 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa, linux-hwmon, linux-arm-msm, devicetree,
	linux-kernel, mfd, Gaurav Kohli

On 26-09-29 18:39:40, Manaf Meethalavalappu Pallikunhi wrote:
> Add Battery Current Limiting (BCL) hardware monitor node for pm8550
> PMIC. The BCL monitors battery voltage and current, providing hardware
> interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 06/12] arm64: dts: qcom: pm7550ba-eliza: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 06/12] arm64: dts: qcom: pm7550ba-eliza: " Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:18   ` Abel Vesa
@ 2026-09-29 13:20   ` sashiko-bot
  1 sibling, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-29 13:20 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: lee, robh, mfd, conor+dt, devicetree, linux-hwmon

> Add Battery Current Limiting (BCL) hardware monitor node for
> pm7550ba-eliza. The BCL monitors battery voltage and current, providing
> hardware interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260929-qcom-bcl-hwmon-v3-0-f5ca00889cf7@oss.qualcomm.com?part=6


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 09/12] arm64: dts: qcom: pmh0101: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 09/12] arm64: dts: qcom: pmh0101: " Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:19   ` Abel Vesa
@ 2026-09-29 13:20   ` Abel Vesa
  2026-09-29 13:27   ` sashiko-bot
  2 siblings, 0 replies; 38+ messages in thread
From: Abel Vesa @ 2026-09-29 13:20 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa, linux-hwmon, linux-arm-msm, devicetree,
	linux-kernel, mfd, Gaurav Kohli

On 26-09-29 18:39:41, Manaf Meethalavalappu Pallikunhi wrote:
> Add Battery Current Limiting (BCL) hardware monitor node for pmh0101
> PMIC. The BCL monitors battery voltage and current, providing hardware
> interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 10/12] arm64: dts: qcom: pmih0108-kaanapali: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 10/12] arm64: dts: qcom: pmih0108-kaanapali: " Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:20   ` Abel Vesa
  2026-09-29 13:25   ` sashiko-bot
  1 sibling, 0 replies; 38+ messages in thread
From: Abel Vesa @ 2026-09-29 13:20 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa, linux-hwmon, linux-arm-msm, devicetree,
	linux-kernel, mfd, Gaurav Kohli

On 26-09-29 18:39:42, Manaf Meethalavalappu Pallikunhi wrote:
> Add Battery Current Limiting (BCL) hardware monitor node for pmih0108
> PMIC. The BCL monitors battery voltage and current, providing hardware
> interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 11/12] arm64: dts: qcom: pmih0108: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 11/12] arm64: dts: qcom: pmih0108: " Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:21   ` Abel Vesa
  2026-09-29 13:26   ` sashiko-bot
  1 sibling, 0 replies; 38+ messages in thread
From: Abel Vesa @ 2026-09-29 13:21 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa, linux-hwmon, linux-arm-msm, devicetree,
	linux-kernel, mfd, Gaurav Kohli

On 26-09-29 18:39:43, Manaf Meethalavalappu Pallikunhi wrote:
> Add Battery Current Limiting (BCL) hardware monitor node for pmih0108
> PMIC. The BCL monitors battery voltage and current, providing hardware
> interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 02/12] hwmon: Add Qualcomm PMIC BCL driver
  2026-09-29 13:09 ` [PATCH v3 02/12] hwmon: Add Qualcomm PMIC BCL driver Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:21   ` sashiko-bot
  2026-10-05 11:25     ` Manaf Meethalavalappu Pallikunhi
  0 siblings, 1 reply; 38+ messages in thread
From: sashiko-bot @ 2026-09-29 13:21 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: devicetree, lee, robh, linux-hwmon, mfd, conor+dt

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] hwmon: use-after-free in delayed work due to missing cleanup on probe error
- [Medium] hwmon: potential torn read of 16-bit volatile ADC values
- [Low] hwmon: incorrect rounding of negative ADC current readings
--

commit 582b6b399b20e883c83628558dc27f1dcb1c1d4d
Author: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
Subject: hwmon: Add Qualcomm PMIC BCL driver

Add driver for Qualcomm SPMI PMIC Battery Current Limiting (BCL)
hardware monitor. The driver exposes battery voltage and current
monitoring through hwmon interface.

> diff --git a/drivers/hwmon/qcom-bcl-hwmon.c b/drivers/hwmon/qcom-bcl-hwmon.c
> new file mode 100644
> index 0000000000000..eb6bfa7ff18f5
> --- /dev/null
> +++ b/drivers/hwmon/qcom-bcl-hwmon.c
[ ... ]
> +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_s64((s64)raw_val * scaling_factor + 500000, 1000000);

[Severity: Low]
Does this math correctly handle negative current values?

When the hardware provides a negative ADC value for current (e.g., during
battery discharging), it is sign-extended in bcl_curr_input_read() and
passed here. The arithmetic unconditionally adds 500000 before performing
integer division (div_s64). For negative dividends, adding a positive offset
shifts the value towards positive infinity, and C integer division truncates
towards zero, causing the hwmon statistics to be off by 1 unit.

Could this conditionally subtract 500000 for negative dividends to ensure
mathematically symmetric rounding?

[ ... ]
> +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 (bcl->last_curr_updated &&
> +	    time_before(jiffies, bcl->last_curr_updated + HZ)) {
> +		*out = bcl->last_curr_input;
> +		return 0;
> +	}
> +
> +	ret = regmap_field_read(bcl->fields[F_CURR_INPUT], &raw_val);
> +	if (ret)
> +		return ret;
> +
> +	/* For 16-bit data, read MSB and combine with LSB */
> +	if (desc->data_field_bits_size == 16) {
> +		ret = regmap_field_read(bcl->fields[F_CURR_INPUT1], &msb);

[Severity: Medium]
Is there a risk of a torn read when fetching this 16-bit volatile ADC value?

These sequential reads can capture hardware registers in an inconsistent
state if the PMIC hardware updates the ADC registers exactly between the two
independent bus transactions. Since the mutex lock only serializes software
threads, a hardware update right between these calls would result in reading a
mix of old and new bytes (e.g., an LSB of 0xFF and an MSB of 0x01).

Should this use an atomic regmap_bulk_read() for 16-bit data fields to
prevent wildly incorrect sensor readings?

> +		if (ret)
> +			return ret;
> +		raw_val |= FIELD_PREP(GENMASK(15, 8), msb);
> +	}
[ ... ]
> +static int bcl_alarm_irq_init(struct platform_device *pdev,
> +			      struct bcl_device *bcl)
> +{
> +	int ret, irq_num, i;
> +	struct bcl_alarm_data *alarm;
> +
> +	for (i = 0; i < ARRAY_SIZE(bcl->bcl_alarms); i++) {
> +		alarm = &bcl->bcl_alarms[i];
[ ... ]
> +		ret = devm_request_threaded_irq(&pdev->dev, irq_num, NULL,
> +						bcl_handle_alarm, IRQF_ONESHOT,
> +						bcl_int_names[i], 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;
> +
> +		ret = devm_add_action_or_reset(&pdev->dev, bcl_alarm_work_cleanup_action,
> +					       alarm);

[Severity: High]
Could this lead to a use-after-free if device probe fails under memory
pressure?

The IRQ is activated by devm_request_threaded_irq() and can immediately
schedule the delayed work. If the very next devm_add_action_or_reset()
fails, the driver returns early without registering
bcl_alarm_work_cleanup_action.

If the IRQ fires in this brief window and schedules the delayed work, the
work will not be safely canceled during the devm teardown sequence and will
execute after the bcl_device memory is freed.

> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 07/12] arm64: dts: qcom: pm8350c: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 07/12] arm64: dts: qcom: pm8350c: " Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:15   ` Abel Vesa
@ 2026-09-29 13:22   ` sashiko-bot
  1 sibling, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-29 13:22 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: mfd, conor+dt, devicetree, linux-hwmon, robh, lee

> Add Battery Current Limiting (BCL) hardware monitor node for pm8350c
> PMIC. The BCL monitors battery voltage and current, providing hardware
> interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260929-qcom-bcl-hwmon-v3-0-f5ca00889cf7@oss.qualcomm.com?part=7


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 05/12] arm64: dts: qcom: pm7550-eliza: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 05/12] arm64: dts: qcom: pm7550-eliza: " Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:18   ` Abel Vesa
@ 2026-09-29 13:23   ` sashiko-bot
  1 sibling, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-29 13:23 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: linux-hwmon, mfd, conor+dt, lee, devicetree, robh

> Add Battery Current Limiting (BCL) hardware monitor node for
> pm7550-eliza. The BCL monitors battery voltage and current, providing
> hardware interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260929-qcom-bcl-hwmon-v3-0-f5ca00889cf7@oss.qualcomm.com?part=5


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 08/12] arm64: dts: qcom: pm8550: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 08/12] arm64: dts: qcom: pm8550: " Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:19   ` Abel Vesa
  2026-09-29 13:20   ` Abel Vesa
@ 2026-09-29 13:24   ` sashiko-bot
  2 siblings, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-29 13:24 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: lee, robh, conor+dt, mfd, linux-hwmon, devicetree

> Add Battery Current Limiting (BCL) hardware monitor node for pm8550
> PMIC. The BCL monitors battery voltage and current, providing hardware
> interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260929-qcom-bcl-hwmon-v3-0-f5ca00889cf7@oss.qualcomm.com?part=8


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 10/12] arm64: dts: qcom: pmih0108-kaanapali: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 10/12] arm64: dts: qcom: pmih0108-kaanapali: " Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:20   ` Abel Vesa
@ 2026-09-29 13:25   ` sashiko-bot
  1 sibling, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-29 13:25 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: robh, devicetree, lee, conor+dt, linux-hwmon, mfd

> Add Battery Current Limiting (BCL) hardware monitor node for pmih0108
> PMIC. The BCL monitors battery voltage and current, providing hardware
> interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260929-qcom-bcl-hwmon-v3-0-f5ca00889cf7@oss.qualcomm.com?part=10


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 11/12] arm64: dts: qcom: pmih0108: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 11/12] arm64: dts: qcom: pmih0108: " Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:21   ` Abel Vesa
@ 2026-09-29 13:26   ` sashiko-bot
  1 sibling, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-29 13:26 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: conor+dt, devicetree, robh, linux-hwmon, lee, mfd

> Add Battery Current Limiting (BCL) hardware monitor node for pmih0108
> PMIC. The BCL monitors battery voltage and current, providing hardware
> interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260929-qcom-bcl-hwmon-v3-0-f5ca00889cf7@oss.qualcomm.com?part=11


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 09/12] arm64: dts: qcom: pmh0101: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 09/12] arm64: dts: qcom: pmh0101: " Manaf Meethalavalappu Pallikunhi
  2026-09-29 13:19   ` Abel Vesa
  2026-09-29 13:20   ` Abel Vesa
@ 2026-09-29 13:27   ` sashiko-bot
  2 siblings, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-29 13:27 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: mfd, lee, linux-hwmon, conor+dt, robh, devicetree

> Add Battery Current Limiting (BCL) hardware monitor node for pmh0101
> PMIC. The BCL monitors battery voltage and current, providing hardware
> interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260929-qcom-bcl-hwmon-v3-0-f5ca00889cf7@oss.qualcomm.com?part=9


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 12/12] arm64: dts: qcom: smb2370: Enable BCL sensor node
  2026-09-29 13:09 ` [PATCH v3 12/12] arm64: dts: qcom: smb2370: " Manaf Meethalavalappu Pallikunhi
@ 2026-09-29 13:29   ` sashiko-bot
  0 siblings, 0 replies; 38+ messages in thread
From: sashiko-bot @ 2026-09-29 13:29 UTC (permalink / raw)
  To: Manaf Meethalavalappu Pallikunhi
  Cc: robh, mfd, lee, linux-hwmon, devicetree, conor+dt

> Add Battery Current Limiting (BCL) hardware monitor node for smb2370
> PMIC. The BCL monitors battery voltage and current, providing hardware
> interrupts when configurable thresholds are violated.
> 
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260929-qcom-bcl-hwmon-v3-0-f5ca00889cf7@oss.qualcomm.com?part=12


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 07/12] arm64: dts: qcom: pm8350c: Enable BCL sensor node
  2026-09-29 13:15   ` Abel Vesa
@ 2026-09-30 10:02     ` Manaf Meethalavalappu Pallikunhi
  0 siblings, 0 replies; 38+ messages in thread
From: Manaf Meethalavalappu Pallikunhi @ 2026-09-30 10:02 UTC (permalink / raw)
  To: Abel Vesa
  Cc: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lee Jones, Stephen Boyd, Bjorn Andersson, Konrad Dybcio,
	Daniel Lezcano, Abel Vesa, linux-hwmon, linux-arm-msm, devicetree,
	linux-kernel, mfd, Gaurav Kohli

Hi Abel,

On 9/29/2026 6:45 PM, Abel Vesa wrote:
> On 26-09-29 18:39:39, Manaf Meethalavalappu Pallikunhi wrote:
>> Add Battery Current Limiting (BCL) hardware monitor node for pm8350c
>> PMIC. The BCL monitors battery voltage and current, providing hardware
>> interrupts when configurable thresholds are violated.
>>
>> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
>> ---
>>   arch/arm64/boot/dts/qcom/pm8350c.dtsi | 12 ++++++++++++
>>   1 file changed, 12 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/qcom/pm8350c.dtsi b/arch/arm64/boot/dts/qcom/pm8350c.dtsi
>> index 1a24e6439e36..52b5fc1ef9a3 100644
>> --- a/arch/arm64/boot/dts/qcom/pm8350c.dtsi
>> +++ b/arch/arm64/boot/dts/qcom/pm8350c.dtsi
>> @@ -20,6 +20,17 @@ pm8350c_temp_alarm: temp-alarm@a00 {
>>   			#thermal-sensor-cells = <0>;
>>   		};
>>   
>> +		sensor@4700 {
>> +			compatible = "qcom,pm8350c-bcl";
>> +			reg = <0x4700>;
>> +			interrupts = <0x2 0x47 0x0 IRQ_TYPE_EDGE_RISING>,
>> +				     <0x2 0x47 0x1 IRQ_TYPE_EDGE_RISING>,
>> +				     <0x2 0x47 0x2 IRQ_TYPE_EDGE_RISING>;
>> +			interrupt-names = "max-min",
>> +					  "critical",
>> +					  "emergency";
>> +		};
>> +
>>   		pm8350c_gpios: gpio@8800 {
>>   			compatible = "qcom,pm8350c-gpio", "qcom,spmi-gpio";
>>   			reg = <0x8800>;
>> @@ -41,6 +52,7 @@ pm8350c_pwm: pwm {
>>   			#pwm-cells = <2>;
>>   			status = "disabled";
>>   		};
>> +
> 
> Drop this new empty line.

Thanks for review, will fix it in next revision.

Thanks,
Manaf>
>>   	};
>>   };
>>   
>>
>> -- 
>> 2.43.0
>>


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 02/12] hwmon: Add Qualcomm PMIC BCL driver
  2026-09-29 13:21   ` sashiko-bot
@ 2026-10-05 11:25     ` Manaf Meethalavalappu Pallikunhi
  0 siblings, 0 replies; 38+ messages in thread
From: Manaf Meethalavalappu Pallikunhi @ 2026-10-05 11:25 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: devicetree, lee, robh, linux-hwmon, mfd, conor+dt

Hi

On 9/29/2026 6:51 PM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
> - [High] hwmon: use-after-free in delayed work due to missing cleanup on probe error
> - [Medium] hwmon: potential torn read of 16-bit volatile ADC values
> - [Low] hwmon: incorrect rounding of negative ADC current readings
> --
> 
> commit 582b6b399b20e883c83628558dc27f1dcb1c1d4d
> Author: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
> Subject: hwmon: Add Qualcomm PMIC BCL driver
> 
> Add driver for Qualcomm SPMI PMIC Battery Current Limiting (BCL)
> hardware monitor. The driver exposes battery voltage and current
> monitoring through hwmon interface.
> 
>> diff --git a/drivers/hwmon/qcom-bcl-hwmon.c b/drivers/hwmon/qcom-bcl-hwmon.c
>> new file mode 100644
>> index 0000000000000..eb6bfa7ff18f5
>> --- /dev/null
>> +++ b/drivers/hwmon/qcom-bcl-hwmon.c
> [ ... ]
>> +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_s64((s64)raw_val * scaling_factor + 500000, 1000000);
> 
> [Severity: Low]
> Does this math correctly handle negative current values?
> 
> When the hardware provides a negative ADC value for current (e.g., during
> battery discharging), it is sign-extended in bcl_curr_input_read() and
> passed here. The arithmetic unconditionally adds 500000 before performing
> integer division (div_s64). For negative dividends, adding a positive offset
> shifts the value towards positive infinity, and C integer division truncates
> towards zero, causing the hwmon statistics to be off by 1 unit.
> 
> Could this conditionally subtract 500000 for negative dividends to ensure
> mathematically symmetric rounding?

I will use DIV_S64_ROUND_CLOSEST instead of the biased 
add-500000-then-truncate pattern in next revision.

> 
> [ ... ]
>> +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 (bcl->last_curr_updated &&
>> +	    time_before(jiffies, bcl->last_curr_updated + HZ)) {
>> +		*out = bcl->last_curr_input;
>> +		return 0;
>> +	}
>> +
>> +	ret = regmap_field_read(bcl->fields[F_CURR_INPUT], &raw_val);
>> +	if (ret)
>> +		return ret;
>> +
>> +	/* For 16-bit data, read MSB and combine with LSB */
>> +	if (desc->data_field_bits_size == 16) {
>> +		ret = regmap_field_read(bcl->fields[F_CURR_INPUT1], &msb);
> 
> [Severity: Medium]
> Is there a risk of a torn read when fetching this 16-bit volatile ADC value?
> 
> These sequential reads can capture hardware registers in an inconsistent
> state if the PMIC hardware updates the ADC registers exactly between the two
> independent bus transactions. Since the mutex lock only serializes software
> threads, a hardware update right between these calls would result in reading a
> mix of old and new bytes (e.g., an LSB of 0xFF and an MSB of 0x01).
> 
> Should this use an atomic regmap_bulk_read() for 16-bit data fields to
> prevent wildly incorrect sensor readings?

I will update regmap_bulk_read() for the 16-bit LSB/MSB pair.

> 
>> +		if (ret)
>> +			return ret;
>> +		raw_val |= FIELD_PREP(GENMASK(15, 8), msb);
>> +	}
> [ ... ]
>> +static int bcl_alarm_irq_init(struct platform_device *pdev,
>> +			      struct bcl_device *bcl)
>> +{
>> +	int ret, irq_num, i;
>> +	struct bcl_alarm_data *alarm;
>> +
>> +	for (i = 0; i < ARRAY_SIZE(bcl->bcl_alarms); i++) {
>> +		alarm = &bcl->bcl_alarms[i];
> [ ... ]
>> +		ret = devm_request_threaded_irq(&pdev->dev, irq_num, NULL,
>> +						bcl_handle_alarm, IRQF_ONESHOT,
>> +						bcl_int_names[i], 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;
>> +
>> +		ret = devm_add_action_or_reset(&pdev->dev, bcl_alarm_work_cleanup_action,
>> +					       alarm);
> 
> [Severity: High]
> Could this lead to a use-after-free if device probe fails under memory
> pressure?
> 
> The IRQ is activated by devm_request_threaded_irq() and can immediately
> schedule the delayed work. If the very next devm_add_action_or_reset()
> fails, the driver returns early without registering
> bcl_alarm_work_cleanup_action.
> 
> If the IRQ fires in this brief window and schedules the delayed work, the
> work will not be safely canceled during the devm teardown sequence and will
> execute after the bcl_device memory is freed.

ACK, will update

Thanks,
Manaf

> 
>> +		if (ret)
>> +			return ret;
>> +	}
>> +
>> +	return 0;
>> +}
> 


^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2026-10-05 11:25 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-29 13:09 [PATCH v3 00/12] hwmon: Add Qualcomm SPMI BCL driver Manaf Meethalavalappu Pallikunhi
2026-09-29 13:09 ` [PATCH v3 01/12] dt-bindings: hwmon: Describe Qualcomm BCL hardware Manaf Meethalavalappu Pallikunhi
2026-09-29 13:15   ` sashiko-bot
2026-09-29 13:09 ` [PATCH v3 02/12] hwmon: Add Qualcomm PMIC BCL driver Manaf Meethalavalappu Pallikunhi
2026-09-29 13:21   ` sashiko-bot
2026-10-05 11:25     ` Manaf Meethalavalappu Pallikunhi
2026-09-29 13:09 ` [PATCH v3 03/12] arm64: dts: qcom: hamoa-pmic: Enable BCL sensor node Manaf Meethalavalappu Pallikunhi
2026-09-29 13:15   ` sashiko-bot
2026-09-29 13:17   ` Abel Vesa
2026-09-29 13:09 ` [PATCH v3 04/12] arm64: dts: qcom: pm7250b: " Manaf Meethalavalappu Pallikunhi
2026-09-29 13:17   ` sashiko-bot
2026-09-29 13:17   ` Abel Vesa
2026-09-29 13:09 ` [PATCH v3 05/12] arm64: dts: qcom: pm7550-eliza: " Manaf Meethalavalappu Pallikunhi
2026-09-29 13:18   ` Abel Vesa
2026-09-29 13:23   ` sashiko-bot
2026-09-29 13:09 ` [PATCH v3 06/12] arm64: dts: qcom: pm7550ba-eliza: " Manaf Meethalavalappu Pallikunhi
2026-09-29 13:18   ` Abel Vesa
2026-09-29 13:20   ` sashiko-bot
2026-09-29 13:09 ` [PATCH v3 07/12] arm64: dts: qcom: pm8350c: " Manaf Meethalavalappu Pallikunhi
2026-09-29 13:15   ` Abel Vesa
2026-09-30 10:02     ` Manaf Meethalavalappu Pallikunhi
2026-09-29 13:22   ` sashiko-bot
2026-09-29 13:09 ` [PATCH v3 08/12] arm64: dts: qcom: pm8550: " Manaf Meethalavalappu Pallikunhi
2026-09-29 13:19   ` Abel Vesa
2026-09-29 13:20   ` Abel Vesa
2026-09-29 13:24   ` sashiko-bot
2026-09-29 13:09 ` [PATCH v3 09/12] arm64: dts: qcom: pmh0101: " Manaf Meethalavalappu Pallikunhi
2026-09-29 13:19   ` Abel Vesa
2026-09-29 13:20   ` Abel Vesa
2026-09-29 13:27   ` sashiko-bot
2026-09-29 13:09 ` [PATCH v3 10/12] arm64: dts: qcom: pmih0108-kaanapali: " Manaf Meethalavalappu Pallikunhi
2026-09-29 13:20   ` Abel Vesa
2026-09-29 13:25   ` sashiko-bot
2026-09-29 13:09 ` [PATCH v3 11/12] arm64: dts: qcom: pmih0108: " Manaf Meethalavalappu Pallikunhi
2026-09-29 13:21   ` Abel Vesa
2026-09-29 13:26   ` sashiko-bot
2026-09-29 13:09 ` [PATCH v3 12/12] arm64: dts: qcom: smb2370: " Manaf Meethalavalappu Pallikunhi
2026-09-29 13:29   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox