| From 737d2d4833f2e37ca2d92f7aad28571de44fe233 Mon Sep 17 00:00:00 2001 |
| From: Furquan Shaikh <furquan@google.com> |
| Date: Tue, 8 May 2018 22:33:39 -0700 |
| Subject: [PATCH] CHROMIUM: thermal: Add notifier call chain for hot/critical |
| events |
| |
| This will allow drivers to register a callback for important |
| thermal events and log critical thresholds that cause the system |
| to shut down. |
| |
| There are other places this might work, but after consideration |
| I think it makes sense to have the chain at this level: |
| |
| The ACPI thermal driver has an existing notify function that is |
| eventually called into, but that would limit the notifier to only |
| working on systems that use ACPI. |
| |
| The cpufreq driver is already getting a notify callback executed |
| in this path (tz->ops->notify) but the threshold info is not passed |
| to the cpu_cooling notifier chain so it is not useful for logging. |
| |
| BUG=b:79449188 |
| TEST=build ok, no visible changes in this commit |
| |
| [sonnyrao fixed up notifer calls for 3.8] |
| Signed-off-by: Duncan Laurie <dlaurie@chromium.org> |
| Reviewed-on: https://gerrit.chromium.org/gerrit/27775 |
| Reviewed-by: Olof Johansson <olofj@chromium.org> |
| Reviewed-by: Vincent Palatin <vpalatin@chromium.org> |
| [rebase44(groeck): Updated subject] |
| Signed-off-by: Guenter Roeck <groeck@chromium.org> |
| |
| Change-Id: I8806c0bf844a08580d936d971aa80a3ec579080a |
| Signed-off-by: Furquan Shaikh <furquan@google.com> |
| Reviewed-on: https://chromium-review.googlesource.com/1051260 |
| Commit-Ready: Furquan Shaikh <furquan@chromium.org> |
| Tested-by: Furquan Shaikh <furquan@chromium.org> |
| Reviewed-by: Aaron Durbin <adurbin@chromium.org> |
| |
| Conflicts: |
| drivers/thermal/thermal_core.c |
| (handle_non_critical_trips argument change) |
| |
| [rebase54(groeck): Fix conflict] |
| Signed-off-by: Guenter Roeck <groeck@chromium.org> |
| Change-Id: I6f7ac14e028767671492f1669e0f6816e642b443 |
| --- |
| drivers/thermal/thermal_core.c | 42 ++++++++++++++++++++++++++++++++-- |
| include/linux/thermal.h | 4 ++++ |
| 2 files changed, 44 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c |
| index 117eeaf7dd241e82ca1401ae39501a4c46896bb5..82c532da6f1948d9c4f4092e38bd8588d33fcf85 100644 |
| --- a/drivers/thermal/thermal_core.c |
| +++ b/drivers/thermal/thermal_core.c |
| @@ -15,6 +15,7 @@ |
| #include <linux/slab.h> |
| #include <linux/kdev_t.h> |
| #include <linux/idr.h> |
| +#include <linux/notifier.h> |
| #include <linux/thermal.h> |
| #include <linux/reboot.h> |
| #include <linux/string.h> |
| @@ -305,10 +306,44 @@ static void monitor_thermal_zone(struct thermal_zone_device *tz) |
| thermal_zone_device_set_polling(tz, tz->polling_delay_jiffies); |
| } |
| |
| -static void handle_non_critical_trips(struct thermal_zone_device *tz, int trip) |
| +BLOCKING_NOTIFIER_HEAD(thermal_notifier_list); |
| + |
| +/** |
| + * register_thermal_notifier - Register function to be called for |
| + * critical thermal events. |
| + * |
| + * @nb: Info about notifier function to be called |
| + * |
| + * Currently always returns zero, as blocking_notifier_chain_register() |
| + * always returns zero. |
| + */ |
| +int register_thermal_notifier(struct notifier_block *nb) |
| +{ |
| + return blocking_notifier_chain_register(&thermal_notifier_list, nb); |
| +} |
| +EXPORT_SYMBOL(register_thermal_notifier); |
| + |
| +/** |
| + * unregister_thermal_notifier - Unregister thermal notifier |
| + * |
| + * @nb: Hook to be unregistered |
| + * |
| + * Returns zero on success, or %-ENOENT on failure. |
| + */ |
| +int unregister_thermal_notifier(struct notifier_block *nb) |
| +{ |
| + return blocking_notifier_chain_unregister(&thermal_notifier_list, nb); |
| +} |
| +EXPORT_SYMBOL(unregister_thermal_notifier); |
| + |
| +static void handle_non_critical_trips(struct thermal_zone_device *tz, int trip, |
| + enum thermal_trip_type trip_type) |
| { |
| tz->governor ? tz->governor->throttle(tz, trip) : |
| def_governor->throttle(tz, trip); |
| + |
| + blocking_notifier_call_chain(&thermal_notifier_list, |
| + trip_type, NULL); |
| } |
| |
| void thermal_zone_device_critical(struct thermal_zone_device *tz) |
| @@ -335,6 +370,9 @@ static void handle_critical_trips(struct thermal_zone_device *tz, |
| |
| trace_thermal_zone_trip(tz, trip, trip_type); |
| |
| + blocking_notifier_call_chain(&thermal_notifier_list, |
| + trip_type, NULL); |
| + |
| if (trip_type == THERMAL_TRIP_HOT && tz->ops->hot) |
| tz->ops->hot(tz); |
| else if (trip_type == THERMAL_TRIP_CRITICAL) |
| @@ -369,7 +407,7 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip) |
| if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT) |
| handle_critical_trips(tz, trip, trip_temp, type); |
| else |
| - handle_non_critical_trips(tz, trip); |
| + handle_non_critical_trips(tz, trip, type); |
| } |
| |
| static void update_temperature(struct thermal_zone_device *tz) |
| diff --git a/include/linux/thermal.h b/include/linux/thermal.h |
| index 9ecc128944a19ba222cbaf043ec0fa2d9f812788..8eeaf7275981e1d35ea5714b3acc89b265224c67 100644 |
| --- a/include/linux/thermal.h |
| +++ b/include/linux/thermal.h |
| @@ -13,6 +13,7 @@ |
| #include <linux/of.h> |
| #include <linux/idr.h> |
| #include <linux/device.h> |
| +#include <linux/notifier.h> |
| #include <linux/sysfs.h> |
| #include <linux/workqueue.h> |
| #include <uapi/linux/thermal.h> |
| @@ -423,4 +424,7 @@ static inline int thermal_zone_device_disable(struct thermal_zone_device *tz) |
| { return -ENODEV; } |
| #endif /* CONFIG_THERMAL */ |
| |
| +extern int register_thermal_notifier(struct notifier_block *); |
| +extern int unregister_thermal_notifier(struct notifier_block *); |
| + |
| #endif /* __THERMAL_H__ */ |
| -- |
| 2.38.1.584.g0f3c55d4c2-goog |
| |