Skip to content

Commit 35b11d2

Browse files
Javi MerinoEduardo Valentin
authored andcommitted
thermal: extend the cooling device API to include power information
Add three optional callbacks to the cooling device interface to allow them to express power. In addition to the callbacks, add helpers to identify cooling devices that implement the power cooling device API. Cc: Zhang Rui <rui.zhang@intel.com> Cc: Eduardo Valentin <edubezval@gmail.com> Signed-off-by: Javi Merino <javi.merino@arm.com> Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
1 parent e33df1d commit 35b11d2

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

drivers/thermal/thermal_core.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,58 @@ emul_temp_store(struct device *dev, struct device_attribute *attr,
875875
static DEVICE_ATTR(emul_temp, S_IWUSR, NULL, emul_temp_store);
876876
#endif/*CONFIG_THERMAL_EMULATION*/
877877

878+
/**
879+
* power_actor_get_max_power() - get the maximum power that a cdev can consume
880+
* @cdev: pointer to &thermal_cooling_device
881+
* @tz: a valid thermal zone device pointer
882+
* @max_power: pointer in which to store the maximum power
883+
*
884+
* Calculate the maximum power consumption in milliwats that the
885+
* cooling device can currently consume and store it in @max_power.
886+
*
887+
* Return: 0 on success, -EINVAL if @cdev doesn't support the
888+
* power_actor API or -E* on other error.
889+
*/
890+
int power_actor_get_max_power(struct thermal_cooling_device *cdev,
891+
struct thermal_zone_device *tz, u32 *max_power)
892+
{
893+
if (!cdev_is_power_actor(cdev))
894+
return -EINVAL;
895+
896+
return cdev->ops->state2power(cdev, tz, 0, max_power);
897+
}
898+
899+
/**
900+
* power_actor_set_power() - limit the maximum power that a cooling device can consume
901+
* @cdev: pointer to &thermal_cooling_device
902+
* @instance: thermal instance to update
903+
* @power: the power in milliwatts
904+
*
905+
* Set the cooling device to consume at most @power milliwatts.
906+
*
907+
* Return: 0 on success, -EINVAL if the cooling device does not
908+
* implement the power actor API or -E* for other failures.
909+
*/
910+
int power_actor_set_power(struct thermal_cooling_device *cdev,
911+
struct thermal_instance *instance, u32 power)
912+
{
913+
unsigned long state;
914+
int ret;
915+
916+
if (!cdev_is_power_actor(cdev))
917+
return -EINVAL;
918+
919+
ret = cdev->ops->power2state(cdev, instance->tz, power, &state);
920+
if (ret)
921+
return ret;
922+
923+
instance->target = state;
924+
cdev->updated = false;
925+
thermal_cdev_update(cdev);
926+
927+
return 0;
928+
}
929+
878930
static DEVICE_ATTR(type, 0444, type_show, NULL);
879931
static DEVICE_ATTR(temp, 0444, temp_show, NULL);
880932
static DEVICE_ATTR(mode, 0644, mode_show, mode_store);

include/linux/thermal.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363

6464
struct thermal_zone_device;
6565
struct thermal_cooling_device;
66+
struct thermal_instance;
6667

6768
enum thermal_device_mode {
6869
THERMAL_DEVICE_DISABLED = 0,
@@ -116,6 +117,12 @@ struct thermal_cooling_device_ops {
116117
int (*get_max_state) (struct thermal_cooling_device *, unsigned long *);
117118
int (*get_cur_state) (struct thermal_cooling_device *, unsigned long *);
118119
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 *);
119126
};
120127

121128
struct thermal_cooling_device {
@@ -331,6 +338,16 @@ void thermal_zone_of_sensor_unregister(struct device *dev,
331338
#endif
332339

333340
#if IS_ENABLED(CONFIG_THERMAL)
341+
static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev)
342+
{
343+
return cdev->ops->get_requested_power && cdev->ops->state2power &&
344+
cdev->ops->power2state;
345+
}
346+
347+
int power_actor_get_max_power(struct thermal_cooling_device *,
348+
struct thermal_zone_device *tz, u32 *max_power);
349+
int power_actor_set_power(struct thermal_cooling_device *,
350+
struct thermal_instance *, u32);
334351
struct thermal_zone_device *thermal_zone_device_register(const char *, int, int,
335352
void *, struct thermal_zone_device_ops *,
336353
const struct thermal_zone_params *, int, int);
@@ -359,6 +376,14 @@ struct thermal_instance *get_thermal_instance(struct thermal_zone_device *,
359376
void thermal_cdev_update(struct thermal_cooling_device *);
360377
void thermal_notify_framework(struct thermal_zone_device *, int);
361378
#else
379+
static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev)
380+
{ return false; }
381+
static inline int power_actor_get_max_power(struct thermal_cooling_device *cdev,
382+
struct thermal_zone_device *tz, u32 *max_power)
383+
{ return 0; }
384+
static inline int power_actor_set_power(struct thermal_cooling_device *cdev,
385+
struct thermal_instance *tz, u32 power)
386+
{ return 0; }
362387
static inline struct thermal_zone_device *thermal_zone_device_register(
363388
const char *type, int trips, int mask, void *devdata,
364389
struct thermal_zone_device_ops *ops,

0 commit comments

Comments
 (0)