hwmon: (pmbus) Fix passing events to regulator core

Sashiko reports:

Commit 754bd2b4a0 ("hwmon: (pmbus/core) Protect regulator operations with
mutex") introduced a worker to batch regulator events over time using
atomic_or(). The delayed worker then passes the combined bitmask unmodified
to regulator_notifier_call_chain().

The core regulator subsystem's regulator_handle_critical() function
evaluates the event parameter using a strict switch statement. If
multiple distinct faults occur before the worker runs (e.g.,
REGULATOR_EVENT_UNDER_VOLTAGE | REGULATOR_EVENT_OVER_CURRENT), the combined
bitmask fails to match any case. This leaves the reason as NULL and
completely bypasses the critical hw_protection_trigger().

Fix the problem by passing events bit by bit to the regulator event
handler.

Reported-by: Sashiko <sashiko-bot@kernel.org>
Fixes: 754bd2b4a0 ("hwmon: (pmbus/core) Protect regulator operations with mutex")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
Guenter Roeck 2026-06-29 16:08:00 -07:00
parent 72a6910103
commit 9ef7dacd44

View File

@ -3347,18 +3347,23 @@ static void pmbus_regulator_notify_worker(struct work_struct *work)
int i, j;
for (i = 0; i < data->info->pages; i++) {
int event;
unsigned int event;
event = atomic_xchg(&data->regulator_events[i], 0);
if (!event)
continue;
for (j = 0; j < data->info->num_regulators; j++) {
if (i == rdev_get_id(data->rdevs[j])) {
if (i != rdev_get_id(data->rdevs[j]))
continue;
while (event) {
unsigned int _event = BIT(__ffs(event));
regulator_notifier_call_chain(data->rdevs[j],
event, NULL);
break;
_event, NULL);
event &= ~_event;
}
break;
}
}
}