at v4.4 17 kB view raw
1/* 2 * thermal.h ($Revision: 0 $) 3 * 4 * Copyright (C) 2008 Intel Corp 5 * Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com> 6 * Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com> 7 * 8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; version 2 of the License. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along 19 * with this program; if not, write to the Free Software Foundation, Inc., 20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 21 * 22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 23 */ 24 25#ifndef __THERMAL_H__ 26#define __THERMAL_H__ 27 28#include <linux/of.h> 29#include <linux/idr.h> 30#include <linux/device.h> 31#include <linux/workqueue.h> 32#include <uapi/linux/thermal.h> 33 34#define THERMAL_TRIPS_NONE -1 35#define THERMAL_MAX_TRIPS 12 36 37/* invalid cooling state */ 38#define THERMAL_CSTATE_INVALID -1UL 39 40/* No upper/lower limit requirement */ 41#define THERMAL_NO_LIMIT ((u32)~0) 42 43/* Default weight of a bound cooling device */ 44#define THERMAL_WEIGHT_DEFAULT 0 45 46/* Unit conversion macros */ 47#define DECI_KELVIN_TO_CELSIUS(t) ({ \ 48 long _t = (t); \ 49 ((_t-2732 >= 0) ? (_t-2732+5)/10 : (_t-2732-5)/10); \ 50}) 51#define CELSIUS_TO_DECI_KELVIN(t) ((t)*10+2732) 52#define DECI_KELVIN_TO_MILLICELSIUS_WITH_OFFSET(t, off) (((t) - (off)) * 100) 53#define DECI_KELVIN_TO_MILLICELSIUS(t) DECI_KELVIN_TO_MILLICELSIUS_WITH_OFFSET(t, 2732) 54#define MILLICELSIUS_TO_DECI_KELVIN_WITH_OFFSET(t, off) (((t) / 100) + (off)) 55#define MILLICELSIUS_TO_DECI_KELVIN(t) MILLICELSIUS_TO_DECI_KELVIN_WITH_OFFSET(t, 2732) 56 57/* Default Thermal Governor */ 58#if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE) 59#define DEFAULT_THERMAL_GOVERNOR "step_wise" 60#elif defined(CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE) 61#define DEFAULT_THERMAL_GOVERNOR "fair_share" 62#elif defined(CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE) 63#define DEFAULT_THERMAL_GOVERNOR "user_space" 64#elif defined(CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR) 65#define DEFAULT_THERMAL_GOVERNOR "power_allocator" 66#endif 67 68struct thermal_zone_device; 69struct thermal_cooling_device; 70struct thermal_instance; 71 72enum thermal_device_mode { 73 THERMAL_DEVICE_DISABLED = 0, 74 THERMAL_DEVICE_ENABLED, 75}; 76 77enum thermal_trip_type { 78 THERMAL_TRIP_ACTIVE = 0, 79 THERMAL_TRIP_PASSIVE, 80 THERMAL_TRIP_HOT, 81 THERMAL_TRIP_CRITICAL, 82}; 83 84enum thermal_trend { 85 THERMAL_TREND_STABLE, /* temperature is stable */ 86 THERMAL_TREND_RAISING, /* temperature is raising */ 87 THERMAL_TREND_DROPPING, /* temperature is dropping */ 88 THERMAL_TREND_RAISE_FULL, /* apply highest cooling action */ 89 THERMAL_TREND_DROP_FULL, /* apply lowest cooling action */ 90}; 91 92struct thermal_zone_device_ops { 93 int (*bind) (struct thermal_zone_device *, 94 struct thermal_cooling_device *); 95 int (*unbind) (struct thermal_zone_device *, 96 struct thermal_cooling_device *); 97 int (*get_temp) (struct thermal_zone_device *, int *); 98 int (*get_mode) (struct thermal_zone_device *, 99 enum thermal_device_mode *); 100 int (*set_mode) (struct thermal_zone_device *, 101 enum thermal_device_mode); 102 int (*get_trip_type) (struct thermal_zone_device *, int, 103 enum thermal_trip_type *); 104 int (*get_trip_temp) (struct thermal_zone_device *, int, int *); 105 int (*set_trip_temp) (struct thermal_zone_device *, int, int); 106 int (*get_trip_hyst) (struct thermal_zone_device *, int, int *); 107 int (*set_trip_hyst) (struct thermal_zone_device *, int, int); 108 int (*get_crit_temp) (struct thermal_zone_device *, int *); 109 int (*set_emul_temp) (struct thermal_zone_device *, int); 110 int (*get_trend) (struct thermal_zone_device *, int, 111 enum thermal_trend *); 112 int (*notify) (struct thermal_zone_device *, int, 113 enum thermal_trip_type); 114}; 115 116struct thermal_cooling_device_ops { 117 int (*get_max_state) (struct thermal_cooling_device *, unsigned long *); 118 int (*get_cur_state) (struct thermal_cooling_device *, unsigned long *); 119 int (*set_cur_state) (struct thermal_cooling_device *, unsigned long); 120 int (*get_requested_power)(struct thermal_cooling_device *, 121 struct thermal_zone_device *, u32 *); 122 int (*state2power)(struct thermal_cooling_device *, 123 struct thermal_zone_device *, unsigned long, u32 *); 124 int (*power2state)(struct thermal_cooling_device *, 125 struct thermal_zone_device *, u32, unsigned long *); 126}; 127 128struct thermal_cooling_device { 129 int id; 130 char type[THERMAL_NAME_LENGTH]; 131 struct device device; 132 struct device_node *np; 133 void *devdata; 134 const struct thermal_cooling_device_ops *ops; 135 bool updated; /* true if the cooling device does not need update */ 136 struct mutex lock; /* protect thermal_instances list */ 137 struct list_head thermal_instances; 138 struct list_head node; 139}; 140 141struct thermal_attr { 142 struct device_attribute attr; 143 char name[THERMAL_NAME_LENGTH]; 144}; 145 146/** 147 * struct thermal_zone_device - structure for a thermal zone 148 * @id: unique id number for each thermal zone 149 * @type: the thermal zone device type 150 * @device: &struct device for this thermal zone 151 * @trip_temp_attrs: attributes for trip points for sysfs: trip temperature 152 * @trip_type_attrs: attributes for trip points for sysfs: trip type 153 * @trip_hyst_attrs: attributes for trip points for sysfs: trip hysteresis 154 * @devdata: private pointer for device private data 155 * @trips: number of trip points the thermal zone supports 156 * @passive_delay: number of milliseconds to wait between polls when 157 * performing passive cooling. 158 * @polling_delay: number of milliseconds to wait between polls when 159 * checking whether trip points have been crossed (0 for 160 * interrupt driven systems) 161 * @temperature: current temperature. This is only for core code, 162 * drivers should use thermal_zone_get_temp() to get the 163 * current temperature 164 * @last_temperature: previous temperature read 165 * @emul_temperature: emulated temperature when using CONFIG_THERMAL_EMULATION 166 * @passive: 1 if you've crossed a passive trip point, 0 otherwise. 167 * @forced_passive: If > 0, temperature at which to switch on all ACPI 168 * processor cooling devices. Currently only used by the 169 * step-wise governor. 170 * @ops: operations this &thermal_zone_device supports 171 * @tzp: thermal zone parameters 172 * @governor: pointer to the governor for this thermal zone 173 * @governor_data: private pointer for governor data 174 * @thermal_instances: list of &struct thermal_instance of this thermal zone 175 * @idr: &struct idr to generate unique id for this zone's cooling 176 * devices 177 * @lock: lock to protect thermal_instances list 178 * @node: node in thermal_tz_list (in thermal_core.c) 179 * @poll_queue: delayed work for polling 180 */ 181struct thermal_zone_device { 182 int id; 183 char type[THERMAL_NAME_LENGTH]; 184 struct device device; 185 struct thermal_attr *trip_temp_attrs; 186 struct thermal_attr *trip_type_attrs; 187 struct thermal_attr *trip_hyst_attrs; 188 void *devdata; 189 int trips; 190 int passive_delay; 191 int polling_delay; 192 int temperature; 193 int last_temperature; 194 int emul_temperature; 195 int passive; 196 unsigned int forced_passive; 197 struct thermal_zone_device_ops *ops; 198 struct thermal_zone_params *tzp; 199 struct thermal_governor *governor; 200 void *governor_data; 201 struct list_head thermal_instances; 202 struct idr idr; 203 struct mutex lock; 204 struct list_head node; 205 struct delayed_work poll_queue; 206}; 207 208/** 209 * struct thermal_governor - structure that holds thermal governor information 210 * @name: name of the governor 211 * @bind_to_tz: callback called when binding to a thermal zone. If it 212 * returns 0, the governor is bound to the thermal zone, 213 * otherwise it fails. 214 * @unbind_from_tz: callback called when a governor is unbound from a 215 * thermal zone. 216 * @throttle: callback called for every trip point even if temperature is 217 * below the trip point temperature 218 * @governor_list: node in thermal_governor_list (in thermal_core.c) 219 */ 220struct thermal_governor { 221 char name[THERMAL_NAME_LENGTH]; 222 int (*bind_to_tz)(struct thermal_zone_device *tz); 223 void (*unbind_from_tz)(struct thermal_zone_device *tz); 224 int (*throttle)(struct thermal_zone_device *tz, int trip); 225 struct list_head governor_list; 226}; 227 228/* Structure that holds binding parameters for a zone */ 229struct thermal_bind_params { 230 struct thermal_cooling_device *cdev; 231 232 /* 233 * This is a measure of 'how effectively these devices can 234 * cool 'this' thermal zone. It shall be determined by 235 * platform characterization. This value is relative to the 236 * rest of the weights so a cooling device whose weight is 237 * double that of another cooling device is twice as 238 * effective. See Documentation/thermal/sysfs-api.txt for more 239 * information. 240 */ 241 int weight; 242 243 /* 244 * This is a bit mask that gives the binding relation between this 245 * thermal zone and cdev, for a particular trip point. 246 * See Documentation/thermal/sysfs-api.txt for more information. 247 */ 248 int trip_mask; 249 250 /* 251 * This is an array of cooling state limits. Must have exactly 252 * 2 * thermal_zone.number_of_trip_points. It is an array consisting 253 * of tuples <lower-state upper-state> of state limits. Each trip 254 * will be associated with one state limit tuple when binding. 255 * A NULL pointer means <THERMAL_NO_LIMITS THERMAL_NO_LIMITS> 256 * on all trips. 257 */ 258 unsigned long *binding_limits; 259 int (*match) (struct thermal_zone_device *tz, 260 struct thermal_cooling_device *cdev); 261}; 262 263/* Structure to define Thermal Zone parameters */ 264struct thermal_zone_params { 265 char governor_name[THERMAL_NAME_LENGTH]; 266 267 /* 268 * a boolean to indicate if the thermal to hwmon sysfs interface 269 * is required. when no_hwmon == false, a hwmon sysfs interface 270 * will be created. when no_hwmon == true, nothing will be done 271 */ 272 bool no_hwmon; 273 274 int num_tbps; /* Number of tbp entries */ 275 struct thermal_bind_params *tbp; 276 277 /* 278 * Sustainable power (heat) that this thermal zone can dissipate in 279 * mW 280 */ 281 u32 sustainable_power; 282 283 /* 284 * Proportional parameter of the PID controller when 285 * overshooting (i.e., when temperature is below the target) 286 */ 287 s32 k_po; 288 289 /* 290 * Proportional parameter of the PID controller when 291 * undershooting 292 */ 293 s32 k_pu; 294 295 /* Integral parameter of the PID controller */ 296 s32 k_i; 297 298 /* Derivative parameter of the PID controller */ 299 s32 k_d; 300 301 /* threshold below which the error is no longer accumulated */ 302 s32 integral_cutoff; 303 304 /* 305 * @slope: slope of a linear temperature adjustment curve. 306 * Used by thermal zone drivers. 307 */ 308 int slope; 309 /* 310 * @offset: offset of a linear temperature adjustment curve. 311 * Used by thermal zone drivers (default 0). 312 */ 313 int offset; 314}; 315 316struct thermal_genl_event { 317 u32 orig; 318 enum events event; 319}; 320 321/** 322 * struct thermal_zone_of_device_ops - scallbacks for handling DT based zones 323 * 324 * Mandatory: 325 * @get_temp: a pointer to a function that reads the sensor temperature. 326 * 327 * Optional: 328 * @get_trend: a pointer to a function that reads the sensor temperature trend. 329 * @set_emul_temp: a pointer to a function that sets sensor emulated 330 * temperature. 331 */ 332struct thermal_zone_of_device_ops { 333 int (*get_temp)(void *, int *); 334 int (*get_trend)(void *, long *); 335 int (*set_emul_temp)(void *, int); 336}; 337 338/** 339 * struct thermal_trip - representation of a point in temperature domain 340 * @np: pointer to struct device_node that this trip point was created from 341 * @temperature: temperature value in miliCelsius 342 * @hysteresis: relative hysteresis in miliCelsius 343 * @type: trip point type 344 */ 345 346struct thermal_trip { 347 struct device_node *np; 348 unsigned long int temperature; 349 unsigned long int hysteresis; 350 enum thermal_trip_type type; 351}; 352 353/* Function declarations */ 354#ifdef CONFIG_THERMAL_OF 355struct thermal_zone_device * 356thermal_zone_of_sensor_register(struct device *dev, int id, void *data, 357 const struct thermal_zone_of_device_ops *ops); 358void thermal_zone_of_sensor_unregister(struct device *dev, 359 struct thermal_zone_device *tz); 360#else 361static inline struct thermal_zone_device * 362thermal_zone_of_sensor_register(struct device *dev, int id, void *data, 363 const struct thermal_zone_of_device_ops *ops) 364{ 365 return ERR_PTR(-ENODEV); 366} 367 368static inline 369void thermal_zone_of_sensor_unregister(struct device *dev, 370 struct thermal_zone_device *tz) 371{ 372} 373 374#endif 375 376#if IS_ENABLED(CONFIG_THERMAL) 377static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) 378{ 379 return cdev->ops->get_requested_power && cdev->ops->state2power && 380 cdev->ops->power2state; 381} 382 383int power_actor_get_max_power(struct thermal_cooling_device *, 384 struct thermal_zone_device *tz, u32 *max_power); 385int power_actor_get_min_power(struct thermal_cooling_device *, 386 struct thermal_zone_device *tz, u32 *min_power); 387int power_actor_set_power(struct thermal_cooling_device *, 388 struct thermal_instance *, u32); 389struct thermal_zone_device *thermal_zone_device_register(const char *, int, int, 390 void *, struct thermal_zone_device_ops *, 391 struct thermal_zone_params *, int, int); 392void thermal_zone_device_unregister(struct thermal_zone_device *); 393 394int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int, 395 struct thermal_cooling_device *, 396 unsigned long, unsigned long, 397 unsigned int); 398int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int, 399 struct thermal_cooling_device *); 400void thermal_zone_device_update(struct thermal_zone_device *); 401 402struct thermal_cooling_device *thermal_cooling_device_register(char *, void *, 403 const struct thermal_cooling_device_ops *); 404struct thermal_cooling_device * 405thermal_of_cooling_device_register(struct device_node *np, char *, void *, 406 const struct thermal_cooling_device_ops *); 407void thermal_cooling_device_unregister(struct thermal_cooling_device *); 408struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name); 409int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp); 410 411int get_tz_trend(struct thermal_zone_device *, int); 412struct thermal_instance *get_thermal_instance(struct thermal_zone_device *, 413 struct thermal_cooling_device *, int); 414void thermal_cdev_update(struct thermal_cooling_device *); 415void thermal_notify_framework(struct thermal_zone_device *, int); 416#else 417static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) 418{ return false; } 419static inline int power_actor_get_max_power(struct thermal_cooling_device *cdev, 420 struct thermal_zone_device *tz, u32 *max_power) 421{ return 0; } 422static inline int power_actor_get_min_power(struct thermal_cooling_device *cdev, 423 struct thermal_zone_device *tz, 424 u32 *min_power) 425{ return -ENODEV; } 426static inline int power_actor_set_power(struct thermal_cooling_device *cdev, 427 struct thermal_instance *tz, u32 power) 428{ return 0; } 429static inline struct thermal_zone_device *thermal_zone_device_register( 430 const char *type, int trips, int mask, void *devdata, 431 struct thermal_zone_device_ops *ops, 432 const struct thermal_zone_params *tzp, 433 int passive_delay, int polling_delay) 434{ return ERR_PTR(-ENODEV); } 435static inline void thermal_zone_device_unregister( 436 struct thermal_zone_device *tz) 437{ } 438static inline int thermal_zone_bind_cooling_device( 439 struct thermal_zone_device *tz, int trip, 440 struct thermal_cooling_device *cdev, 441 unsigned long upper, unsigned long lower, 442 unsigned int weight) 443{ return -ENODEV; } 444static inline int thermal_zone_unbind_cooling_device( 445 struct thermal_zone_device *tz, int trip, 446 struct thermal_cooling_device *cdev) 447{ return -ENODEV; } 448static inline void thermal_zone_device_update(struct thermal_zone_device *tz) 449{ } 450static inline struct thermal_cooling_device * 451thermal_cooling_device_register(char *type, void *devdata, 452 const struct thermal_cooling_device_ops *ops) 453{ return ERR_PTR(-ENODEV); } 454static inline struct thermal_cooling_device * 455thermal_of_cooling_device_register(struct device_node *np, 456 char *type, void *devdata, const struct thermal_cooling_device_ops *ops) 457{ return ERR_PTR(-ENODEV); } 458static inline void thermal_cooling_device_unregister( 459 struct thermal_cooling_device *cdev) 460{ } 461static inline struct thermal_zone_device *thermal_zone_get_zone_by_name( 462 const char *name) 463{ return ERR_PTR(-ENODEV); } 464static inline int thermal_zone_get_temp( 465 struct thermal_zone_device *tz, int *temp) 466{ return -ENODEV; } 467static inline int get_tz_trend(struct thermal_zone_device *tz, int trip) 468{ return -ENODEV; } 469static inline struct thermal_instance * 470get_thermal_instance(struct thermal_zone_device *tz, 471 struct thermal_cooling_device *cdev, int trip) 472{ return ERR_PTR(-ENODEV); } 473static inline void thermal_cdev_update(struct thermal_cooling_device *cdev) 474{ } 475static inline void thermal_notify_framework(struct thermal_zone_device *tz, 476 int trip) 477{ } 478#endif /* CONFIG_THERMAL */ 479 480#if defined(CONFIG_NET) && IS_ENABLED(CONFIG_THERMAL) 481extern int thermal_generate_netlink_event(struct thermal_zone_device *tz, 482 enum events event); 483#else 484static inline int thermal_generate_netlink_event(struct thermal_zone_device *tz, 485 enum events event) 486{ 487 return 0; 488} 489#endif 490 491#endif /* __THERMAL_H__ */