Commit a8c95940 authored by Lukasz Luba's avatar Lukasz Luba Committed by Rafael J. Wysocki

thermal: core: Add governor callback for thermal zone change

Add a new callback to the struct thermal_governor. It can be used for
updating governors when there is a change in the thermal zone internals,
e.g. thermal cooling device is bind to the thermal zone.

That makes possible to move some heavy operations like memory allocations
related to the number of cooling instances out of the throttle() callback.

Both callback code paths (throttle() and update_tz()) are protected with
the same thermal zone lock, which guaranties the consistency.
Signed-off-by: default avatarLukasz Luba <lukasz.luba@arm.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 04c3b030
...@@ -309,6 +309,15 @@ static void handle_non_critical_trips(struct thermal_zone_device *tz, ...@@ -309,6 +309,15 @@ static void handle_non_critical_trips(struct thermal_zone_device *tz,
def_governor->throttle(tz, trip); def_governor->throttle(tz, trip);
} }
void thermal_governor_update_tz(struct thermal_zone_device *tz,
enum thermal_notify_event reason)
{
if (!tz->governor || !tz->governor->update_tz)
return;
tz->governor->update_tz(tz, reason);
}
void thermal_zone_device_critical(struct thermal_zone_device *tz) void thermal_zone_device_critical(struct thermal_zone_device *tz)
{ {
/* /*
...@@ -715,6 +724,8 @@ int thermal_bind_cdev_to_trip(struct thermal_zone_device *tz, ...@@ -715,6 +724,8 @@ int thermal_bind_cdev_to_trip(struct thermal_zone_device *tz,
list_add_tail(&dev->tz_node, &tz->thermal_instances); list_add_tail(&dev->tz_node, &tz->thermal_instances);
list_add_tail(&dev->cdev_node, &cdev->thermal_instances); list_add_tail(&dev->cdev_node, &cdev->thermal_instances);
atomic_set(&tz->need_update, 1); atomic_set(&tz->need_update, 1);
thermal_governor_update_tz(tz, THERMAL_TZ_BIND_CDEV);
} }
mutex_unlock(&cdev->lock); mutex_unlock(&cdev->lock);
mutex_unlock(&tz->lock); mutex_unlock(&tz->lock);
...@@ -773,6 +784,9 @@ int thermal_unbind_cdev_from_trip(struct thermal_zone_device *tz, ...@@ -773,6 +784,9 @@ int thermal_unbind_cdev_from_trip(struct thermal_zone_device *tz,
if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) { if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
list_del(&pos->tz_node); list_del(&pos->tz_node);
list_del(&pos->cdev_node); list_del(&pos->cdev_node);
thermal_governor_update_tz(tz, THERMAL_TZ_UNBIND_CDEV);
mutex_unlock(&cdev->lock); mutex_unlock(&cdev->lock);
mutex_unlock(&tz->lock); mutex_unlock(&tz->lock);
goto unbind; goto unbind;
......
...@@ -114,6 +114,8 @@ int thermal_zone_device_set_policy(struct thermal_zone_device *, char *); ...@@ -114,6 +114,8 @@ int thermal_zone_device_set_policy(struct thermal_zone_device *, char *);
int thermal_build_list_of_policies(char *buf); int thermal_build_list_of_policies(char *buf);
void __thermal_zone_device_update(struct thermal_zone_device *tz, void __thermal_zone_device_update(struct thermal_zone_device *tz,
enum thermal_notify_event event); enum thermal_notify_event event);
void thermal_governor_update_tz(struct thermal_zone_device *tz,
enum thermal_notify_event reason);
/* Helpers */ /* Helpers */
#define for_each_trip(__tz, __trip) \ #define for_each_trip(__tz, __trip) \
......
...@@ -51,6 +51,8 @@ enum thermal_notify_event { ...@@ -51,6 +51,8 @@ enum thermal_notify_event {
THERMAL_DEVICE_POWER_CAPABILITY_CHANGED, /* power capability changed */ THERMAL_DEVICE_POWER_CAPABILITY_CHANGED, /* power capability changed */
THERMAL_TABLE_CHANGED, /* Thermal table(s) changed */ THERMAL_TABLE_CHANGED, /* Thermal table(s) changed */
THERMAL_EVENT_KEEP_ALIVE, /* Request for user space handler to respond */ THERMAL_EVENT_KEEP_ALIVE, /* Request for user space handler to respond */
THERMAL_TZ_BIND_CDEV, /* Cooling dev is bind to the thermal zone */
THERMAL_TZ_UNBIND_CDEV, /* Cooling dev is unbind from the thermal zone */
}; };
/** /**
...@@ -199,6 +201,8 @@ struct thermal_zone_device { ...@@ -199,6 +201,8 @@ struct thermal_zone_device {
* thermal zone. * thermal zone.
* @throttle: callback called for every trip point even if temperature is * @throttle: callback called for every trip point even if temperature is
* below the trip point temperature * below the trip point temperature
* @update_tz: callback called when thermal zone internals have changed, e.g.
* thermal cooling instance was added/removed
* @governor_list: node in thermal_governor_list (in thermal_core.c) * @governor_list: node in thermal_governor_list (in thermal_core.c)
*/ */
struct thermal_governor { struct thermal_governor {
...@@ -207,6 +211,8 @@ struct thermal_governor { ...@@ -207,6 +211,8 @@ struct thermal_governor {
void (*unbind_from_tz)(struct thermal_zone_device *tz); void (*unbind_from_tz)(struct thermal_zone_device *tz);
int (*throttle)(struct thermal_zone_device *tz, int (*throttle)(struct thermal_zone_device *tz,
const struct thermal_trip *trip); const struct thermal_trip *trip);
void (*update_tz)(struct thermal_zone_device *tz,
enum thermal_notify_event reason);
struct list_head governor_list; struct list_head governor_list;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment