| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- /* SPDX-License-Identifier: GPL-2.0 */
- /*
- * thermal_core.h
- *
- * Copyright (C) 2012 Intel Corp
- * Author: Durgadoss R <durgadoss.r@intel.com>
- */
- #ifndef __THERMAL_CORE_H__
- #define __THERMAL_CORE_H__
- #include <linux/cleanup.h>
- #include <linux/device.h>
- #include <linux/thermal.h>
- #include "thermal_netlink.h"
- #include "thermal_thresholds.h"
- #include "thermal_debugfs.h"
- struct thermal_attr {
- struct device_attribute attr;
- char name[THERMAL_NAME_LENGTH];
- };
- struct thermal_trip_attrs {
- struct thermal_attr type;
- struct thermal_attr temp;
- struct thermal_attr hyst;
- };
- struct thermal_trip_desc {
- struct thermal_trip trip;
- struct thermal_trip_attrs trip_attrs;
- struct list_head list_node;
- struct list_head thermal_instances;
- int threshold;
- };
- /**
- * struct thermal_governor - structure that holds thermal governor information
- * @name: name of the governor
- * @bind_to_tz: callback called when binding to a thermal zone. If it
- * returns 0, the governor is bound to the thermal zone,
- * otherwise it fails.
- * @unbind_from_tz: callback called when a governor is unbound from a
- * thermal zone.
- * @trip_crossed: called for trip points that have just been crossed
- * @manage: called on thermal zone temperature updates
- * @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)
- */
- struct thermal_governor {
- const char *name;
- int (*bind_to_tz)(struct thermal_zone_device *tz);
- void (*unbind_from_tz)(struct thermal_zone_device *tz);
- void (*trip_crossed)(struct thermal_zone_device *tz,
- const struct thermal_trip *trip,
- bool upward);
- void (*manage)(struct thermal_zone_device *tz);
- void (*update_tz)(struct thermal_zone_device *tz,
- enum thermal_notify_event reason);
- struct list_head governor_list;
- };
- #define TZ_STATE_FLAG_SUSPENDED BIT(0)
- #define TZ_STATE_FLAG_RESUMING BIT(1)
- #define TZ_STATE_FLAG_INIT BIT(2)
- #define TZ_STATE_FLAG_EXIT BIT(3)
- #define TZ_STATE_READY 0
- /**
- * struct thermal_zone_device - structure for a thermal zone
- * @id: unique id number for each thermal zone
- * @type: the thermal zone device type
- * @device: &struct device for this thermal zone
- * @removal: removal completion
- * @resume: resume completion
- * @trips_attribute_group: trip point sysfs attributes
- * @trips_high: trips above the current zone temperature
- * @trips_reached: trips below or at the current zone temperature
- * @trips_invalid: trips with invalid temperature
- * @mode: current mode of this thermal zone
- * @devdata: private pointer for device private data
- * @num_trips: number of trip points the thermal zone supports
- * @passive_delay_jiffies: number of jiffies to wait between polls when
- * performing passive cooling.
- * @polling_delay_jiffies: number of jiffies to wait between polls when
- * checking whether trip points have been crossed (0 for
- * interrupt driven systems)
- * @recheck_delay_jiffies: delay after a failed attempt to determine the zone
- * temperature before trying again
- * @temperature: current temperature. This is only for core code,
- * drivers should use thermal_zone_get_temp() to get the
- * current temperature
- * @last_temperature: previous temperature read
- * @emul_temperature: emulated temperature when using CONFIG_THERMAL_EMULATION
- * @passive: 1 if you've crossed a passive trip point, 0 otherwise.
- * @prev_low_trip: the low current temperature if you've crossed a passive
- * trip point.
- * @prev_high_trip: the above current temperature if you've crossed a
- * passive trip point.
- * @ops: operations this &thermal_zone_device supports
- * @tzp: thermal zone parameters
- * @governor: pointer to the governor for this thermal zone
- * @governor_data: private pointer for governor data
- * @ida: &struct ida to generate unique id for this zone's cooling
- * devices
- * @lock: lock to protect thermal_instances list
- * @node: node in thermal_tz_list (in thermal_core.c)
- * @poll_queue: delayed work for polling
- * @notify_event: Last notification event
- * @state: current state of the thermal zone
- * @debugfs: this thermal zone device's thermal zone debug info
- * @user_thresholds: list of userspace thresholds for temp. limit notifications
- * @trips: array of struct thermal_trip objects
- */
- struct thermal_zone_device {
- int id;
- char type[THERMAL_NAME_LENGTH];
- struct device device;
- struct completion removal;
- struct completion resume;
- struct attribute_group trips_attribute_group;
- struct list_head trips_high;
- struct list_head trips_reached;
- struct list_head trips_invalid;
- enum thermal_device_mode mode;
- void *devdata;
- int num_trips;
- unsigned long passive_delay_jiffies;
- unsigned long polling_delay_jiffies;
- unsigned long recheck_delay_jiffies;
- int temperature;
- int last_temperature;
- int emul_temperature;
- int passive;
- int prev_low_trip;
- int prev_high_trip;
- struct thermal_zone_device_ops ops;
- struct thermal_zone_params *tzp;
- struct thermal_governor *governor;
- void *governor_data;
- struct ida ida;
- struct mutex lock;
- struct list_head node;
- struct delayed_work poll_queue;
- enum thermal_notify_event notify_event;
- u8 state;
- #ifdef CONFIG_THERMAL_DEBUGFS
- struct thermal_debugfs *debugfs;
- #endif
- struct list_head user_thresholds;
- struct thermal_trip_desc trips[] __counted_by(num_trips);
- };
- DEFINE_GUARD(thermal_zone, struct thermal_zone_device *, mutex_lock(&_T->lock),
- mutex_unlock(&_T->lock))
- DEFINE_GUARD(thermal_zone_reverse, struct thermal_zone_device *,
- mutex_unlock(&_T->lock), mutex_lock(&_T->lock))
- /* Initial thermal zone temperature. */
- #define THERMAL_TEMP_INIT INT_MIN
- /*
- * Default and maximum delay after a failed thermal zone temperature check
- * before attempting to check it again (in jiffies).
- */
- #define THERMAL_RECHECK_DELAY msecs_to_jiffies(250)
- #define THERMAL_MAX_RECHECK_DELAY (120 * HZ)
- /* Default Thermal Governor */
- #if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE)
- #define DEFAULT_THERMAL_GOVERNOR "step_wise"
- #elif defined(CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE)
- #define DEFAULT_THERMAL_GOVERNOR "fair_share"
- #elif defined(CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE)
- #define DEFAULT_THERMAL_GOVERNOR "user_space"
- #elif defined(CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR)
- #define DEFAULT_THERMAL_GOVERNOR "power_allocator"
- #elif defined(CONFIG_THERMAL_DEFAULT_GOV_BANG_BANG)
- #define DEFAULT_THERMAL_GOVERNOR "bang_bang"
- #endif
- /* Initial state of a cooling device during binding */
- #define THERMAL_NO_TARGET -1UL
- /* Init section thermal table */
- extern struct thermal_governor *__governor_thermal_table[];
- extern struct thermal_governor *__governor_thermal_table_end[];
- #define THERMAL_TABLE_ENTRY(table, name) \
- static typeof(name) *__thermal_table_entry_##name \
- __used __section("__" #table "_thermal_table") = &name
- #define THERMAL_GOVERNOR_DECLARE(name) THERMAL_TABLE_ENTRY(governor, name)
- #define for_each_governor_table(__governor) \
- for (__governor = __governor_thermal_table; \
- __governor < __governor_thermal_table_end; \
- __governor++)
- int for_each_thermal_zone(int (*cb)(struct thermal_zone_device *, void *),
- void *);
- int for_each_thermal_cooling_device(int (*cb)(struct thermal_cooling_device *,
- void *), void *);
- int for_each_thermal_governor(int (*cb)(struct thermal_governor *, void *),
- void *thermal_governor);
- struct thermal_zone_device *thermal_zone_get_by_id(int id);
- DEFINE_CLASS(thermal_zone_get_by_id, struct thermal_zone_device *,
- if (_T) put_device(&_T->device), thermal_zone_get_by_id(id), int id)
- static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev)
- {
- return cdev->ops->get_requested_power && cdev->ops->state2power &&
- cdev->ops->power2state;
- }
- void thermal_cdev_update(struct thermal_cooling_device *);
- void thermal_cdev_update_nocheck(struct thermal_cooling_device *cdev);
- void __thermal_cdev_update(struct thermal_cooling_device *cdev);
- int get_tz_trend(struct thermal_zone_device *tz, const struct thermal_trip *trip);
- /*
- * This structure is used to describe the behavior of
- * a certain cooling device on a certain trip point
- * in a certain thermal zone
- */
- struct thermal_instance {
- int id;
- char name[THERMAL_NAME_LENGTH];
- struct thermal_cooling_device *cdev;
- const struct thermal_trip *trip;
- bool initialized;
- unsigned long upper; /* Highest cooling state for this trip point */
- unsigned long lower; /* Lowest cooling state for this trip point */
- unsigned long target; /* expected cooling state */
- char attr_name[THERMAL_NAME_LENGTH];
- struct device_attribute attr;
- char weight_attr_name[THERMAL_NAME_LENGTH];
- struct device_attribute weight_attr;
- struct list_head trip_node; /* node in trip->thermal_instances */
- struct list_head cdev_node; /* node in cdev->thermal_instances */
- unsigned int weight; /* The weight of the cooling device */
- bool upper_no_limit;
- };
- #define to_thermal_zone(_dev) \
- container_of(_dev, struct thermal_zone_device, device)
- #define to_cooling_device(_dev) \
- container_of(_dev, struct thermal_cooling_device, device)
- int thermal_register_governor(struct thermal_governor *);
- void thermal_unregister_governor(struct thermal_governor *);
- int thermal_zone_device_set_policy(struct thermal_zone_device *, char *);
- int thermal_build_list_of_policies(char *buf);
- void __thermal_zone_device_update(struct thermal_zone_device *tz,
- enum thermal_notify_event event);
- void thermal_zone_device_critical_reboot(struct thermal_zone_device *tz);
- void thermal_zone_device_critical_shutdown(struct thermal_zone_device *tz);
- void thermal_governor_update_tz(struct thermal_zone_device *tz,
- enum thermal_notify_event reason);
- /* Helpers */
- #define for_each_trip_desc(__tz, __td) \
- for (__td = __tz->trips; __td - __tz->trips < __tz->num_trips; __td++)
- #define trip_to_trip_desc(__trip) \
- container_of(__trip, struct thermal_trip_desc, trip)
- const char *thermal_trip_type_name(enum thermal_trip_type trip_type);
- void thermal_zone_set_trips(struct thermal_zone_device *tz, int low, int high);
- int thermal_zone_trip_id(const struct thermal_zone_device *tz,
- const struct thermal_trip *trip);
- int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
- void thermal_zone_set_trip_hyst(struct thermal_zone_device *tz,
- struct thermal_trip *trip, int hyst);
- /* sysfs I/F */
- int thermal_zone_create_device_groups(struct thermal_zone_device *tz);
- void thermal_zone_destroy_device_groups(struct thermal_zone_device *);
- void thermal_cooling_device_setup_sysfs(struct thermal_cooling_device *);
- void thermal_cooling_device_destroy_sysfs(struct thermal_cooling_device *cdev);
- void thermal_cooling_device_stats_reinit(struct thermal_cooling_device *cdev);
- /* used only at binding time */
- ssize_t trip_point_show(struct device *, struct device_attribute *, char *);
- ssize_t weight_show(struct device *, struct device_attribute *, char *);
- ssize_t weight_store(struct device *, struct device_attribute *, const char *,
- size_t);
- #ifdef CONFIG_THERMAL_STATISTICS
- void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev,
- unsigned long new_state);
- #else
- static inline void
- thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev,
- unsigned long new_state) {}
- #endif /* CONFIG_THERMAL_STATISTICS */
- #endif /* __THERMAL_CORE_H__ */
|