10de967f2SLukasz Luba /* SPDX-License-Identifier: GPL-2.0 */
2a76caf55SØrjan Eide /*
3a76caf55SØrjan Eide  * devfreq_cooling: Thermal cooling device implementation for devices using
4a76caf55SØrjan Eide  *                  devfreq
5a76caf55SØrjan Eide  *
6a76caf55SØrjan Eide  * Copyright (C) 2014-2015 ARM Limited
7a76caf55SØrjan Eide  *
8a76caf55SØrjan Eide  */
9a76caf55SØrjan Eide 
10a76caf55SØrjan Eide #ifndef __DEVFREQ_COOLING_H__
11a76caf55SØrjan Eide #define __DEVFREQ_COOLING_H__
12a76caf55SØrjan Eide 
13a76caf55SØrjan Eide #include <linux/devfreq.h>
14a76caf55SØrjan Eide #include <linux/thermal.h>
15a76caf55SØrjan Eide 
16a76caf55SØrjan Eide 
17a76caf55SØrjan Eide /**
18a76caf55SØrjan Eide  * struct devfreq_cooling_power - Devfreq cooling power ops
192be83da8SLukasz Luba  * @get_real_power:	When this is set, the framework uses it to ask the
202be83da8SLukasz Luba  *			device driver for the actual power.
212be83da8SLukasz Luba  *			Some devices have more sophisticated methods
222be83da8SLukasz Luba  *			(like power counters) to approximate the actual power
232be83da8SLukasz Luba  *			that they use.
242be83da8SLukasz Luba  *			This function provides more accurate data to the
252be83da8SLukasz Luba  *			thermal governor. When the driver does not provide
262be83da8SLukasz Luba  *			such function, framework just uses pre-calculated
272be83da8SLukasz Luba  *			table and scale the power by 'utilization'
282be83da8SLukasz Luba  *			(based on 'busy_time' and 'total_time' taken from
292be83da8SLukasz Luba  *			devfreq 'last_status').
302be83da8SLukasz Luba  *			The value returned by this function must be lower
312be83da8SLukasz Luba  *			or equal than the maximum power value
322be83da8SLukasz Luba  *			for the current	state
332be83da8SLukasz Luba  *			(which can be found in power_table[state]).
342be83da8SLukasz Luba  *			When this interface is used, the power_table holds
352be83da8SLukasz Luba  *			max total (static + dynamic) power value for each OPP.
36a76caf55SØrjan Eide  */
37a76caf55SØrjan Eide struct devfreq_cooling_power {
382be83da8SLukasz Luba 	int (*get_real_power)(struct devfreq *df, u32 *power,
392be83da8SLukasz Luba 			      unsigned long freq, unsigned long voltage);
40a76caf55SØrjan Eide };
41a76caf55SØrjan Eide 
421cea4e77SLukasz Luba #ifdef CONFIG_DEVFREQ_THERMAL
431cea4e77SLukasz Luba 
443c99c2ceSJavi Merino struct thermal_cooling_device *
45a76caf55SØrjan Eide of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
46a76caf55SØrjan Eide 				  struct devfreq_cooling_power *dfc_power);
473c99c2ceSJavi Merino struct thermal_cooling_device *
48a76caf55SØrjan Eide of_devfreq_cooling_register(struct device_node *np, struct devfreq *df);
493c99c2ceSJavi Merino struct thermal_cooling_device *devfreq_cooling_register(struct devfreq *df);
503c99c2ceSJavi Merino void devfreq_cooling_unregister(struct thermal_cooling_device *dfc);
51*84e0d87cSLukasz Luba struct thermal_cooling_device *
52*84e0d87cSLukasz Luba devfreq_cooling_em_register(struct devfreq *df,
53*84e0d87cSLukasz Luba 			    struct devfreq_cooling_power *dfc_power);
54a76caf55SØrjan Eide 
55a76caf55SØrjan Eide #else /* !CONFIG_DEVFREQ_THERMAL */
56a76caf55SØrjan Eide 
573f5b9959SMartin Blumenstingl static inline struct thermal_cooling_device *
of_devfreq_cooling_register_power(struct device_node * np,struct devfreq * df,struct devfreq_cooling_power * dfc_power)58a76caf55SØrjan Eide of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
59a76caf55SØrjan Eide 				  struct devfreq_cooling_power *dfc_power)
60a76caf55SØrjan Eide {
61a76caf55SØrjan Eide 	return ERR_PTR(-EINVAL);
62a76caf55SØrjan Eide }
63a76caf55SØrjan Eide 
643c99c2ceSJavi Merino static inline struct thermal_cooling_device *
of_devfreq_cooling_register(struct device_node * np,struct devfreq * df)65a76caf55SØrjan Eide of_devfreq_cooling_register(struct device_node *np, struct devfreq *df)
66a76caf55SØrjan Eide {
67a76caf55SØrjan Eide 	return ERR_PTR(-EINVAL);
68a76caf55SØrjan Eide }
69a76caf55SØrjan Eide 
703c99c2ceSJavi Merino static inline struct thermal_cooling_device *
devfreq_cooling_register(struct devfreq * df)71a76caf55SØrjan Eide devfreq_cooling_register(struct devfreq *df)
72a76caf55SØrjan Eide {
73a76caf55SØrjan Eide 	return ERR_PTR(-EINVAL);
74a76caf55SØrjan Eide }
75a76caf55SØrjan Eide 
76*84e0d87cSLukasz Luba static inline struct thermal_cooling_device *
devfreq_cooling_em_register(struct devfreq * df,struct devfreq_cooling_power * dfc_power)77*84e0d87cSLukasz Luba devfreq_cooling_em_register(struct devfreq *df,
78*84e0d87cSLukasz Luba 			    struct devfreq_cooling_power *dfc_power)
79*84e0d87cSLukasz Luba {
80*84e0d87cSLukasz Luba 	return ERR_PTR(-EINVAL);
81*84e0d87cSLukasz Luba }
82*84e0d87cSLukasz Luba 
83a76caf55SØrjan Eide static inline void
devfreq_cooling_unregister(struct thermal_cooling_device * dfc)843c99c2ceSJavi Merino devfreq_cooling_unregister(struct thermal_cooling_device *dfc)
85a76caf55SØrjan Eide {
86a76caf55SØrjan Eide }
87a76caf55SØrjan Eide 
88a76caf55SØrjan Eide #endif /* CONFIG_DEVFREQ_THERMAL */
89a76caf55SØrjan Eide #endif /* __DEVFREQ_COOLING_H__ */
90