diff options
| author | Shubham Chakraborty <chakrabortyshubham66@gmail.com> | 2026-05-17 11:04:45 +0300 |
|---|---|---|
| committer | Guenter Roeck <linux@roeck-us.net> | 2026-06-09 18:23:05 +0300 |
| commit | eb0d491e2787aa359f0d930151ff6e5e5df70fb9 (patch) | |
| tree | 9caf22cca8ee9051707ad45e509a0ccd2532bb53 | |
| parent | 78a3e36eec06a0dc4a205c753e7754e9f9408fba (diff) | |
| download | linux-eb0d491e2787aa359f0d930151ff6e5e5df70fb9.tar.xz | |
hwmon: (raspberrypi) Fix delayed-work teardown race
The delayed polling work rearms itself from the work function, so use
explicit delayed-work setup and cleanup instead of
devm_delayed_work_autocancel().
Initialize the delayed work with INIT_DELAYED_WORK() and register a
devres cleanup action that calls disable_delayed_work_sync() during
teardown.
This addresses the concern raised during review about the polling work
being able to requeue itself while the driver is being removed.
Signed-off-by: Shubham Chakraborty <chakrabortyshubham66@gmail.com>
Link: https://lore.kernel.org/r/20260517080445.103962-4-chakrabortyshubham66@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
| -rw-r--r-- | drivers/hwmon/raspberrypi-hwmon.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/hwmon/raspberrypi-hwmon.c b/drivers/hwmon/raspberrypi-hwmon.c index a458a858b0ac..7b1d2829f012 100644 --- a/drivers/hwmon/raspberrypi-hwmon.c +++ b/drivers/hwmon/raspberrypi-hwmon.c @@ -8,7 +8,6 @@ * Copyright (C) 2026 Shubham Chakraborty <chakrabortyshubham66@gmail.com> */ #include <linux/device.h> -#include <linux/devm-helpers.h> #include <linux/err.h> #include <linux/hwmon.h> #include <linux/module.h> @@ -97,6 +96,13 @@ static void get_values_poll(struct work_struct *work) schedule_delayed_work(&data->get_values_poll_work, 2 * HZ); } +static void rpi_hwmon_cancel_poll_work(void *res) +{ + struct rpi_hwmon_data *data = res; + + disable_delayed_work_sync(&data->get_values_poll_work); +} + static int rpi_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long *val) { @@ -238,8 +244,8 @@ static int rpi_hwmon_probe(struct platform_device *pdev) if (IS_ERR(data->hwmon_dev)) return PTR_ERR(data->hwmon_dev); - ret = devm_delayed_work_autocancel(dev, &data->get_values_poll_work, - get_values_poll); + INIT_DELAYED_WORK(&data->get_values_poll_work, get_values_poll); + ret = devm_add_action_or_reset(dev, rpi_hwmon_cancel_poll_work, data); if (ret) return ret; platform_set_drvdata(pdev, data); |
