thermal/core: Introduce locked version of thermal_zone_device_update
authorGuenter Roeck <linux@roeck-us.net>
Thu, 10 Nov 2022 15:24:56 +0000 (07:24 -0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 14 Nov 2022 18:04:37 +0000 (19:04 +0100)
In thermal_zone_device_set_mode(), the thermal zone mutex is released only
to be reacquired in the subsequent call to thermal_zone_device_update().

Introduce __thermal_zone_device_update(), which is similar to
thermal_zone_device_update() but has to be called with the thermal device
mutex held. Call the new function from thermal_zone_device_set_mode()
to avoid the extra thermal device mutex release/acquire sequence in that
function.

With the new function in place, re-implement thermal_zone_device_update()
as wrapper around __thermal_zone_device_update() to acquire and release
the thermal device mutex.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/thermal/thermal_core.c

index 5d19dc6a82b4d342cc0bb075290f893c6fc54bf3..0657e4bd47917f769280d37e969155b5e1c07cb3 100644 (file)
@@ -403,6 +403,34 @@ static void thermal_zone_device_init(struct thermal_zone_device *tz)
                pos->initialized = false;
 }
 
+static void __thermal_zone_device_update(struct thermal_zone_device *tz,
+                                        enum thermal_notify_event event)
+{
+       int count;
+
+       if (atomic_read(&in_suspend))
+               return;
+
+       if (WARN_ONCE(!tz->ops->get_temp,
+                     "'%s' must not be called without 'get_temp' ops set\n",
+                     __func__))
+               return;
+
+       if (!thermal_zone_device_is_enabled(tz))
+               return;
+
+       update_temperature(tz);
+
+       __thermal_zone_set_trips(tz);
+
+       tz->notify_event = event;
+
+       for (count = 0; count < tz->num_trips; count++)
+               handle_thermal_trip(tz, count);
+
+       monitor_thermal_zone(tz);
+}
+
 static int thermal_zone_device_set_mode(struct thermal_zone_device *tz,
                                        enum thermal_device_mode mode)
 {
@@ -423,9 +451,9 @@ static int thermal_zone_device_set_mode(struct thermal_zone_device *tz,
        if (!ret)
                tz->mode = mode;
 
-       mutex_unlock(&tz->lock);
+       __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
 
-       thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
+       mutex_unlock(&tz->lock);
 
        if (mode == THERMAL_DEVICE_ENABLED)
                thermal_notify_tz_enable(tz->id);
@@ -457,31 +485,8 @@ int thermal_zone_device_is_enabled(struct thermal_zone_device *tz)
 void thermal_zone_device_update(struct thermal_zone_device *tz,
                                enum thermal_notify_event event)
 {
-       int count;
-
-       if (atomic_read(&in_suspend))
-               return;
-
-       if (WARN_ONCE(!tz->ops->get_temp, "'%s' must not be called without "
-                     "'get_temp' ops set\n", __func__))
-               return;
-
        mutex_lock(&tz->lock);
-
-       if (!thermal_zone_device_is_enabled(tz))
-               goto out;
-
-       update_temperature(tz);
-
-       __thermal_zone_set_trips(tz);
-
-       tz->notify_event = event;
-
-       for (count = 0; count < tz->num_trips; count++)
-               handle_thermal_trip(tz, count);
-
-       monitor_thermal_zone(tz);
-out:
+       __thermal_zone_device_update(tz, event);
        mutex_unlock(&tz->lock);
 }
 EXPORT_SYMBOL_GPL(thermal_zone_device_update);