diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2023-12-08 20:13:44 +0100 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2023-12-11 20:49:53 +0100 |
commit | 4649620d9404d3aceb25891c24bab77143e3f21c (patch) | |
tree | 4ce2e20623c5a1ea244f02ae92aed31bf4c85444 /drivers/thermal/thermal_core.c | |
parent | thermal: sysfs: Rework the reading of trip point attributes (diff) | |
download | linux-4649620d9404d3aceb25891c24bab77143e3f21c.tar.gz linux-4649620d9404d3aceb25891c24bab77143e3f21c.tar.bz2 linux-4649620d9404d3aceb25891c24bab77143e3f21c.zip |
thermal: core: Make thermal_zone_device_unregister() return after freeing the zone
Make thermal_zone_device_unregister() wait until all of the references
to the given thermal zone object have been dropped and free it before
returning.
This guarantees that when thermal_zone_device_unregister() returns,
there is no leftover activity regarding the thermal zone in question
which is required by some of its callers (for instance, modular driver
code that wants to know when it is safe to let the module go away).
Subsequently, this will allow some confusing device_is_registered()
checks to be dropped from the thermal sysfs and core code.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-and-tested-by: Lukasz Luba <lukasz.luba@arm.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Diffstat (limited to 'drivers/thermal/thermal_core.c')
-rw-r--r-- | drivers/thermal/thermal_core.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 625ba07cbe2f..70a294d12187 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -822,7 +822,7 @@ static void thermal_release(struct device *dev) tz = to_thermal_zone(dev); thermal_zone_destroy_device_groups(tz); mutex_destroy(&tz->lock); - kfree(tz); + complete(&tz->removal); } else if (!strncmp(dev_name(dev), "cooling_device", sizeof("cooling_device") - 1)) { cdev = to_cooling_device(dev); @@ -1315,6 +1315,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t INIT_LIST_HEAD(&tz->thermal_instances); ida_init(&tz->ida); mutex_init(&tz->lock); + init_completion(&tz->removal); id = ida_alloc(&thermal_tz_ida, GFP_KERNEL); if (id < 0) { result = id; @@ -1494,6 +1495,9 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) put_device(&tz->device); thermal_notify_tz_delete(tz_id); + + wait_for_completion(&tz->removal); + kfree(tz); } EXPORT_SYMBOL_GPL(thermal_zone_device_unregister); |