drivers: thermal: Add a snapshot of thermal framework
This is a snapshot of the thermal framework from msm-4.19 to msm-5.4 as of 'commit <14237cefb3f65441677efd9163852ee148017d0c> (thermal: Fix deadlock in thermal thermal_zone_device_check)'. Change-Id: I5702ad4f314f2dddfc04244d21605444bd7760a3 Signed-off-by: Ram Chandrasekar <rkumbako@codeaurora.org>
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 2012 Intel Corp
|
* Copyright (C) 2012 Intel Corp
|
||||||
* Copyright (C) 2012 Durgadoss R <durgadoss.r@intel.com>
|
* Copyright (C) 2012 Durgadoss R <durgadoss.r@intel.com>
|
||||||
|
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
*
|
*
|
||||||
@@ -41,6 +42,12 @@ static unsigned long get_target_state(struct thermal_instance *instance,
|
|||||||
unsigned long cur_state;
|
unsigned long cur_state;
|
||||||
unsigned long next_target;
|
unsigned long next_target;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the throttle condition is not reached and there is no
|
||||||
|
* previous mitigaiton request, then there is nothing to compute.
|
||||||
|
*/
|
||||||
|
if (!throttle && instance->target == THERMAL_NO_TARGET)
|
||||||
|
return THERMAL_NO_TARGET;
|
||||||
/*
|
/*
|
||||||
* We keep this instance the way it is by default.
|
* We keep this instance the way it is by default.
|
||||||
* Otherwise, we use the current state of the
|
* Otherwise, we use the current state of the
|
||||||
@@ -77,7 +84,9 @@ static unsigned long get_target_state(struct thermal_instance *instance,
|
|||||||
next_target = instance->upper;
|
next_target = instance->upper;
|
||||||
break;
|
break;
|
||||||
case THERMAL_TREND_DROPPING:
|
case THERMAL_TREND_DROPPING:
|
||||||
if (cur_state <= instance->lower) {
|
case THERMAL_TREND_STABLE:
|
||||||
|
if (cur_state <= instance->lower ||
|
||||||
|
instance->target <= instance->lower) {
|
||||||
if (!throttle)
|
if (!throttle)
|
||||||
next_target = THERMAL_NO_TARGET;
|
next_target = THERMAL_NO_TARGET;
|
||||||
} else {
|
} else {
|
||||||
@@ -115,7 +124,7 @@ static void update_passive_instance(struct thermal_zone_device *tz,
|
|||||||
|
|
||||||
static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
|
static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
|
||||||
{
|
{
|
||||||
int trip_temp;
|
int trip_temp, hyst_temp;
|
||||||
enum thermal_trip_type trip_type;
|
enum thermal_trip_type trip_type;
|
||||||
enum thermal_trend trend;
|
enum thermal_trend trend;
|
||||||
struct thermal_instance *instance;
|
struct thermal_instance *instance;
|
||||||
@@ -123,20 +132,21 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
|
|||||||
int old_target;
|
int old_target;
|
||||||
|
|
||||||
if (trip == THERMAL_TRIPS_NONE) {
|
if (trip == THERMAL_TRIPS_NONE) {
|
||||||
trip_temp = tz->forced_passive;
|
hyst_temp = trip_temp = tz->forced_passive;
|
||||||
trip_type = THERMAL_TRIPS_NONE;
|
trip_type = THERMAL_TRIPS_NONE;
|
||||||
} else {
|
} else {
|
||||||
tz->ops->get_trip_temp(tz, trip, &trip_temp);
|
tz->ops->get_trip_temp(tz, trip, &trip_temp);
|
||||||
|
if (tz->ops->get_trip_hyst) {
|
||||||
|
tz->ops->get_trip_hyst(tz, trip, &hyst_temp);
|
||||||
|
hyst_temp = trip_temp - hyst_temp;
|
||||||
|
} else {
|
||||||
|
hyst_temp = trip_temp;
|
||||||
|
}
|
||||||
tz->ops->get_trip_type(tz, trip, &trip_type);
|
tz->ops->get_trip_type(tz, trip, &trip_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
trend = get_tz_trend(tz, trip);
|
trend = get_tz_trend(tz, trip);
|
||||||
|
|
||||||
if (tz->temperature >= trip_temp) {
|
|
||||||
throttle = true;
|
|
||||||
trace_thermal_zone_trip(tz, trip, trip_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_dbg(&tz->device, "Trip%d[type=%d,temp=%d]:trend=%d,throttle=%d\n",
|
dev_dbg(&tz->device, "Trip%d[type=%d,temp=%d]:trend=%d,throttle=%d\n",
|
||||||
trip, trip_type, trip_temp, trend, throttle);
|
trip, trip_type, trip_temp, trend, throttle);
|
||||||
|
|
||||||
@@ -147,6 +157,20 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
old_target = instance->target;
|
old_target = instance->target;
|
||||||
|
/*
|
||||||
|
* Step wise has to lower the mitigation only if the
|
||||||
|
* temperature goes below the hysteresis temperature.
|
||||||
|
* Atleast, it has to hold on to mitigation device lower
|
||||||
|
* limit if the temperature is above the hysteresis
|
||||||
|
* temperature.
|
||||||
|
*/
|
||||||
|
if (tz->temperature >= trip_temp ||
|
||||||
|
(tz->temperature > hyst_temp &&
|
||||||
|
old_target != THERMAL_NO_TARGET))
|
||||||
|
throttle = true;
|
||||||
|
else
|
||||||
|
throttle = false;
|
||||||
|
|
||||||
instance->target = get_target_state(instance, trend, throttle);
|
instance->target = get_target_state(instance, trend, throttle);
|
||||||
dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n",
|
dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n",
|
||||||
old_target, (int)instance->target);
|
old_target, (int)instance->target);
|
||||||
@@ -154,14 +178,27 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
|
|||||||
if (instance->initialized && old_target == instance->target)
|
if (instance->initialized && old_target == instance->target)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!instance->initialized) {
|
||||||
|
if (instance->target != THERMAL_NO_TARGET) {
|
||||||
|
trace_thermal_zone_trip(tz, trip, trip_type,
|
||||||
|
true);
|
||||||
|
update_passive_instance(tz, trip_type, 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
/* Activate a passive thermal instance */
|
/* Activate a passive thermal instance */
|
||||||
if (old_target == THERMAL_NO_TARGET &&
|
if (old_target == THERMAL_NO_TARGET &&
|
||||||
instance->target != THERMAL_NO_TARGET)
|
instance->target != THERMAL_NO_TARGET) {
|
||||||
|
trace_thermal_zone_trip(tz, trip, trip_type,
|
||||||
|
true);
|
||||||
update_passive_instance(tz, trip_type, 1);
|
update_passive_instance(tz, trip_type, 1);
|
||||||
/* Deactivate a passive thermal instance */
|
/* Deactivate a passive thermal instance */
|
||||||
else if (old_target != THERMAL_NO_TARGET &&
|
} else if (old_target != THERMAL_NO_TARGET &&
|
||||||
instance->target == THERMAL_NO_TARGET)
|
instance->target == THERMAL_NO_TARGET) {
|
||||||
|
trace_thermal_zone_trip(tz, trip, trip_type,
|
||||||
|
false);
|
||||||
update_passive_instance(tz, trip_type, -1);
|
update_passive_instance(tz, trip_type, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
instance->initialized = true;
|
instance->initialized = true;
|
||||||
mutex_lock(&instance->cdev->lock);
|
mutex_lock(&instance->cdev->lock);
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
* Copyright (C) 2008 Intel Corp
|
* Copyright (C) 2008 Intel Corp
|
||||||
* Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
|
* Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
|
||||||
* Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
|
* Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
|
||||||
|
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
@@ -33,6 +34,8 @@ MODULE_AUTHOR("Zhang Rui");
|
|||||||
MODULE_DESCRIPTION("Generic thermal management sysfs support");
|
MODULE_DESCRIPTION("Generic thermal management sysfs support");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
|
|
||||||
|
#define THERMAL_MAX_ACTIVE 16
|
||||||
|
|
||||||
static DEFINE_IDA(thermal_tz_ida);
|
static DEFINE_IDA(thermal_tz_ida);
|
||||||
static DEFINE_IDA(thermal_cdev_ida);
|
static DEFINE_IDA(thermal_cdev_ida);
|
||||||
|
|
||||||
@@ -49,6 +52,8 @@ static bool power_off_triggered;
|
|||||||
|
|
||||||
static struct thermal_governor *def_governor;
|
static struct thermal_governor *def_governor;
|
||||||
|
|
||||||
|
static struct workqueue_struct *thermal_passive_wq;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Governor section: set of functions to handle thermal governors
|
* Governor section: set of functions to handle thermal governors
|
||||||
*
|
*
|
||||||
@@ -292,19 +297,18 @@ static int __init thermal_register_governors(void)
|
|||||||
* - Hot trips will produce a notification to userspace;
|
* - Hot trips will produce a notification to userspace;
|
||||||
* - Critical trip point will cause a system shutdown.
|
* - Critical trip point will cause a system shutdown.
|
||||||
*/
|
*/
|
||||||
static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
|
static void thermal_zone_device_set_polling(struct workqueue_struct *queue,
|
||||||
|
struct thermal_zone_device *tz,
|
||||||
int delay)
|
int delay)
|
||||||
{
|
{
|
||||||
if (delay > 1000)
|
if (delay > 1000)
|
||||||
mod_delayed_work(system_freezable_power_efficient_wq,
|
mod_delayed_work(queue, &tz->poll_queue,
|
||||||
&tz->poll_queue,
|
|
||||||
round_jiffies(msecs_to_jiffies(delay)));
|
round_jiffies(msecs_to_jiffies(delay)));
|
||||||
else if (delay)
|
else if (delay)
|
||||||
mod_delayed_work(system_freezable_power_efficient_wq,
|
mod_delayed_work(queue, &tz->poll_queue,
|
||||||
&tz->poll_queue,
|
|
||||||
msecs_to_jiffies(delay));
|
msecs_to_jiffies(delay));
|
||||||
else
|
else
|
||||||
cancel_delayed_work_sync(&tz->poll_queue);
|
cancel_delayed_work(&tz->poll_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void monitor_thermal_zone(struct thermal_zone_device *tz)
|
static void monitor_thermal_zone(struct thermal_zone_device *tz)
|
||||||
@@ -312,11 +316,14 @@ static void monitor_thermal_zone(struct thermal_zone_device *tz)
|
|||||||
mutex_lock(&tz->lock);
|
mutex_lock(&tz->lock);
|
||||||
|
|
||||||
if (tz->passive)
|
if (tz->passive)
|
||||||
thermal_zone_device_set_polling(tz, tz->passive_delay);
|
thermal_zone_device_set_polling(thermal_passive_wq,
|
||||||
|
tz, tz->passive_delay);
|
||||||
else if (tz->polling_delay)
|
else if (tz->polling_delay)
|
||||||
thermal_zone_device_set_polling(tz, tz->polling_delay);
|
thermal_zone_device_set_polling(
|
||||||
|
system_freezable_power_efficient_wq,
|
||||||
|
tz, tz->polling_delay);
|
||||||
else
|
else
|
||||||
thermal_zone_device_set_polling(tz, 0);
|
thermal_zone_device_set_polling(NULL, tz, 0);
|
||||||
|
|
||||||
mutex_unlock(&tz->lock);
|
mutex_unlock(&tz->lock);
|
||||||
}
|
}
|
||||||
@@ -386,7 +393,7 @@ static void handle_critical_trips(struct thermal_zone_device *tz,
|
|||||||
if (trip_temp <= 0 || tz->temperature < trip_temp)
|
if (trip_temp <= 0 || tz->temperature < trip_temp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
trace_thermal_zone_trip(tz, trip, trip_type);
|
trace_thermal_zone_trip(tz, trip, trip_type, true);
|
||||||
|
|
||||||
if (tz->ops->notify)
|
if (tz->ops->notify)
|
||||||
tz->ops->notify(tz, trip, trip_type);
|
tz->ops->notify(tz, trip, trip_type);
|
||||||
@@ -428,6 +435,23 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
|
|||||||
* So, start monitoring again.
|
* So, start monitoring again.
|
||||||
*/
|
*/
|
||||||
monitor_thermal_zone(tz);
|
monitor_thermal_zone(tz);
|
||||||
|
trace_thermal_handle_trip(tz, trip);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void store_temperature(struct thermal_zone_device *tz, int temp)
|
||||||
|
{
|
||||||
|
mutex_lock(&tz->lock);
|
||||||
|
tz->last_temperature = tz->temperature;
|
||||||
|
tz->temperature = temp;
|
||||||
|
mutex_unlock(&tz->lock);
|
||||||
|
|
||||||
|
trace_thermal_temperature(tz);
|
||||||
|
if (tz->last_temperature == THERMAL_TEMP_INVALID)
|
||||||
|
dev_dbg(&tz->device, "last_temperature N/A, current_temperature=%d\n",
|
||||||
|
tz->temperature);
|
||||||
|
else
|
||||||
|
dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
|
||||||
|
tz->last_temperature, tz->temperature);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_temperature(struct thermal_zone_device *tz)
|
static void update_temperature(struct thermal_zone_device *tz)
|
||||||
@@ -442,19 +466,7 @@ static void update_temperature(struct thermal_zone_device *tz)
|
|||||||
ret);
|
ret);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
store_temperature(tz, temp);
|
||||||
mutex_lock(&tz->lock);
|
|
||||||
tz->last_temperature = tz->temperature;
|
|
||||||
tz->temperature = temp;
|
|
||||||
mutex_unlock(&tz->lock);
|
|
||||||
|
|
||||||
trace_thermal_temperature(tz);
|
|
||||||
if (tz->last_temperature == THERMAL_TEMP_INVALID)
|
|
||||||
dev_dbg(&tz->device, "last_temperature N/A, current_temperature=%d\n",
|
|
||||||
tz->temperature);
|
|
||||||
else
|
|
||||||
dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
|
|
||||||
tz->last_temperature, tz->temperature);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thermal_zone_device_init(struct thermal_zone_device *tz)
|
static void thermal_zone_device_init(struct thermal_zone_device *tz)
|
||||||
@@ -471,17 +483,36 @@ static void thermal_zone_device_reset(struct thermal_zone_device *tz)
|
|||||||
thermal_zone_device_init(tz);
|
thermal_zone_device_init(tz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void thermal_zone_device_update_temp(struct thermal_zone_device *tz,
|
||||||
|
enum thermal_notify_event event, int temp)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
|
||||||
|
if (atomic_read(&in_suspend) && tz->polling_delay)
|
||||||
|
return;
|
||||||
|
trace_thermal_device_update(tz, event);
|
||||||
|
store_temperature(tz, temp);
|
||||||
|
|
||||||
|
thermal_zone_set_trips(tz);
|
||||||
|
|
||||||
|
tz->notify_event = event;
|
||||||
|
|
||||||
|
for (count = 0; count < tz->trips; count++)
|
||||||
|
handle_thermal_trip(tz, count);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(thermal_zone_device_update_temp);
|
||||||
|
|
||||||
void thermal_zone_device_update(struct thermal_zone_device *tz,
|
void thermal_zone_device_update(struct thermal_zone_device *tz,
|
||||||
enum thermal_notify_event event)
|
enum thermal_notify_event event)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
if (atomic_read(&in_suspend))
|
if (atomic_read(&in_suspend) && tz->polling_delay)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!tz->ops->get_temp)
|
if (!tz->ops->get_temp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
trace_thermal_device_update(tz, event);
|
||||||
update_temperature(tz);
|
update_temperature(tz);
|
||||||
|
|
||||||
thermal_zone_set_trips(tz);
|
thermal_zone_set_trips(tz);
|
||||||
@@ -710,9 +741,26 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* lower default 0, upper default max_state */
|
/*
|
||||||
lower = lower == THERMAL_NO_LIMIT ? 0 : lower;
|
* If upper or lower has a MACRO to define the mitigation state,
|
||||||
upper = upper == THERMAL_NO_LIMIT ? max_state : upper;
|
* based on the MACRO determine the default state to use or the
|
||||||
|
* offset from the max_state.
|
||||||
|
*/
|
||||||
|
if (upper >= (THERMAL_MAX_LIMIT - max_state)) {
|
||||||
|
/* upper default max_state */
|
||||||
|
if (upper == THERMAL_NO_LIMIT)
|
||||||
|
upper = max_state;
|
||||||
|
else
|
||||||
|
upper = max_state - (THERMAL_MAX_LIMIT - upper);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lower >= (THERMAL_MAX_LIMIT - max_state)) {
|
||||||
|
/* lower default 0 */
|
||||||
|
if (lower == THERMAL_NO_LIMIT)
|
||||||
|
lower = 0;
|
||||||
|
else
|
||||||
|
lower = max_state - (THERMAL_MAX_LIMIT - lower);
|
||||||
|
}
|
||||||
|
|
||||||
if (lower > upper || upper > max_state)
|
if (lower > upper || upper > max_state)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -839,6 +887,7 @@ static void thermal_release(struct device *dev)
|
|||||||
{
|
{
|
||||||
struct thermal_zone_device *tz;
|
struct thermal_zone_device *tz;
|
||||||
struct thermal_cooling_device *cdev;
|
struct thermal_cooling_device *cdev;
|
||||||
|
struct thermal_instance *instance;
|
||||||
|
|
||||||
if (!strncmp(dev_name(dev), "thermal_zone",
|
if (!strncmp(dev_name(dev), "thermal_zone",
|
||||||
sizeof("thermal_zone") - 1)) {
|
sizeof("thermal_zone") - 1)) {
|
||||||
@@ -848,6 +897,12 @@ static void thermal_release(struct device *dev)
|
|||||||
} else if (!strncmp(dev_name(dev), "cooling_device",
|
} else if (!strncmp(dev_name(dev), "cooling_device",
|
||||||
sizeof("cooling_device") - 1)) {
|
sizeof("cooling_device") - 1)) {
|
||||||
cdev = to_cooling_device(dev);
|
cdev = to_cooling_device(dev);
|
||||||
|
if (list_is_singular(&cdev->thermal_instances)) {
|
||||||
|
instance = list_first_entry(&cdev->thermal_instances,
|
||||||
|
typeof(*instance), cdev_node);
|
||||||
|
list_del(&instance->cdev_node);
|
||||||
|
kfree(instance);
|
||||||
|
}
|
||||||
kfree(cdev);
|
kfree(cdev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -953,6 +1008,7 @@ __thermal_cooling_device_register(struct device_node *np,
|
|||||||
struct thermal_cooling_device *cdev;
|
struct thermal_cooling_device *cdev;
|
||||||
struct thermal_zone_device *pos = NULL;
|
struct thermal_zone_device *pos = NULL;
|
||||||
int result;
|
int result;
|
||||||
|
struct thermal_instance *instance;
|
||||||
|
|
||||||
if (type && strlen(type) >= THERMAL_NAME_LENGTH)
|
if (type && strlen(type) >= THERMAL_NAME_LENGTH)
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
@@ -965,9 +1021,16 @@ __thermal_cooling_device_register(struct device_node *np,
|
|||||||
if (!cdev)
|
if (!cdev)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
instance = kzalloc(sizeof(*instance), GFP_KERNEL);
|
||||||
|
if (!instance) {
|
||||||
|
kfree(cdev);
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
result = ida_simple_get(&thermal_cdev_ida, 0, 0, GFP_KERNEL);
|
result = ida_simple_get(&thermal_cdev_ida, 0, 0, GFP_KERNEL);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
kfree(cdev);
|
kfree(cdev);
|
||||||
|
kfree(instance);
|
||||||
return ERR_PTR(result);
|
return ERR_PTR(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -975,6 +1038,8 @@ __thermal_cooling_device_register(struct device_node *np,
|
|||||||
strlcpy(cdev->type, type ? : "", sizeof(cdev->type));
|
strlcpy(cdev->type, type ? : "", sizeof(cdev->type));
|
||||||
mutex_init(&cdev->lock);
|
mutex_init(&cdev->lock);
|
||||||
INIT_LIST_HEAD(&cdev->thermal_instances);
|
INIT_LIST_HEAD(&cdev->thermal_instances);
|
||||||
|
instance->target = THERMAL_NO_TARGET;
|
||||||
|
list_add_tail(&instance->cdev_node, &cdev->thermal_instances);
|
||||||
cdev->np = np;
|
cdev->np = np;
|
||||||
cdev->ops = ops;
|
cdev->ops = ops;
|
||||||
cdev->updated = false;
|
cdev->updated = false;
|
||||||
@@ -1345,7 +1410,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
|
|||||||
/* Bind cooling devices for this zone */
|
/* Bind cooling devices for this zone */
|
||||||
bind_tz(tz);
|
bind_tz(tz);
|
||||||
|
|
||||||
INIT_DELAYED_WORK(&tz->poll_queue, thermal_zone_device_check);
|
INIT_DEFERRABLE_WORK(&(tz->poll_queue), thermal_zone_device_check);
|
||||||
|
|
||||||
thermal_zone_device_reset(tz);
|
thermal_zone_device_reset(tz);
|
||||||
/* Update the new thermal zone and mark it as already updated. */
|
/* Update the new thermal zone and mark it as already updated. */
|
||||||
@@ -1414,7 +1479,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
|
|||||||
|
|
||||||
mutex_unlock(&thermal_list_lock);
|
mutex_unlock(&thermal_list_lock);
|
||||||
|
|
||||||
thermal_zone_device_set_polling(tz, 0);
|
cancel_delayed_work_sync(&tz->poll_queue);
|
||||||
|
|
||||||
thermal_set_governor(tz, NULL);
|
thermal_set_governor(tz, NULL);
|
||||||
|
|
||||||
@@ -1576,7 +1641,8 @@ static int thermal_pm_notify(struct notifier_block *nb,
|
|||||||
if (tz->ops->get_mode)
|
if (tz->ops->get_mode)
|
||||||
tz->ops->get_mode(tz, &tz_mode);
|
tz->ops->get_mode(tz, &tz_mode);
|
||||||
|
|
||||||
if (tz_mode == THERMAL_DEVICE_DISABLED)
|
if (tz_mode == THERMAL_DEVICE_DISABLED ||
|
||||||
|
tz->polling_delay == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
thermal_zone_device_init(tz);
|
thermal_zone_device_init(tz);
|
||||||
@@ -1599,21 +1665,26 @@ static int __init thermal_init(void)
|
|||||||
int result;
|
int result;
|
||||||
|
|
||||||
mutex_init(&poweroff_lock);
|
mutex_init(&poweroff_lock);
|
||||||
|
thermal_passive_wq = alloc_workqueue("thermal_passive_wq",
|
||||||
|
WQ_HIGHPRI | WQ_UNBOUND
|
||||||
|
| WQ_FREEZABLE,
|
||||||
|
THERMAL_MAX_ACTIVE);
|
||||||
|
if (!thermal_passive_wq) {
|
||||||
|
result = -ENOMEM;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
result = thermal_register_governors();
|
result = thermal_register_governors();
|
||||||
if (result)
|
if (result)
|
||||||
goto error;
|
goto destroy_wq;
|
||||||
|
|
||||||
result = class_register(&thermal_class);
|
result = class_register(&thermal_class);
|
||||||
if (result)
|
if (result)
|
||||||
goto unregister_governors;
|
goto unregister_governors;
|
||||||
|
|
||||||
result = genetlink_init();
|
|
||||||
if (result)
|
|
||||||
goto unregister_class;
|
|
||||||
|
|
||||||
result = of_parse_thermal_zones();
|
result = of_parse_thermal_zones();
|
||||||
if (result)
|
if (result)
|
||||||
goto exit_netlink;
|
goto unregister_class;
|
||||||
|
|
||||||
result = register_pm_notifier(&thermal_pm_nb);
|
result = register_pm_notifier(&thermal_pm_nb);
|
||||||
if (result)
|
if (result)
|
||||||
@@ -1622,12 +1693,12 @@ static int __init thermal_init(void)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
exit_netlink:
|
|
||||||
genetlink_exit();
|
|
||||||
unregister_class:
|
unregister_class:
|
||||||
class_unregister(&thermal_class);
|
class_unregister(&thermal_class);
|
||||||
unregister_governors:
|
unregister_governors:
|
||||||
thermal_unregister_governors();
|
thermal_unregister_governors();
|
||||||
|
destroy_wq:
|
||||||
|
destroy_workqueue(thermal_passive_wq);
|
||||||
error:
|
error:
|
||||||
ida_destroy(&thermal_tz_ida);
|
ida_destroy(&thermal_tz_ida);
|
||||||
ida_destroy(&thermal_cdev_ida);
|
ida_destroy(&thermal_cdev_ida);
|
||||||
@@ -1636,4 +1707,33 @@ error:
|
|||||||
mutex_destroy(&poweroff_lock);
|
mutex_destroy(&poweroff_lock);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
fs_initcall(thermal_init);
|
|
||||||
|
static void thermal_exit(void)
|
||||||
|
{
|
||||||
|
unregister_pm_notifier(&thermal_pm_nb);
|
||||||
|
of_thermal_destroy_zones();
|
||||||
|
destroy_workqueue(thermal_passive_wq);
|
||||||
|
genetlink_exit();
|
||||||
|
class_unregister(&thermal_class);
|
||||||
|
thermal_unregister_governors();
|
||||||
|
ida_destroy(&thermal_tz_ida);
|
||||||
|
ida_destroy(&thermal_cdev_ida);
|
||||||
|
mutex_destroy(&thermal_list_lock);
|
||||||
|
mutex_destroy(&thermal_governor_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init thermal_netlink_init(void)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ret = genetlink_init();
|
||||||
|
if (!ret)
|
||||||
|
goto exit_netlink;
|
||||||
|
|
||||||
|
thermal_exit();
|
||||||
|
exit_netlink:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
subsys_initcall(thermal_init);
|
||||||
|
fs_initcall(thermal_netlink_init);
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 2012 Intel Corp
|
* Copyright (C) 2012 Intel Corp
|
||||||
* Author: Durgadoss R <durgadoss.r@intel.com>
|
* Author: Durgadoss R <durgadoss.r@intel.com>
|
||||||
|
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __THERMAL_CORE_H__
|
#ifndef __THERMAL_CORE_H__
|
||||||
@@ -97,6 +98,12 @@ int of_thermal_get_ntrips(struct thermal_zone_device *);
|
|||||||
bool of_thermal_is_trip_valid(struct thermal_zone_device *, int);
|
bool of_thermal_is_trip_valid(struct thermal_zone_device *, int);
|
||||||
const struct thermal_trip *
|
const struct thermal_trip *
|
||||||
of_thermal_get_trip_points(struct thermal_zone_device *);
|
of_thermal_get_trip_points(struct thermal_zone_device *);
|
||||||
|
int of_thermal_aggregate_trip(struct thermal_zone_device *tz,
|
||||||
|
enum thermal_trip_type type,
|
||||||
|
int *low, int *high);
|
||||||
|
void of_thermal_handle_trip(struct thermal_zone_device *tz);
|
||||||
|
void of_thermal_handle_trip_temp(struct thermal_zone_device *tz,
|
||||||
|
int trip_temp);
|
||||||
#else
|
#else
|
||||||
static inline int of_parse_thermal_zones(void) { return 0; }
|
static inline int of_parse_thermal_zones(void) { return 0; }
|
||||||
static inline void of_thermal_destroy_zones(void) { }
|
static inline void of_thermal_destroy_zones(void) { }
|
||||||
@@ -114,6 +121,19 @@ of_thermal_get_trip_points(struct thermal_zone_device *tz)
|
|||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
static inline int of_thermal_aggregate_trip(struct thermal_zone_device *tz,
|
||||||
|
enum thermal_trip_type type,
|
||||||
|
int *low, int *high)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
static inline
|
||||||
|
void of_thermal_handle_trip(struct thermal_zone_device *tz)
|
||||||
|
{ }
|
||||||
|
static inline
|
||||||
|
void of_thermal_handle_trip_temp(struct thermal_zone_device *tz,
|
||||||
|
int trip_temp)
|
||||||
|
{ }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __THERMAL_CORE_H__ */
|
#endif /* __THERMAL_CORE_H__ */
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
* Copyright (C) 2008 Intel Corp
|
* Copyright (C) 2008 Intel Corp
|
||||||
* Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
|
* Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
|
||||||
* Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
|
* Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
|
||||||
|
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
@@ -106,7 +107,7 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
|
|||||||
if (!ret && *temp < crit_temp)
|
if (!ret && *temp < crit_temp)
|
||||||
*temp = tz->emul_temperature;
|
*temp = tz->emul_temperature;
|
||||||
}
|
}
|
||||||
|
trace_thermal_query_temp(tz, *temp);
|
||||||
mutex_unlock(&tz->lock);
|
mutex_unlock(&tz->lock);
|
||||||
exit:
|
exit:
|
||||||
return ret;
|
return ret;
|
||||||
@@ -140,10 +141,6 @@ void thermal_zone_set_trips(struct thermal_zone_device *tz)
|
|||||||
high = trip_temp;
|
high = trip_temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No need to change trip points */
|
|
||||||
if (tz->prev_low_trip == low && tz->prev_high_trip == high)
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
tz->prev_low_trip = low;
|
tz->prev_low_trip = low;
|
||||||
tz->prev_high_trip = high;
|
tz->prev_high_trip = high;
|
||||||
|
|
||||||
@@ -157,6 +154,7 @@ void thermal_zone_set_trips(struct thermal_zone_device *tz)
|
|||||||
ret = tz->ops->set_trips(tz, low, high);
|
ret = tz->ops->set_trips(tz, low, high);
|
||||||
if (ret)
|
if (ret)
|
||||||
dev_err(&tz->device, "Failed to set trips: %d\n", ret);
|
dev_err(&tz->device, "Failed to set trips: %d\n", ret);
|
||||||
|
trace_thermal_set_trip(tz);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
mutex_unlock(&tz->lock);
|
mutex_unlock(&tz->lock);
|
||||||
@@ -177,6 +175,11 @@ void thermal_cdev_update(struct thermal_cooling_device *cdev)
|
|||||||
|
|
||||||
/* Make sure cdev enters the deepest cooling state */
|
/* Make sure cdev enters the deepest cooling state */
|
||||||
list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
|
list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
|
||||||
|
if (list_is_first(&instance->cdev_node,
|
||||||
|
&cdev->thermal_instances))
|
||||||
|
dev_dbg(&cdev->device, "userspace->target=%lu\n",
|
||||||
|
instance->target);
|
||||||
|
else
|
||||||
dev_dbg(&cdev->device, "zone%d->target=%lu\n",
|
dev_dbg(&cdev->device, "zone%d->target=%lu\n",
|
||||||
instance->tz->id, instance->target);
|
instance->tz->id, instance->target);
|
||||||
if (instance->target == THERMAL_NO_TARGET)
|
if (instance->target == THERMAL_NO_TARGET)
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
* Copyright (C) 2008 Intel Corp
|
* Copyright (C) 2008 Intel Corp
|
||||||
* Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
|
* Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
|
||||||
* Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
|
* Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
|
||||||
|
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
@@ -63,6 +64,28 @@ mode_show(struct device *dev, struct device_attribute *attr, char *buf)
|
|||||||
: "disabled");
|
: "disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int thermal_zone_device_clear(struct thermal_zone_device *tz)
|
||||||
|
{
|
||||||
|
struct thermal_instance *pos;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ret = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
|
||||||
|
mutex_lock(&tz->lock);
|
||||||
|
tz->temperature = THERMAL_TEMP_INVALID;
|
||||||
|
tz->passive = 0;
|
||||||
|
list_for_each_entry(pos, &tz->thermal_instances, tz_node) {
|
||||||
|
pos->initialized = false;
|
||||||
|
pos->target = THERMAL_NO_TARGET;
|
||||||
|
mutex_lock(&pos->cdev->lock);
|
||||||
|
pos->cdev->updated = false; /* cdev needs update */
|
||||||
|
mutex_unlock(&pos->cdev->lock);
|
||||||
|
thermal_cdev_update(pos->cdev);
|
||||||
|
}
|
||||||
|
mutex_unlock(&tz->lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
mode_store(struct device *dev, struct device_attribute *attr,
|
mode_store(struct device *dev, struct device_attribute *attr,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
@@ -76,7 +99,7 @@ mode_store(struct device *dev, struct device_attribute *attr,
|
|||||||
if (!strncmp(buf, "enabled", sizeof("enabled") - 1))
|
if (!strncmp(buf, "enabled", sizeof("enabled") - 1))
|
||||||
result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
|
result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
|
||||||
else if (!strncmp(buf, "disabled", sizeof("disabled") - 1))
|
else if (!strncmp(buf, "disabled", sizeof("disabled") - 1))
|
||||||
result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
|
result = thermal_zone_device_clear(tz);
|
||||||
else
|
else
|
||||||
result = -EINVAL;
|
result = -EINVAL;
|
||||||
|
|
||||||
@@ -348,6 +371,24 @@ sustainable_power_store(struct device *dev, struct device_attribute *devattr,
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
polling_delay_show(struct device *dev, struct device_attribute *attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
struct thermal_zone_device *tz = to_thermal_zone(dev);
|
||||||
|
|
||||||
|
return scnprintf(buf, PAGE_SIZE, "%d\n", tz->polling_delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
passive_delay_show(struct device *dev, struct device_attribute *attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
struct thermal_zone_device *tz = to_thermal_zone(dev);
|
||||||
|
|
||||||
|
return scnprintf(buf, PAGE_SIZE, "%d\n", tz->passive_delay);
|
||||||
|
}
|
||||||
|
|
||||||
#define create_s32_tzp_attr(name) \
|
#define create_s32_tzp_attr(name) \
|
||||||
static ssize_t \
|
static ssize_t \
|
||||||
name##_show(struct device *dev, struct device_attribute *devattr, \
|
name##_show(struct device *dev, struct device_attribute *devattr, \
|
||||||
@@ -399,6 +440,8 @@ static DEVICE_ATTR_RO(temp);
|
|||||||
static DEVICE_ATTR_RW(policy);
|
static DEVICE_ATTR_RW(policy);
|
||||||
static DEVICE_ATTR_RO(available_policies);
|
static DEVICE_ATTR_RO(available_policies);
|
||||||
static DEVICE_ATTR_RW(sustainable_power);
|
static DEVICE_ATTR_RW(sustainable_power);
|
||||||
|
static DEVICE_ATTR_RO(passive_delay);
|
||||||
|
static DEVICE_ATTR_RO(polling_delay);
|
||||||
|
|
||||||
/* These thermal zone device attributes are created based on conditions */
|
/* These thermal zone device attributes are created based on conditions */
|
||||||
static DEVICE_ATTR_RW(mode);
|
static DEVICE_ATTR_RW(mode);
|
||||||
@@ -414,6 +457,8 @@ static struct attribute *thermal_zone_dev_attrs[] = {
|
|||||||
&dev_attr_policy.attr,
|
&dev_attr_policy.attr,
|
||||||
&dev_attr_available_policies.attr,
|
&dev_attr_available_policies.attr,
|
||||||
&dev_attr_sustainable_power.attr,
|
&dev_attr_sustainable_power.attr,
|
||||||
|
&dev_attr_passive_delay.attr,
|
||||||
|
&dev_attr_polling_delay.attr,
|
||||||
&dev_attr_k_po.attr,
|
&dev_attr_k_po.attr,
|
||||||
&dev_attr_k_pu.attr,
|
&dev_attr_k_pu.attr,
|
||||||
&dev_attr_k_i.attr,
|
&dev_attr_k_i.attr,
|
||||||
@@ -704,7 +749,7 @@ cur_state_store(struct device *dev, struct device_attribute *attr,
|
|||||||
{
|
{
|
||||||
struct thermal_cooling_device *cdev = to_cooling_device(dev);
|
struct thermal_cooling_device *cdev = to_cooling_device(dev);
|
||||||
unsigned long state;
|
unsigned long state;
|
||||||
int result;
|
struct thermal_instance *instance = NULL;
|
||||||
|
|
||||||
if (sscanf(buf, "%ld\n", &state) != 1)
|
if (sscanf(buf, "%ld\n", &state) != 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -713,13 +758,15 @@ cur_state_store(struct device *dev, struct device_attribute *attr,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
mutex_lock(&cdev->lock);
|
mutex_lock(&cdev->lock);
|
||||||
|
instance = list_first_entry(&cdev->thermal_instances,
|
||||||
|
typeof(*instance), cdev_node);
|
||||||
|
instance->target = state;
|
||||||
|
|
||||||
result = cdev->ops->set_cur_state(cdev, state);
|
cdev->updated = false;
|
||||||
if (!result)
|
|
||||||
thermal_cooling_device_stats_update(cdev, state);
|
|
||||||
|
|
||||||
mutex_unlock(&cdev->lock);
|
mutex_unlock(&cdev->lock);
|
||||||
return result ? result : count;
|
thermal_cdev_update(cdev);
|
||||||
|
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct device_attribute
|
static struct device_attribute
|
||||||
@@ -770,6 +817,9 @@ void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev,
|
|||||||
{
|
{
|
||||||
struct cooling_dev_stats *stats = cdev->stats;
|
struct cooling_dev_stats *stats = cdev->stats;
|
||||||
|
|
||||||
|
if (!stats)
|
||||||
|
return;
|
||||||
|
|
||||||
spin_lock(&stats->lock);
|
spin_lock(&stats->lock);
|
||||||
|
|
||||||
if (stats->state == new_state)
|
if (stats->state == new_state)
|
||||||
@@ -791,6 +841,9 @@ static ssize_t total_trans_show(struct device *dev,
|
|||||||
struct cooling_dev_stats *stats = cdev->stats;
|
struct cooling_dev_stats *stats = cdev->stats;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (!stats)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
spin_lock(&stats->lock);
|
spin_lock(&stats->lock);
|
||||||
ret = sprintf(buf, "%u\n", stats->total_trans);
|
ret = sprintf(buf, "%u\n", stats->total_trans);
|
||||||
spin_unlock(&stats->lock);
|
spin_unlock(&stats->lock);
|
||||||
@@ -807,6 +860,9 @@ time_in_state_ms_show(struct device *dev, struct device_attribute *attr,
|
|||||||
ssize_t len = 0;
|
ssize_t len = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (!stats)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
spin_lock(&stats->lock);
|
spin_lock(&stats->lock);
|
||||||
update_time_in_state(stats);
|
update_time_in_state(stats);
|
||||||
|
|
||||||
@@ -825,8 +881,12 @@ reset_store(struct device *dev, struct device_attribute *attr, const char *buf,
|
|||||||
{
|
{
|
||||||
struct thermal_cooling_device *cdev = to_cooling_device(dev);
|
struct thermal_cooling_device *cdev = to_cooling_device(dev);
|
||||||
struct cooling_dev_stats *stats = cdev->stats;
|
struct cooling_dev_stats *stats = cdev->stats;
|
||||||
int i, states = stats->max_states;
|
int i, states;
|
||||||
|
|
||||||
|
if (!stats)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
states = stats->max_states;
|
||||||
spin_lock(&stats->lock);
|
spin_lock(&stats->lock);
|
||||||
|
|
||||||
stats->total_trans = 0;
|
stats->total_trans = 0;
|
||||||
@@ -850,6 +910,9 @@ static ssize_t trans_table_show(struct device *dev,
|
|||||||
ssize_t len = 0;
|
ssize_t len = 0;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
|
if (!stats)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n");
|
len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n");
|
||||||
len += snprintf(buf + len, PAGE_SIZE - len, " : ");
|
len += snprintf(buf + len, PAGE_SIZE - len, " : ");
|
||||||
for (i = 0; i < stats->max_states; i++) {
|
for (i = 0; i < stats->max_states; i++) {
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
* Copyright (C) 2008 Intel Corp
|
* Copyright (C) 2008 Intel Corp
|
||||||
* Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
|
* Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
|
||||||
* Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
|
* Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
|
||||||
|
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __THERMAL_H__
|
#ifndef __THERMAL_H__
|
||||||
@@ -26,6 +27,9 @@
|
|||||||
/* No upper/lower limit requirement */
|
/* No upper/lower limit requirement */
|
||||||
#define THERMAL_NO_LIMIT ((u32)~0)
|
#define THERMAL_NO_LIMIT ((u32)~0)
|
||||||
|
|
||||||
|
/* upper limit requirement */
|
||||||
|
#define THERMAL_MAX_LIMIT (THERMAL_NO_LIMIT - 1)
|
||||||
|
|
||||||
/* Default weight of a bound cooling device */
|
/* Default weight of a bound cooling device */
|
||||||
#define THERMAL_WEIGHT_DEFAULT 0
|
#define THERMAL_WEIGHT_DEFAULT 0
|
||||||
|
|
||||||
@@ -440,6 +444,8 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int,
|
|||||||
struct thermal_cooling_device *);
|
struct thermal_cooling_device *);
|
||||||
void thermal_zone_device_update(struct thermal_zone_device *,
|
void thermal_zone_device_update(struct thermal_zone_device *,
|
||||||
enum thermal_notify_event);
|
enum thermal_notify_event);
|
||||||
|
void thermal_zone_device_update_temp(struct thermal_zone_device *tz,
|
||||||
|
enum thermal_notify_event event, int temp);
|
||||||
void thermal_zone_set_trips(struct thermal_zone_device *);
|
void thermal_zone_set_trips(struct thermal_zone_device *);
|
||||||
|
|
||||||
struct thermal_cooling_device *thermal_cooling_device_register(const char *,
|
struct thermal_cooling_device *thermal_cooling_device_register(const char *,
|
||||||
@@ -498,6 +504,10 @@ static inline int thermal_zone_unbind_cooling_device(
|
|||||||
static inline void thermal_zone_device_update(struct thermal_zone_device *tz,
|
static inline void thermal_zone_device_update(struct thermal_zone_device *tz,
|
||||||
enum thermal_notify_event event)
|
enum thermal_notify_event event)
|
||||||
{ }
|
{ }
|
||||||
|
static inline void thermal_zone_device_update_temp(
|
||||||
|
struct thermal_zone_device *tz, enum thermal_notify_event event,
|
||||||
|
int temp)
|
||||||
|
{ }
|
||||||
static inline void thermal_zone_set_trips(struct thermal_zone_device *tz)
|
static inline void thermal_zone_set_trips(struct thermal_zone_device *tz)
|
||||||
{ }
|
{ }
|
||||||
static inline struct thermal_cooling_device *
|
static inline struct thermal_cooling_device *
|
||||||
|
@@ -21,6 +21,29 @@ TRACE_DEFINE_ENUM(THERMAL_TRIP_ACTIVE);
|
|||||||
{ THERMAL_TRIP_PASSIVE, "PASSIVE"}, \
|
{ THERMAL_TRIP_PASSIVE, "PASSIVE"}, \
|
||||||
{ THERMAL_TRIP_ACTIVE, "ACTIVE"})
|
{ THERMAL_TRIP_ACTIVE, "ACTIVE"})
|
||||||
|
|
||||||
|
TRACE_EVENT(thermal_query_temp,
|
||||||
|
|
||||||
|
TP_PROTO(struct thermal_zone_device *tz, int temp),
|
||||||
|
|
||||||
|
TP_ARGS(tz, temp),
|
||||||
|
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__string(thermal_zone, tz->type)
|
||||||
|
__field(int, id)
|
||||||
|
__field(int, temp)
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_fast_assign(
|
||||||
|
__assign_str(thermal_zone, tz->type);
|
||||||
|
__entry->id = tz->id;
|
||||||
|
__entry->temp = temp;
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_printk("thermal_zone=%s id=%d temp=%d",
|
||||||
|
__get_str(thermal_zone), __entry->id,
|
||||||
|
__entry->temp)
|
||||||
|
);
|
||||||
|
|
||||||
TRACE_EVENT(thermal_temperature,
|
TRACE_EVENT(thermal_temperature,
|
||||||
|
|
||||||
TP_PROTO(struct thermal_zone_device *tz),
|
TP_PROTO(struct thermal_zone_device *tz),
|
||||||
@@ -68,15 +91,16 @@ TRACE_EVENT(cdev_update,
|
|||||||
TRACE_EVENT(thermal_zone_trip,
|
TRACE_EVENT(thermal_zone_trip,
|
||||||
|
|
||||||
TP_PROTO(struct thermal_zone_device *tz, int trip,
|
TP_PROTO(struct thermal_zone_device *tz, int trip,
|
||||||
enum thermal_trip_type trip_type),
|
enum thermal_trip_type trip_type, bool is_trip),
|
||||||
|
|
||||||
TP_ARGS(tz, trip, trip_type),
|
TP_ARGS(tz, trip, trip_type, is_trip),
|
||||||
|
|
||||||
TP_STRUCT__entry(
|
TP_STRUCT__entry(
|
||||||
__string(thermal_zone, tz->type)
|
__string(thermal_zone, tz->type)
|
||||||
__field(int, id)
|
__field(int, id)
|
||||||
__field(int, trip)
|
__field(int, trip)
|
||||||
__field(enum thermal_trip_type, trip_type)
|
__field(enum thermal_trip_type, trip_type)
|
||||||
|
__field(bool, is_trip)
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
@@ -84,13 +108,85 @@ TRACE_EVENT(thermal_zone_trip,
|
|||||||
__entry->id = tz->id;
|
__entry->id = tz->id;
|
||||||
__entry->trip = trip;
|
__entry->trip = trip;
|
||||||
__entry->trip_type = trip_type;
|
__entry->trip_type = trip_type;
|
||||||
|
__entry->is_trip = is_trip;
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_printk("thermal_zone=%s id=%d trip=%d trip_type=%s",
|
TP_printk("thermal_zone=%s id=%d %s=%d trip_type=%s",
|
||||||
__get_str(thermal_zone), __entry->id, __entry->trip,
|
__get_str(thermal_zone), __entry->id,
|
||||||
|
(__entry->is_trip) ? "trip" : "hyst",
|
||||||
|
__entry->trip,
|
||||||
show_tzt_type(__entry->trip_type))
|
show_tzt_type(__entry->trip_type))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
TRACE_EVENT(thermal_handle_trip,
|
||||||
|
|
||||||
|
TP_PROTO(struct thermal_zone_device *tz, int trip),
|
||||||
|
|
||||||
|
TP_ARGS(tz, trip),
|
||||||
|
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__string(thermal_zone, tz->type)
|
||||||
|
__field(int, id)
|
||||||
|
__field(int, trip)
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_fast_assign(
|
||||||
|
__assign_str(thermal_zone, tz->type);
|
||||||
|
__entry->id = tz->id;
|
||||||
|
__entry->trip = trip;
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_printk("thermal_zone=%s id=%d handle trip=%d",
|
||||||
|
__get_str(thermal_zone), __entry->id, __entry->trip)
|
||||||
|
);
|
||||||
|
|
||||||
|
TRACE_EVENT(thermal_device_update,
|
||||||
|
|
||||||
|
TP_PROTO(struct thermal_zone_device *tz, int event),
|
||||||
|
|
||||||
|
TP_ARGS(tz, event),
|
||||||
|
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__string(thermal_zone, tz->type)
|
||||||
|
__field(int, id)
|
||||||
|
__field(int, event)
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_fast_assign(
|
||||||
|
__assign_str(thermal_zone, tz->type);
|
||||||
|
__entry->id = tz->id;
|
||||||
|
__entry->event = event;
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_printk("thermal_zone=%s id=%d received event:%d",
|
||||||
|
__get_str(thermal_zone), __entry->id, __entry->event)
|
||||||
|
);
|
||||||
|
|
||||||
|
TRACE_EVENT(thermal_set_trip,
|
||||||
|
|
||||||
|
TP_PROTO(struct thermal_zone_device *tz),
|
||||||
|
|
||||||
|
TP_ARGS(tz),
|
||||||
|
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__string(thermal_zone, tz->type)
|
||||||
|
__field(int, id)
|
||||||
|
__field(int, low)
|
||||||
|
__field(int, high)
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_fast_assign(
|
||||||
|
__assign_str(thermal_zone, tz->type);
|
||||||
|
__entry->id = tz->id;
|
||||||
|
__entry->low = tz->prev_low_trip;
|
||||||
|
__entry->high = tz->prev_high_trip;
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_printk("thermal_zone=%s id=%d low trip=%d high trip=%d",
|
||||||
|
__get_str(thermal_zone), __entry->id, __entry->low,
|
||||||
|
__entry->high)
|
||||||
|
);
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_THERMAL
|
#ifdef CONFIG_CPU_THERMAL
|
||||||
TRACE_EVENT(thermal_power_cpu_get_power,
|
TRACE_EVENT(thermal_power_cpu_get_power,
|
||||||
TP_PROTO(const struct cpumask *cpus, unsigned long freq, u32 *load,
|
TP_PROTO(const struct cpumask *cpus, unsigned long freq, u32 *load,
|
||||||
|
Reference in New Issue
Block a user