diff options
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/cpu_cooling.h | 39 | ||||
| -rw-r--r-- | include/linux/thermal.h | 97 |
2 files changed, 127 insertions, 9 deletions
diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h index bd955270d5aa..c156f5082758 100644 --- a/include/linux/cpu_cooling.h +++ b/include/linux/cpu_cooling.h | |||
| @@ -28,6 +28,9 @@ | |||
| 28 | #include <linux/thermal.h> | 28 | #include <linux/thermal.h> |
| 29 | #include <linux/cpumask.h> | 29 | #include <linux/cpumask.h> |
| 30 | 30 | ||
| 31 | typedef int (*get_static_t)(cpumask_t *cpumask, int interval, | ||
| 32 | unsigned long voltage, u32 *power); | ||
| 33 | |||
| 31 | #ifdef CONFIG_CPU_THERMAL | 34 | #ifdef CONFIG_CPU_THERMAL |
| 32 | /** | 35 | /** |
| 33 | * cpufreq_cooling_register - function to create cpufreq cooling device. | 36 | * cpufreq_cooling_register - function to create cpufreq cooling device. |
| @@ -36,6 +39,10 @@ | |||
| 36 | struct thermal_cooling_device * | 39 | struct thermal_cooling_device * |
| 37 | cpufreq_cooling_register(const struct cpumask *clip_cpus); | 40 | cpufreq_cooling_register(const struct cpumask *clip_cpus); |
| 38 | 41 | ||
| 42 | struct thermal_cooling_device * | ||
| 43 | cpufreq_power_cooling_register(const struct cpumask *clip_cpus, | ||
| 44 | u32 capacitance, get_static_t plat_static_func); | ||
| 45 | |||
| 39 | /** | 46 | /** |
| 40 | * of_cpufreq_cooling_register - create cpufreq cooling device based on DT. | 47 | * of_cpufreq_cooling_register - create cpufreq cooling device based on DT. |
| 41 | * @np: a valid struct device_node to the cooling device device tree node. | 48 | * @np: a valid struct device_node to the cooling device device tree node. |
| @@ -45,6 +52,12 @@ cpufreq_cooling_register(const struct cpumask *clip_cpus); | |||
| 45 | struct thermal_cooling_device * | 52 | struct thermal_cooling_device * |
| 46 | of_cpufreq_cooling_register(struct device_node *np, | 53 | of_cpufreq_cooling_register(struct device_node *np, |
| 47 | const struct cpumask *clip_cpus); | 54 | const struct cpumask *clip_cpus); |
| 55 | |||
| 56 | struct thermal_cooling_device * | ||
| 57 | of_cpufreq_power_cooling_register(struct device_node *np, | ||
| 58 | const struct cpumask *clip_cpus, | ||
| 59 | u32 capacitance, | ||
| 60 | get_static_t plat_static_func); | ||
| 48 | #else | 61 | #else |
| 49 | static inline struct thermal_cooling_device * | 62 | static inline struct thermal_cooling_device * |
| 50 | of_cpufreq_cooling_register(struct device_node *np, | 63 | of_cpufreq_cooling_register(struct device_node *np, |
| @@ -52,6 +65,15 @@ of_cpufreq_cooling_register(struct device_node *np, | |||
| 52 | { | 65 | { |
| 53 | return ERR_PTR(-ENOSYS); | 66 | return ERR_PTR(-ENOSYS); |
| 54 | } | 67 | } |
| 68 | |||
| 69 | static inline struct thermal_cooling_device * | ||
| 70 | of_cpufreq_power_cooling_register(struct device_node *np, | ||
| 71 | const struct cpumask *clip_cpus, | ||
| 72 | u32 capacitance, | ||
| 73 | get_static_t plat_static_func) | ||
| 74 | { | ||
| 75 | return NULL; | ||
| 76 | } | ||
| 55 | #endif | 77 | #endif |
| 56 | 78 | ||
| 57 | /** | 79 | /** |
| @@ -68,11 +90,28 @@ cpufreq_cooling_register(const struct cpumask *clip_cpus) | |||
| 68 | return ERR_PTR(-ENOSYS); | 90 | return ERR_PTR(-ENOSYS); |
| 69 | } | 91 | } |
| 70 | static inline struct thermal_cooling_device * | 92 | static inline struct thermal_cooling_device * |
| 93 | cpufreq_power_cooling_register(const struct cpumask *clip_cpus, | ||
| 94 | u32 capacitance, get_static_t plat_static_func) | ||
| 95 | { | ||
| 96 | return NULL; | ||
| 97 | } | ||
| 98 | |||
| 99 | static inline struct thermal_cooling_device * | ||
| 71 | of_cpufreq_cooling_register(struct device_node *np, | 100 | of_cpufreq_cooling_register(struct device_node *np, |
| 72 | const struct cpumask *clip_cpus) | 101 | const struct cpumask *clip_cpus) |
| 73 | { | 102 | { |
| 74 | return ERR_PTR(-ENOSYS); | 103 | return ERR_PTR(-ENOSYS); |
| 75 | } | 104 | } |
| 105 | |||
| 106 | static inline struct thermal_cooling_device * | ||
| 107 | of_cpufreq_power_cooling_register(struct device_node *np, | ||
| 108 | const struct cpumask *clip_cpus, | ||
| 109 | u32 capacitance, | ||
| 110 | get_static_t plat_static_func) | ||
| 111 | { | ||
| 112 | return NULL; | ||
| 113 | } | ||
| 114 | |||
| 76 | static inline | 115 | static inline |
| 77 | void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) | 116 | void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) |
| 78 | { | 117 | { |
diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 5eac316490ea..037e9df2f610 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h | |||
| @@ -40,6 +40,9 @@ | |||
| 40 | /* No upper/lower limit requirement */ | 40 | /* No upper/lower limit requirement */ |
| 41 | #define THERMAL_NO_LIMIT ((u32)~0) | 41 | #define THERMAL_NO_LIMIT ((u32)~0) |
| 42 | 42 | ||
| 43 | /* Default weight of a bound cooling device */ | ||
| 44 | #define THERMAL_WEIGHT_DEFAULT 0 | ||
| 45 | |||
| 43 | /* Unit conversion macros */ | 46 | /* Unit conversion macros */ |
| 44 | #define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732 >= 0) ? \ | 47 | #define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732 >= 0) ? \ |
| 45 | ((long)t-2732+5)/10 : ((long)t-2732-5)/10) | 48 | ((long)t-2732+5)/10 : ((long)t-2732-5)/10) |
| @@ -56,10 +59,13 @@ | |||
| 56 | #define DEFAULT_THERMAL_GOVERNOR "fair_share" | 59 | #define DEFAULT_THERMAL_GOVERNOR "fair_share" |
| 57 | #elif defined(CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE) | 60 | #elif defined(CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE) |
| 58 | #define DEFAULT_THERMAL_GOVERNOR "user_space" | 61 | #define DEFAULT_THERMAL_GOVERNOR "user_space" |
| 62 | #elif defined(CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR) | ||
| 63 | #define DEFAULT_THERMAL_GOVERNOR "power_allocator" | ||
| 59 | #endif | 64 | #endif |
| 60 | 65 | ||
| 61 | struct thermal_zone_device; | 66 | struct thermal_zone_device; |
| 62 | struct thermal_cooling_device; | 67 | struct thermal_cooling_device; |
| 68 | struct thermal_instance; | ||
| 63 | 69 | ||
| 64 | enum thermal_device_mode { | 70 | enum thermal_device_mode { |
| 65 | THERMAL_DEVICE_DISABLED = 0, | 71 | THERMAL_DEVICE_DISABLED = 0, |
| @@ -113,6 +119,12 @@ struct thermal_cooling_device_ops { | |||
| 113 | int (*get_max_state) (struct thermal_cooling_device *, unsigned long *); | 119 | int (*get_max_state) (struct thermal_cooling_device *, unsigned long *); |
| 114 | int (*get_cur_state) (struct thermal_cooling_device *, unsigned long *); | 120 | int (*get_cur_state) (struct thermal_cooling_device *, unsigned long *); |
| 115 | int (*set_cur_state) (struct thermal_cooling_device *, unsigned long); | 121 | int (*set_cur_state) (struct thermal_cooling_device *, unsigned long); |
| 122 | int (*get_requested_power)(struct thermal_cooling_device *, | ||
| 123 | struct thermal_zone_device *, u32 *); | ||
| 124 | int (*state2power)(struct thermal_cooling_device *, | ||
| 125 | struct thermal_zone_device *, unsigned long, u32 *); | ||
| 126 | int (*power2state)(struct thermal_cooling_device *, | ||
| 127 | struct thermal_zone_device *, u32, unsigned long *); | ||
| 116 | }; | 128 | }; |
| 117 | 129 | ||
| 118 | struct thermal_cooling_device { | 130 | struct thermal_cooling_device { |
| @@ -144,8 +156,7 @@ struct thermal_attr { | |||
| 144 | * @devdata: private pointer for device private data | 156 | * @devdata: private pointer for device private data |
| 145 | * @trips: number of trip points the thermal zone supports | 157 | * @trips: number of trip points the thermal zone supports |
| 146 | * @passive_delay: number of milliseconds to wait between polls when | 158 | * @passive_delay: number of milliseconds to wait between polls when |
| 147 | * performing passive cooling. Currenty only used by the | 159 | * performing passive cooling. |
| 148 | * step-wise governor | ||
| 149 | * @polling_delay: number of milliseconds to wait between polls when | 160 | * @polling_delay: number of milliseconds to wait between polls when |
| 150 | * checking whether trip points have been crossed (0 for | 161 | * checking whether trip points have been crossed (0 for |
| 151 | * interrupt driven systems) | 162 | * interrupt driven systems) |
| @@ -155,13 +166,13 @@ struct thermal_attr { | |||
| 155 | * @last_temperature: previous temperature read | 166 | * @last_temperature: previous temperature read |
| 156 | * @emul_temperature: emulated temperature when using CONFIG_THERMAL_EMULATION | 167 | * @emul_temperature: emulated temperature when using CONFIG_THERMAL_EMULATION |
| 157 | * @passive: 1 if you've crossed a passive trip point, 0 otherwise. | 168 | * @passive: 1 if you've crossed a passive trip point, 0 otherwise. |
| 158 | * Currenty only used by the step-wise governor. | ||
| 159 | * @forced_passive: If > 0, temperature at which to switch on all ACPI | 169 | * @forced_passive: If > 0, temperature at which to switch on all ACPI |
| 160 | * processor cooling devices. Currently only used by the | 170 | * processor cooling devices. Currently only used by the |
| 161 | * step-wise governor. | 171 | * step-wise governor. |
| 162 | * @ops: operations this &thermal_zone_device supports | 172 | * @ops: operations this &thermal_zone_device supports |
| 163 | * @tzp: thermal zone parameters | 173 | * @tzp: thermal zone parameters |
| 164 | * @governor: pointer to the governor for this thermal zone | 174 | * @governor: pointer to the governor for this thermal zone |
| 175 | * @governor_data: private pointer for governor data | ||
| 165 | * @thermal_instances: list of &struct thermal_instance of this thermal zone | 176 | * @thermal_instances: list of &struct thermal_instance of this thermal zone |
| 166 | * @idr: &struct idr to generate unique id for this zone's cooling | 177 | * @idr: &struct idr to generate unique id for this zone's cooling |
| 167 | * devices | 178 | * devices |
| @@ -186,8 +197,9 @@ struct thermal_zone_device { | |||
| 186 | int passive; | 197 | int passive; |
| 187 | unsigned int forced_passive; | 198 | unsigned int forced_passive; |
| 188 | struct thermal_zone_device_ops *ops; | 199 | struct thermal_zone_device_ops *ops; |
| 189 | const struct thermal_zone_params *tzp; | 200 | struct thermal_zone_params *tzp; |
| 190 | struct thermal_governor *governor; | 201 | struct thermal_governor *governor; |
| 202 | void *governor_data; | ||
| 191 | struct list_head thermal_instances; | 203 | struct list_head thermal_instances; |
| 192 | struct idr idr; | 204 | struct idr idr; |
| 193 | struct mutex lock; | 205 | struct mutex lock; |
| @@ -198,12 +210,19 @@ struct thermal_zone_device { | |||
| 198 | /** | 210 | /** |
| 199 | * struct thermal_governor - structure that holds thermal governor information | 211 | * struct thermal_governor - structure that holds thermal governor information |
| 200 | * @name: name of the governor | 212 | * @name: name of the governor |
| 213 | * @bind_to_tz: callback called when binding to a thermal zone. If it | ||
| 214 | * returns 0, the governor is bound to the thermal zone, | ||
| 215 | * otherwise it fails. | ||
| 216 | * @unbind_from_tz: callback called when a governor is unbound from a | ||
| 217 | * thermal zone. | ||
| 201 | * @throttle: callback called for every trip point even if temperature is | 218 | * @throttle: callback called for every trip point even if temperature is |
| 202 | * below the trip point temperature | 219 | * below the trip point temperature |
| 203 | * @governor_list: node in thermal_governor_list (in thermal_core.c) | 220 | * @governor_list: node in thermal_governor_list (in thermal_core.c) |
| 204 | */ | 221 | */ |
| 205 | struct thermal_governor { | 222 | struct thermal_governor { |
| 206 | char name[THERMAL_NAME_LENGTH]; | 223 | char name[THERMAL_NAME_LENGTH]; |
| 224 | int (*bind_to_tz)(struct thermal_zone_device *tz); | ||
| 225 | void (*unbind_from_tz)(struct thermal_zone_device *tz); | ||
| 207 | int (*throttle)(struct thermal_zone_device *tz, int trip); | 226 | int (*throttle)(struct thermal_zone_device *tz, int trip); |
| 208 | struct list_head governor_list; | 227 | struct list_head governor_list; |
| 209 | }; | 228 | }; |
| @@ -214,9 +233,12 @@ struct thermal_bind_params { | |||
| 214 | 233 | ||
| 215 | /* | 234 | /* |
| 216 | * This is a measure of 'how effectively these devices can | 235 | * This is a measure of 'how effectively these devices can |
| 217 | * cool 'this' thermal zone. The shall be determined by platform | 236 | * cool 'this' thermal zone. It shall be determined by |
| 218 | * characterization. This is on a 'percentage' scale. | 237 | * platform characterization. This value is relative to the |
| 219 | * See Documentation/thermal/sysfs-api.txt for more information. | 238 | * rest of the weights so a cooling device whose weight is |
| 239 | * double that of another cooling device is twice as | ||
| 240 | * effective. See Documentation/thermal/sysfs-api.txt for more | ||
| 241 | * information. | ||
| 220 | */ | 242 | */ |
| 221 | int weight; | 243 | int weight; |
| 222 | 244 | ||
| @@ -253,6 +275,44 @@ struct thermal_zone_params { | |||
| 253 | 275 | ||
| 254 | int num_tbps; /* Number of tbp entries */ | 276 | int num_tbps; /* Number of tbp entries */ |
| 255 | struct thermal_bind_params *tbp; | 277 | struct thermal_bind_params *tbp; |
| 278 | |||
| 279 | /* | ||
| 280 | * Sustainable power (heat) that this thermal zone can dissipate in | ||
| 281 | * mW | ||
| 282 | */ | ||
| 283 | u32 sustainable_power; | ||
| 284 | |||
| 285 | /* | ||
| 286 | * Proportional parameter of the PID controller when | ||
| 287 | * overshooting (i.e., when temperature is below the target) | ||
| 288 | */ | ||
| 289 | s32 k_po; | ||
| 290 | |||
| 291 | /* | ||
| 292 | * Proportional parameter of the PID controller when | ||
| 293 | * undershooting | ||
| 294 | */ | ||
| 295 | s32 k_pu; | ||
| 296 | |||
| 297 | /* Integral parameter of the PID controller */ | ||
| 298 | s32 k_i; | ||
| 299 | |||
| 300 | /* Derivative parameter of the PID controller */ | ||
| 301 | s32 k_d; | ||
| 302 | |||
| 303 | /* threshold below which the error is no longer accumulated */ | ||
| 304 | s32 integral_cutoff; | ||
| 305 | |||
| 306 | /* | ||
| 307 | * @slope: slope of a linear temperature adjustment curve. | ||
| 308 | * Used by thermal zone drivers. | ||
| 309 | */ | ||
| 310 | int slope; | ||
| 311 | /* | ||
| 312 | * @offset: offset of a linear temperature adjustment curve. | ||
| 313 | * Used by thermal zone drivers (default 0). | ||
| 314 | */ | ||
| 315 | int offset; | ||
| 256 | }; | 316 | }; |
| 257 | 317 | ||
| 258 | struct thermal_genl_event { | 318 | struct thermal_genl_event { |
| @@ -316,14 +376,25 @@ void thermal_zone_of_sensor_unregister(struct device *dev, | |||
| 316 | #endif | 376 | #endif |
| 317 | 377 | ||
| 318 | #if IS_ENABLED(CONFIG_THERMAL) | 378 | #if IS_ENABLED(CONFIG_THERMAL) |
| 379 | static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) | ||
| 380 | { | ||
| 381 | return cdev->ops->get_requested_power && cdev->ops->state2power && | ||
| 382 | cdev->ops->power2state; | ||
| 383 | } | ||
| 384 | |||
| 385 | int power_actor_get_max_power(struct thermal_cooling_device *, | ||
| 386 | struct thermal_zone_device *tz, u32 *max_power); | ||
| 387 | int power_actor_set_power(struct thermal_cooling_device *, | ||
| 388 | struct thermal_instance *, u32); | ||
| 319 | struct thermal_zone_device *thermal_zone_device_register(const char *, int, int, | 389 | struct thermal_zone_device *thermal_zone_device_register(const char *, int, int, |
| 320 | void *, struct thermal_zone_device_ops *, | 390 | void *, struct thermal_zone_device_ops *, |
| 321 | const struct thermal_zone_params *, int, int); | 391 | struct thermal_zone_params *, int, int); |
| 322 | void thermal_zone_device_unregister(struct thermal_zone_device *); | 392 | void thermal_zone_device_unregister(struct thermal_zone_device *); |
| 323 | 393 | ||
| 324 | int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int, | 394 | int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int, |
| 325 | struct thermal_cooling_device *, | 395 | struct thermal_cooling_device *, |
| 326 | unsigned long, unsigned long); | 396 | unsigned long, unsigned long, |
| 397 | unsigned int); | ||
| 327 | int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int, | 398 | int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int, |
| 328 | struct thermal_cooling_device *); | 399 | struct thermal_cooling_device *); |
| 329 | void thermal_zone_device_update(struct thermal_zone_device *); | 400 | void thermal_zone_device_update(struct thermal_zone_device *); |
| @@ -343,6 +414,14 @@ struct thermal_instance *get_thermal_instance(struct thermal_zone_device *, | |||
| 343 | void thermal_cdev_update(struct thermal_cooling_device *); | 414 | void thermal_cdev_update(struct thermal_cooling_device *); |
| 344 | void thermal_notify_framework(struct thermal_zone_device *, int); | 415 | void thermal_notify_framework(struct thermal_zone_device *, int); |
| 345 | #else | 416 | #else |
| 417 | static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) | ||
| 418 | { return false; } | ||
| 419 | static inline int power_actor_get_max_power(struct thermal_cooling_device *cdev, | ||
| 420 | struct thermal_zone_device *tz, u32 *max_power) | ||
| 421 | { return 0; } | ||
| 422 | static inline int power_actor_set_power(struct thermal_cooling_device *cdev, | ||
| 423 | struct thermal_instance *tz, u32 power) | ||
| 424 | { return 0; } | ||
| 346 | static inline struct thermal_zone_device *thermal_zone_device_register( | 425 | static inline struct thermal_zone_device *thermal_zone_device_register( |
| 347 | const char *type, int trips, int mask, void *devdata, | 426 | const char *type, int trips, int mask, void *devdata, |
| 348 | struct thermal_zone_device_ops *ops, | 427 | struct thermal_zone_device_ops *ops, |
