Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  *  thermal.h  ($Revision: 0 $)
0004  *
0005  *  Copyright (C) 2008  Intel Corp
0006  *  Copyright (C) 2008  Zhang Rui <rui.zhang@intel.com>
0007  *  Copyright (C) 2008  Sujith Thomas <sujith.thomas@intel.com>
0008  */
0009 
0010 #ifndef __THERMAL_H__
0011 #define __THERMAL_H__
0012 
0013 #include <linux/of.h>
0014 #include <linux/idr.h>
0015 #include <linux/device.h>
0016 #include <linux/sysfs.h>
0017 #include <linux/workqueue.h>
0018 #include <uapi/linux/thermal.h>
0019 
0020 #define THERMAL_MAX_TRIPS   12
0021 
0022 /* invalid cooling state */
0023 #define THERMAL_CSTATE_INVALID -1UL
0024 
0025 /* No upper/lower limit requirement */
0026 #define THERMAL_NO_LIMIT    ((u32)~0)
0027 
0028 /* Default weight of a bound cooling device */
0029 #define THERMAL_WEIGHT_DEFAULT 0
0030 
0031 /* use value, which < 0K, to indicate an invalid/uninitialized temperature */
0032 #define THERMAL_TEMP_INVALID    -274000
0033 
0034 struct thermal_zone_device;
0035 struct thermal_cooling_device;
0036 struct thermal_instance;
0037 struct thermal_attr;
0038 
0039 enum thermal_trend {
0040     THERMAL_TREND_STABLE, /* temperature is stable */
0041     THERMAL_TREND_RAISING, /* temperature is raising */
0042     THERMAL_TREND_DROPPING, /* temperature is dropping */
0043 };
0044 
0045 /* Thermal notification reason */
0046 enum thermal_notify_event {
0047     THERMAL_EVENT_UNSPECIFIED, /* Unspecified event */
0048     THERMAL_EVENT_TEMP_SAMPLE, /* New Temperature sample */
0049     THERMAL_TRIP_VIOLATED, /* TRIP Point violation */
0050     THERMAL_TRIP_CHANGED, /* TRIP Point temperature changed */
0051     THERMAL_DEVICE_DOWN, /* Thermal device is down */
0052     THERMAL_DEVICE_UP, /* Thermal device is up after a down event */
0053     THERMAL_DEVICE_POWER_CAPABILITY_CHANGED, /* power capability changed */
0054     THERMAL_TABLE_CHANGED, /* Thermal table(s) changed */
0055     THERMAL_EVENT_KEEP_ALIVE, /* Request for user space handler to respond */
0056 };
0057 
0058 struct thermal_zone_device_ops {
0059     int (*bind) (struct thermal_zone_device *,
0060              struct thermal_cooling_device *);
0061     int (*unbind) (struct thermal_zone_device *,
0062                struct thermal_cooling_device *);
0063     int (*get_temp) (struct thermal_zone_device *, int *);
0064     int (*set_trips) (struct thermal_zone_device *, int, int);
0065     int (*change_mode) (struct thermal_zone_device *,
0066         enum thermal_device_mode);
0067     int (*get_trip_type) (struct thermal_zone_device *, int,
0068         enum thermal_trip_type *);
0069     int (*get_trip_temp) (struct thermal_zone_device *, int, int *);
0070     int (*set_trip_temp) (struct thermal_zone_device *, int, int);
0071     int (*get_trip_hyst) (struct thermal_zone_device *, int, int *);
0072     int (*set_trip_hyst) (struct thermal_zone_device *, int, int);
0073     int (*get_crit_temp) (struct thermal_zone_device *, int *);
0074     int (*set_emul_temp) (struct thermal_zone_device *, int);
0075     int (*get_trend) (struct thermal_zone_device *, int,
0076               enum thermal_trend *);
0077     void (*hot)(struct thermal_zone_device *);
0078     void (*critical)(struct thermal_zone_device *);
0079 };
0080 
0081 /**
0082  * struct thermal_trip - representation of a point in temperature domain
0083  * @temperature: temperature value in miliCelsius
0084  * @hysteresis: relative hysteresis in miliCelsius
0085  * @type: trip point type
0086  */
0087 struct thermal_trip {
0088     int temperature;
0089     int hysteresis;
0090     enum thermal_trip_type type;
0091 };
0092 
0093 struct thermal_cooling_device_ops {
0094     int (*get_max_state) (struct thermal_cooling_device *, unsigned long *);
0095     int (*get_cur_state) (struct thermal_cooling_device *, unsigned long *);
0096     int (*set_cur_state) (struct thermal_cooling_device *, unsigned long);
0097     int (*get_requested_power)(struct thermal_cooling_device *, u32 *);
0098     int (*state2power)(struct thermal_cooling_device *, unsigned long, u32 *);
0099     int (*power2state)(struct thermal_cooling_device *, u32, unsigned long *);
0100 };
0101 
0102 struct thermal_cooling_device {
0103     int id;
0104     char *type;
0105     struct device device;
0106     struct device_node *np;
0107     void *devdata;
0108     void *stats;
0109     const struct thermal_cooling_device_ops *ops;
0110     bool updated; /* true if the cooling device does not need update */
0111     struct mutex lock; /* protect thermal_instances list */
0112     struct list_head thermal_instances;
0113     struct list_head node;
0114 };
0115 
0116 /**
0117  * struct thermal_zone_device - structure for a thermal zone
0118  * @id:     unique id number for each thermal zone
0119  * @type:   the thermal zone device type
0120  * @device: &struct device for this thermal zone
0121  * @trip_temp_attrs:    attributes for trip points for sysfs: trip temperature
0122  * @trip_type_attrs:    attributes for trip points for sysfs: trip type
0123  * @trip_hyst_attrs:    attributes for trip points for sysfs: trip hysteresis
0124  * @mode:       current mode of this thermal zone
0125  * @devdata:    private pointer for device private data
0126  * @trips:  an array of struct thermal_trip
0127  * @num_trips:  number of trip points the thermal zone supports
0128  * @trips_disabled; bitmap for disabled trips
0129  * @passive_delay_jiffies: number of jiffies to wait between polls when
0130  *          performing passive cooling.
0131  * @polling_delay_jiffies: number of jiffies to wait between polls when
0132  *          checking whether trip points have been crossed (0 for
0133  *          interrupt driven systems)
0134  * @temperature:    current temperature.  This is only for core code,
0135  *          drivers should use thermal_zone_get_temp() to get the
0136  *          current temperature
0137  * @last_temperature:   previous temperature read
0138  * @emul_temperature:   emulated temperature when using CONFIG_THERMAL_EMULATION
0139  * @passive:        1 if you've crossed a passive trip point, 0 otherwise.
0140  * @prev_low_trip:  the low current temperature if you've crossed a passive
0141             trip point.
0142  * @prev_high_trip: the above current temperature if you've crossed a
0143             passive trip point.
0144  * @need_update:    if equals 1, thermal_zone_device_update needs to be invoked.
0145  * @ops:    operations this &thermal_zone_device supports
0146  * @tzp:    thermal zone parameters
0147  * @governor:   pointer to the governor for this thermal zone
0148  * @governor_data:  private pointer for governor data
0149  * @thermal_instances:  list of &struct thermal_instance of this thermal zone
0150  * @ida:    &struct ida to generate unique id for this zone's cooling
0151  *      devices
0152  * @lock:   lock to protect thermal_instances list
0153  * @node:   node in thermal_tz_list (in thermal_core.c)
0154  * @poll_queue: delayed work for polling
0155  * @notify_event: Last notification event
0156  */
0157 struct thermal_zone_device {
0158     int id;
0159     char type[THERMAL_NAME_LENGTH];
0160     struct device device;
0161     struct attribute_group trips_attribute_group;
0162     struct thermal_attr *trip_temp_attrs;
0163     struct thermal_attr *trip_type_attrs;
0164     struct thermal_attr *trip_hyst_attrs;
0165     enum thermal_device_mode mode;
0166     void *devdata;
0167     struct thermal_trip *trips;
0168     int num_trips;
0169     unsigned long trips_disabled;   /* bitmap for disabled trips */
0170     unsigned long passive_delay_jiffies;
0171     unsigned long polling_delay_jiffies;
0172     int temperature;
0173     int last_temperature;
0174     int emul_temperature;
0175     int passive;
0176     int prev_low_trip;
0177     int prev_high_trip;
0178     atomic_t need_update;
0179     struct thermal_zone_device_ops *ops;
0180     struct thermal_zone_params *tzp;
0181     struct thermal_governor *governor;
0182     void *governor_data;
0183     struct list_head thermal_instances;
0184     struct ida ida;
0185     struct mutex lock;
0186     struct list_head node;
0187     struct delayed_work poll_queue;
0188     enum thermal_notify_event notify_event;
0189 };
0190 
0191 /**
0192  * struct thermal_governor - structure that holds thermal governor information
0193  * @name:   name of the governor
0194  * @bind_to_tz: callback called when binding to a thermal zone.  If it
0195  *      returns 0, the governor is bound to the thermal zone,
0196  *      otherwise it fails.
0197  * @unbind_from_tz: callback called when a governor is unbound from a
0198  *          thermal zone.
0199  * @throttle:   callback called for every trip point even if temperature is
0200  *      below the trip point temperature
0201  * @governor_list:  node in thermal_governor_list (in thermal_core.c)
0202  */
0203 struct thermal_governor {
0204     char name[THERMAL_NAME_LENGTH];
0205     int (*bind_to_tz)(struct thermal_zone_device *tz);
0206     void (*unbind_from_tz)(struct thermal_zone_device *tz);
0207     int (*throttle)(struct thermal_zone_device *tz, int trip);
0208     struct list_head    governor_list;
0209 };
0210 
0211 /* Structure that holds binding parameters for a zone */
0212 struct thermal_bind_params {
0213     struct thermal_cooling_device *cdev;
0214 
0215     /*
0216      * This is a measure of 'how effectively these devices can
0217      * cool 'this' thermal zone. It shall be determined by
0218      * platform characterization. This value is relative to the
0219      * rest of the weights so a cooling device whose weight is
0220      * double that of another cooling device is twice as
0221      * effective. See Documentation/driver-api/thermal/sysfs-api.rst for more
0222      * information.
0223      */
0224     int weight;
0225 
0226     /*
0227      * This is a bit mask that gives the binding relation between this
0228      * thermal zone and cdev, for a particular trip point.
0229      * See Documentation/driver-api/thermal/sysfs-api.rst for more information.
0230      */
0231     int trip_mask;
0232 
0233     /*
0234      * This is an array of cooling state limits. Must have exactly
0235      * 2 * thermal_zone.number_of_trip_points. It is an array consisting
0236      * of tuples <lower-state upper-state> of state limits. Each trip
0237      * will be associated with one state limit tuple when binding.
0238      * A NULL pointer means <THERMAL_NO_LIMITS THERMAL_NO_LIMITS>
0239      * on all trips.
0240      */
0241     unsigned long *binding_limits;
0242     int (*match) (struct thermal_zone_device *tz,
0243             struct thermal_cooling_device *cdev);
0244 };
0245 
0246 /* Structure to define Thermal Zone parameters */
0247 struct thermal_zone_params {
0248     char governor_name[THERMAL_NAME_LENGTH];
0249 
0250     /*
0251      * a boolean to indicate if the thermal to hwmon sysfs interface
0252      * is required. when no_hwmon == false, a hwmon sysfs interface
0253      * will be created. when no_hwmon == true, nothing will be done
0254      */
0255     bool no_hwmon;
0256 
0257     int num_tbps;   /* Number of tbp entries */
0258     struct thermal_bind_params *tbp;
0259 
0260     /*
0261      * Sustainable power (heat) that this thermal zone can dissipate in
0262      * mW
0263      */
0264     u32 sustainable_power;
0265 
0266     /*
0267      * Proportional parameter of the PID controller when
0268      * overshooting (i.e., when temperature is below the target)
0269      */
0270     s32 k_po;
0271 
0272     /*
0273      * Proportional parameter of the PID controller when
0274      * undershooting
0275      */
0276     s32 k_pu;
0277 
0278     /* Integral parameter of the PID controller */
0279     s32 k_i;
0280 
0281     /* Derivative parameter of the PID controller */
0282     s32 k_d;
0283 
0284     /* threshold below which the error is no longer accumulated */
0285     s32 integral_cutoff;
0286 
0287     /*
0288      * @slope:  slope of a linear temperature adjustment curve.
0289      *      Used by thermal zone drivers.
0290      */
0291     int slope;
0292     /*
0293      * @offset: offset of a linear temperature adjustment curve.
0294      *      Used by thermal zone drivers (default 0).
0295      */
0296     int offset;
0297 };
0298 
0299 /**
0300  * struct thermal_zone_of_device_ops - callbacks for handling DT based zones
0301  *
0302  * Mandatory:
0303  * @get_temp: a pointer to a function that reads the sensor temperature.
0304  *
0305  * Optional:
0306  * @get_trend: a pointer to a function that reads the sensor temperature trend.
0307  * @set_trips: a pointer to a function that sets a temperature window. When
0308  *         this window is left the driver must inform the thermal core via
0309  *         thermal_zone_device_update.
0310  * @set_emul_temp: a pointer to a function that sets sensor emulated
0311  *         temperature.
0312  * @set_trip_temp: a pointer to a function that sets the trip temperature on
0313  *         hardware.
0314  * @change_mode: a pointer to a function that notifies the thermal zone
0315  *         mode change.
0316  */
0317 struct thermal_zone_of_device_ops {
0318     int (*get_temp)(void *, int *);
0319     int (*get_trend)(void *, int, enum thermal_trend *);
0320     int (*set_trips)(void *, int, int);
0321     int (*set_emul_temp)(void *, int);
0322     int (*set_trip_temp)(void *, int, int);
0323     int (*change_mode) (void *, enum thermal_device_mode);
0324 };
0325 
0326 /* Function declarations */
0327 #ifdef CONFIG_THERMAL_OF
0328 int thermal_zone_of_get_sensor_id(struct device_node *tz_np,
0329                   struct device_node *sensor_np,
0330                   u32 *id);
0331 struct thermal_zone_device *
0332 thermal_zone_of_sensor_register(struct device *dev, int id, void *data,
0333                 const struct thermal_zone_of_device_ops *ops);
0334 void thermal_zone_of_sensor_unregister(struct device *dev,
0335                        struct thermal_zone_device *tz);
0336 struct thermal_zone_device *devm_thermal_zone_of_sensor_register(
0337         struct device *dev, int id, void *data,
0338         const struct thermal_zone_of_device_ops *ops);
0339 void devm_thermal_zone_of_sensor_unregister(struct device *dev,
0340                         struct thermal_zone_device *tz);
0341 #else
0342 
0343 static inline int thermal_zone_of_get_sensor_id(struct device_node *tz_np,
0344                      struct device_node *sensor_np,
0345                      u32 *id)
0346 {
0347     return -ENOENT;
0348 }
0349 static inline struct thermal_zone_device *
0350 thermal_zone_of_sensor_register(struct device *dev, int id, void *data,
0351                 const struct thermal_zone_of_device_ops *ops)
0352 {
0353     return ERR_PTR(-ENODEV);
0354 }
0355 
0356 static inline
0357 void thermal_zone_of_sensor_unregister(struct device *dev,
0358                        struct thermal_zone_device *tz)
0359 {
0360 }
0361 
0362 static inline struct thermal_zone_device *devm_thermal_zone_of_sensor_register(
0363         struct device *dev, int id, void *data,
0364         const struct thermal_zone_of_device_ops *ops)
0365 {
0366     return ERR_PTR(-ENODEV);
0367 }
0368 
0369 static inline
0370 void devm_thermal_zone_of_sensor_unregister(struct device *dev,
0371                         struct thermal_zone_device *tz)
0372 {
0373 }
0374 
0375 #endif
0376 
0377 #ifdef CONFIG_THERMAL
0378 struct thermal_zone_device *thermal_zone_device_register(const char *, int, int,
0379         void *, struct thermal_zone_device_ops *,
0380         struct thermal_zone_params *, int, int);
0381 
0382 void thermal_zone_device_unregister(struct thermal_zone_device *);
0383 
0384 struct thermal_zone_device *
0385 thermal_zone_device_register_with_trips(const char *, struct thermal_trip *, int, int,
0386                     void *, struct thermal_zone_device_ops *,
0387                     struct thermal_zone_params *, int, int);
0388 
0389 int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
0390                      struct thermal_cooling_device *,
0391                      unsigned long, unsigned long,
0392                      unsigned int);
0393 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int,
0394                        struct thermal_cooling_device *);
0395 void thermal_zone_device_update(struct thermal_zone_device *,
0396                 enum thermal_notify_event);
0397 
0398 struct thermal_cooling_device *thermal_cooling_device_register(const char *,
0399         void *, const struct thermal_cooling_device_ops *);
0400 struct thermal_cooling_device *
0401 thermal_of_cooling_device_register(struct device_node *np, const char *, void *,
0402                    const struct thermal_cooling_device_ops *);
0403 struct thermal_cooling_device *
0404 devm_thermal_of_cooling_device_register(struct device *dev,
0405                 struct device_node *np,
0406                 char *type, void *devdata,
0407                 const struct thermal_cooling_device_ops *ops);
0408 void thermal_cooling_device_unregister(struct thermal_cooling_device *);
0409 struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name);
0410 int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
0411 int thermal_zone_get_slope(struct thermal_zone_device *tz);
0412 int thermal_zone_get_offset(struct thermal_zone_device *tz);
0413 
0414 int thermal_zone_device_enable(struct thermal_zone_device *tz);
0415 int thermal_zone_device_disable(struct thermal_zone_device *tz);
0416 void thermal_zone_device_critical(struct thermal_zone_device *tz);
0417 #else
0418 static inline struct thermal_zone_device *thermal_zone_device_register(
0419     const char *type, int trips, int mask, void *devdata,
0420     struct thermal_zone_device_ops *ops,
0421     struct thermal_zone_params *tzp,
0422     int passive_delay, int polling_delay)
0423 { return ERR_PTR(-ENODEV); }
0424 static inline void thermal_zone_device_unregister(
0425     struct thermal_zone_device *tz)
0426 { }
0427 static inline struct thermal_cooling_device *
0428 thermal_cooling_device_register(const char *type, void *devdata,
0429     const struct thermal_cooling_device_ops *ops)
0430 { return ERR_PTR(-ENODEV); }
0431 static inline struct thermal_cooling_device *
0432 thermal_of_cooling_device_register(struct device_node *np,
0433     const char *type, void *devdata,
0434     const struct thermal_cooling_device_ops *ops)
0435 { return ERR_PTR(-ENODEV); }
0436 static inline struct thermal_cooling_device *
0437 devm_thermal_of_cooling_device_register(struct device *dev,
0438                 struct device_node *np,
0439                 char *type, void *devdata,
0440                 const struct thermal_cooling_device_ops *ops)
0441 {
0442     return ERR_PTR(-ENODEV);
0443 }
0444 static inline void thermal_cooling_device_unregister(
0445     struct thermal_cooling_device *cdev)
0446 { }
0447 static inline struct thermal_zone_device *thermal_zone_get_zone_by_name(
0448         const char *name)
0449 { return ERR_PTR(-ENODEV); }
0450 static inline int thermal_zone_get_temp(
0451         struct thermal_zone_device *tz, int *temp)
0452 { return -ENODEV; }
0453 static inline int thermal_zone_get_slope(
0454         struct thermal_zone_device *tz)
0455 { return -ENODEV; }
0456 static inline int thermal_zone_get_offset(
0457         struct thermal_zone_device *tz)
0458 { return -ENODEV; }
0459 
0460 static inline int thermal_zone_device_enable(struct thermal_zone_device *tz)
0461 { return -ENODEV; }
0462 
0463 static inline int thermal_zone_device_disable(struct thermal_zone_device *tz)
0464 { return -ENODEV; }
0465 #endif /* CONFIG_THERMAL */
0466 
0467 #endif /* __THERMAL_H__ */