diff options
| author | Javier Carrasco <javier.carrasco.cruz@gmail.com> | 2026-10-14 19:34:07 +0200 |
|---|---|---|
| committer | Guenter Roeck <linux@roeck-us.net> | 2026-11-02 07:00:04 -0800 |
| commit | 378add65fd7d352de9fe440d167fde5bf511b090 (patch) | |
| tree | db4532dbd98693b7c33fb4dadd4455d854fa6527 | |
| parent | d1ce827a9cc11ffdfec77b7fec9b73a8020a308d (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.c | 18 |
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) |
