summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier Carrasco <javier.carrasco.cruz@gmail.com>2026-10-14 19:34:07 +0200
committerGuenter Roeck <linux@roeck-us.net>2026-11-02 07:00:04 -0800
commit378add65fd7d352de9fe440d167fde5bf511b090 (patch)
treedb4532dbd98693b7c33fb4dadd4455d854fa6527
parentd1ce827a9cc11ffdfec77b7fec9b73a8020a308d (diff)
hwmon: chipcap2: balance regulator state
The current implementation does not guarantee that the calls to regulator_enable() and regulator_disable() are balanced. regulator_is_enabled() might return a negative value, and an always-on attribute in the DT might break the symmetry anyway. Add a regulator_enabled flag to keep balance within this regulator consumer. Fixes: 3af350929e75 ("hwmon: Add support for Amphenol ChipCap 2") Cc: stable@vger.kernel.org Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com> Link: https://patch.msgid.link/20261014-chipcap2_locks-v3-8-27ebfc2c5b9e@gmail.com Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r--drivers/hwmon/chipcap2.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/hwmon/chipcap2.c b/drivers/hwmon/chipcap2.c
index 837b1830f2e4..952789fdb9db 100644
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -91,6 +91,7 @@ struct cc2_data {
int irq_low;
int irq_high;
bool process_irqs;
+ bool regulator_enabled;
};
/* %RH as a per cent mille from a register value */
@@ -120,7 +121,7 @@ static int cc2_enable(struct cc2_data *data)
int ret;
/* exclusive regulator, check in case a disable failed */
- if (regulator_is_enabled(data->regulator)) {
+ if (data->regulator_enabled) {
data->process_irqs = true;
return 0;
}
@@ -132,6 +133,8 @@ static int cc2_enable(struct cc2_data *data)
if (ret < 0)
return ret;
+ data->regulator_enabled = true;
+
usleep_range(CC2_STARTUP_TIME_US, CC2_STARTUP_TIME_US + 125);
data->process_irqs = true;
@@ -147,11 +150,16 @@ static void cc2_disable(struct cc2_data *data)
data->process_irqs = false;
/* exclusive regulator, check in case an enable failed */
- if (regulator_is_enabled(data->regulator)) {
- err = regulator_disable(data->regulator);
- if (err)
- dev_dbg(&data->client->dev, "Failed to disable device");
+ if (!data->regulator_enabled)
+ return;
+
+ err = regulator_disable(data->regulator);
+ if (err) {
+ dev_dbg(&data->client->dev, "Failed to disable device");
+ return;
}
+
+ data->regulator_enabled = false;
}
static void cc2_disable_action(void *data)