mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 14:19:09 -04:00
Merge "drivers: thermal: Add QTI_THERMAL config"
This commit is contained in:
commit
8213b6428a
8 changed files with 481 additions and 113 deletions
|
|
@ -401,6 +401,18 @@ depends on (ARCH_QCOM && OF) || COMPILE_TEST
|
|||
source "drivers/thermal/qcom/Kconfig"
|
||||
endmenu
|
||||
|
||||
config QTI_THERMAL
|
||||
bool
|
||||
prompt "Enable QTI Thermal Framework enhancements"
|
||||
depends on THERMAL && QGKI
|
||||
default y
|
||||
help
|
||||
Enable the QTI enhancements on the thermal framework. This will
|
||||
enable enhancements like handling passive evaluation on high
|
||||
priority queue, using same trip temperature from sensor to algorithm
|
||||
and enabling user space thermal daemon as a separate client of
|
||||
cooling device.
|
||||
|
||||
config ZX2967_THERMAL
|
||||
tristate "Thermal sensors on zx2967 SoC"
|
||||
depends on ARCH_ZX || COMPILE_TEST
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
* if the cooling state already equals lower limit,
|
||||
* deactivate the thermal instance
|
||||
*/
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
static unsigned long get_target_state(struct thermal_instance *instance,
|
||||
enum thermal_trend trend, bool throttle)
|
||||
{
|
||||
|
|
@ -110,6 +111,75 @@ static unsigned long get_target_state(struct thermal_instance *instance,
|
|||
|
||||
return next_target;
|
||||
}
|
||||
#else
|
||||
static unsigned long get_target_state(struct thermal_instance *instance,
|
||||
enum thermal_trend trend, bool throttle)
|
||||
{
|
||||
struct thermal_cooling_device *cdev = instance->cdev;
|
||||
unsigned long cur_state;
|
||||
unsigned long next_target;
|
||||
|
||||
/*
|
||||
* We keep this instance the way it is by default.
|
||||
* Otherwise, we use the current state of the
|
||||
* cdev in use to determine the next_target.
|
||||
*/
|
||||
cdev->ops->get_cur_state(cdev, &cur_state);
|
||||
next_target = instance->target;
|
||||
dev_dbg(&cdev->device, "cur_state=%ld\n", cur_state);
|
||||
|
||||
if (!instance->initialized) {
|
||||
if (throttle) {
|
||||
next_target = (cur_state + 1) >= instance->upper ?
|
||||
instance->upper :
|
||||
((cur_state + 1) < instance->lower ?
|
||||
instance->lower : (cur_state + 1));
|
||||
} else {
|
||||
next_target = THERMAL_NO_TARGET;
|
||||
}
|
||||
|
||||
return next_target;
|
||||
}
|
||||
|
||||
switch (trend) {
|
||||
case THERMAL_TREND_RAISING:
|
||||
if (throttle) {
|
||||
next_target = cur_state < instance->upper ?
|
||||
(cur_state + 1) : instance->upper;
|
||||
if (next_target < instance->lower)
|
||||
next_target = instance->lower;
|
||||
}
|
||||
break;
|
||||
case THERMAL_TREND_RAISE_FULL:
|
||||
if (throttle)
|
||||
next_target = instance->upper;
|
||||
break;
|
||||
case THERMAL_TREND_DROPPING:
|
||||
if (cur_state <= instance->lower) {
|
||||
if (!throttle)
|
||||
next_target = THERMAL_NO_TARGET;
|
||||
} else {
|
||||
if (!throttle) {
|
||||
next_target = cur_state - 1;
|
||||
if (next_target > instance->upper)
|
||||
next_target = instance->upper;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case THERMAL_TREND_DROP_FULL:
|
||||
if (cur_state == instance->lower) {
|
||||
if (!throttle)
|
||||
next_target = THERMAL_NO_TARGET;
|
||||
} else
|
||||
next_target = instance->lower;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return next_target;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void update_passive_instance(struct thermal_zone_device *tz,
|
||||
enum thermal_trip_type type, int value)
|
||||
|
|
@ -122,6 +192,7 @@ static void update_passive_instance(struct thermal_zone_device *tz,
|
|||
tz->passive += value;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
|
||||
{
|
||||
int trip_temp, hyst_temp;
|
||||
|
|
@ -208,6 +279,66 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
|
|||
|
||||
mutex_unlock(&tz->lock);
|
||||
}
|
||||
#else
|
||||
static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
|
||||
{
|
||||
int trip_temp;
|
||||
enum thermal_trip_type trip_type;
|
||||
enum thermal_trend trend;
|
||||
struct thermal_instance *instance;
|
||||
bool throttle = false;
|
||||
int old_target;
|
||||
|
||||
if (trip == THERMAL_TRIPS_NONE) {
|
||||
trip_temp = tz->forced_passive;
|
||||
trip_type = THERMAL_TRIPS_NONE;
|
||||
} else {
|
||||
tz->ops->get_trip_temp(tz, trip, &trip_temp);
|
||||
tz->ops->get_trip_type(tz, trip, &trip_type);
|
||||
}
|
||||
|
||||
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",
|
||||
trip, trip_type, trip_temp, trend, throttle);
|
||||
|
||||
mutex_lock(&tz->lock);
|
||||
|
||||
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
|
||||
if (instance->trip != trip)
|
||||
continue;
|
||||
|
||||
old_target = instance->target;
|
||||
instance->target = get_target_state(instance, trend, throttle);
|
||||
dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n",
|
||||
old_target, (int)instance->target);
|
||||
|
||||
if (instance->initialized && old_target == instance->target)
|
||||
continue;
|
||||
|
||||
/* Activate a passive thermal instance */
|
||||
if (old_target == THERMAL_NO_TARGET &&
|
||||
instance->target != THERMAL_NO_TARGET)
|
||||
update_passive_instance(tz, trip_type, 1);
|
||||
/* Deactivate a passive thermal instance */
|
||||
else if (old_target != THERMAL_NO_TARGET &&
|
||||
instance->target == THERMAL_NO_TARGET)
|
||||
update_passive_instance(tz, trip_type, -1);
|
||||
|
||||
instance->initialized = true;
|
||||
mutex_lock(&instance->cdev->lock);
|
||||
instance->cdev->updated = false; /* cdev needs update */
|
||||
mutex_unlock(&instance->cdev->lock);
|
||||
}
|
||||
|
||||
mutex_unlock(&tz->lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* step_wise_throttle - throttles devices associated with the given zone
|
||||
|
|
|
|||
|
|
@ -34,8 +34,6 @@ MODULE_AUTHOR("Zhang Rui");
|
|||
MODULE_DESCRIPTION("Generic thermal management sysfs support");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
#define THERMAL_MAX_ACTIVE 16
|
||||
|
||||
static DEFINE_IDA(thermal_tz_ida);
|
||||
static DEFINE_IDA(thermal_cdev_ida);
|
||||
|
||||
|
|
@ -52,8 +50,6 @@ static bool power_off_triggered;
|
|||
|
||||
static struct thermal_governor *def_governor;
|
||||
|
||||
static struct workqueue_struct *thermal_passive_wq;
|
||||
|
||||
/*
|
||||
* Governor section: set of functions to handle thermal governors
|
||||
*
|
||||
|
|
@ -297,6 +293,10 @@ static int __init thermal_register_governors(void)
|
|||
* - Hot trips will produce a notification to userspace;
|
||||
* - Critical trip point will cause a system shutdown.
|
||||
*/
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
#define THERMAL_MAX_ACTIVE 16
|
||||
|
||||
static struct workqueue_struct *thermal_passive_wq;
|
||||
static void thermal_zone_device_set_polling(struct workqueue_struct *queue,
|
||||
struct thermal_zone_device *tz,
|
||||
int delay)
|
||||
|
|
@ -327,6 +327,113 @@ static void monitor_thermal_zone(struct thermal_zone_device *tz)
|
|||
|
||||
mutex_unlock(&tz->lock);
|
||||
}
|
||||
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)
|
||||
{
|
||||
int temp, ret;
|
||||
|
||||
ret = thermal_zone_get_temp(tz, &temp);
|
||||
if (ret) {
|
||||
if (ret != -EAGAIN)
|
||||
dev_warn(&tz->device,
|
||||
"failed to read out thermal zone (%d)\n",
|
||||
ret);
|
||||
return;
|
||||
}
|
||||
store_temperature(tz, temp);
|
||||
}
|
||||
|
||||
static void handle_thermal_trip(struct thermal_zone_device *tz, int trip);
|
||||
|
||||
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);
|
||||
#else
|
||||
static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
|
||||
int delay)
|
||||
{
|
||||
if (delay > 1000)
|
||||
mod_delayed_work(system_freezable_power_efficient_wq,
|
||||
&tz->poll_queue,
|
||||
round_jiffies(msecs_to_jiffies(delay)));
|
||||
else if (delay)
|
||||
mod_delayed_work(system_freezable_power_efficient_wq,
|
||||
&tz->poll_queue,
|
||||
msecs_to_jiffies(delay));
|
||||
else
|
||||
cancel_delayed_work_sync(&tz->poll_queue);
|
||||
}
|
||||
|
||||
static void monitor_thermal_zone(struct thermal_zone_device *tz)
|
||||
{
|
||||
mutex_lock(&tz->lock);
|
||||
|
||||
if (tz->passive)
|
||||
thermal_zone_device_set_polling(tz, tz->passive_delay);
|
||||
else if (tz->polling_delay)
|
||||
thermal_zone_device_set_polling(tz, tz->polling_delay);
|
||||
else
|
||||
thermal_zone_device_set_polling(tz, 0);
|
||||
|
||||
mutex_unlock(&tz->lock);
|
||||
}
|
||||
static void update_temperature(struct thermal_zone_device *tz)
|
||||
{
|
||||
int temp, ret;
|
||||
|
||||
ret = thermal_zone_get_temp(tz, &temp);
|
||||
if (ret) {
|
||||
if (ret != -EAGAIN)
|
||||
dev_warn(&tz->device,
|
||||
"failed to read out thermal zone (%d)\n",
|
||||
ret);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void handle_non_critical_trips(struct thermal_zone_device *tz, int trip)
|
||||
{
|
||||
|
|
@ -393,7 +500,9 @@ static void handle_critical_trips(struct thermal_zone_device *tz,
|
|||
if (trip_temp <= 0 || tz->temperature < trip_temp)
|
||||
return;
|
||||
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
trace_thermal_zone_trip(tz, trip, trip_type, true);
|
||||
#endif
|
||||
|
||||
if (tz->ops->notify)
|
||||
tz->ops->notify(tz, trip, trip_type);
|
||||
|
|
@ -435,38 +544,9 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
|
|||
* So, start monitoring again.
|
||||
*/
|
||||
monitor_thermal_zone(tz);
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
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)
|
||||
{
|
||||
int temp, ret;
|
||||
|
||||
ret = thermal_zone_get_temp(tz, &temp);
|
||||
if (ret) {
|
||||
if (ret != -EAGAIN)
|
||||
dev_warn(&tz->device,
|
||||
"failed to read out thermal zone (%d)\n",
|
||||
ret);
|
||||
return;
|
||||
}
|
||||
store_temperature(tz, temp);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void thermal_zone_device_init(struct thermal_zone_device *tz)
|
||||
|
|
@ -483,36 +563,22 @@ static void thermal_zone_device_reset(struct thermal_zone_device *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,
|
||||
enum thermal_notify_event event)
|
||||
{
|
||||
int count;
|
||||
|
||||
if (atomic_read(&in_suspend) && tz->polling_delay)
|
||||
return;
|
||||
if (!tz->ops->get_temp)
|
||||
return;
|
||||
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
if (atomic_read(&in_suspend) && tz->polling_delay)
|
||||
return;
|
||||
trace_thermal_device_update(tz, event);
|
||||
#else
|
||||
if (atomic_read(&in_suspend))
|
||||
return;
|
||||
#endif
|
||||
|
||||
update_temperature(tz);
|
||||
|
||||
thermal_zone_set_trips(tz);
|
||||
|
|
@ -741,6 +807,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
/*
|
||||
* If upper or lower has a MACRO to define the mitigation state,
|
||||
* based on the MACRO determine the default state to use or the
|
||||
|
|
@ -761,6 +828,11 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
|
|||
else
|
||||
lower = max_state - (THERMAL_MAX_LIMIT - lower);
|
||||
}
|
||||
#else
|
||||
/* lower default 0, upper default max_state */
|
||||
lower = lower == THERMAL_NO_LIMIT ? 0 : lower;
|
||||
upper = upper == THERMAL_NO_LIMIT ? max_state : upper;
|
||||
#endif
|
||||
|
||||
if (lower > upper || upper > max_state)
|
||||
return -EINVAL;
|
||||
|
|
@ -883,6 +955,7 @@ unbind:
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_zone_unbind_cooling_device);
|
||||
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
static void thermal_release(struct device *dev)
|
||||
{
|
||||
struct thermal_zone_device *tz;
|
||||
|
|
@ -906,6 +979,24 @@ static void thermal_release(struct device *dev)
|
|||
kfree(cdev);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void thermal_release(struct device *dev)
|
||||
{
|
||||
struct thermal_zone_device *tz;
|
||||
struct thermal_cooling_device *cdev;
|
||||
|
||||
if (!strncmp(dev_name(dev), "thermal_zone",
|
||||
sizeof("thermal_zone") - 1)) {
|
||||
tz = to_thermal_zone(dev);
|
||||
thermal_zone_destroy_device_groups(tz);
|
||||
kfree(tz);
|
||||
} else if (!strncmp(dev_name(dev), "cooling_device",
|
||||
sizeof("cooling_device") - 1)) {
|
||||
cdev = to_cooling_device(dev);
|
||||
kfree(cdev);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct class thermal_class = {
|
||||
.name = "thermal",
|
||||
|
|
@ -1008,7 +1099,9 @@ __thermal_cooling_device_register(struct device_node *np,
|
|||
struct thermal_cooling_device *cdev;
|
||||
struct thermal_zone_device *pos = NULL;
|
||||
int result;
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
struct thermal_instance *instance;
|
||||
#endif
|
||||
|
||||
if (type && strlen(type) >= THERMAL_NAME_LENGTH)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
|
@ -1021,16 +1114,20 @@ __thermal_cooling_device_register(struct device_node *np,
|
|||
if (!cdev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
instance = kzalloc(sizeof(*instance), GFP_KERNEL);
|
||||
if (!instance) {
|
||||
kfree(cdev);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
#endif
|
||||
|
||||
result = ida_simple_get(&thermal_cdev_ida, 0, 0, GFP_KERNEL);
|
||||
if (result < 0) {
|
||||
kfree(cdev);
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
kfree(instance);
|
||||
#endif
|
||||
return ERR_PTR(result);
|
||||
}
|
||||
|
||||
|
|
@ -1038,8 +1135,10 @@ __thermal_cooling_device_register(struct device_node *np,
|
|||
strlcpy(cdev->type, type ? : "", sizeof(cdev->type));
|
||||
mutex_init(&cdev->lock);
|
||||
INIT_LIST_HEAD(&cdev->thermal_instances);
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
instance->target = THERMAL_NO_TARGET;
|
||||
list_add_tail(&instance->cdev_node, &cdev->thermal_instances);
|
||||
#endif
|
||||
cdev->np = np;
|
||||
cdev->ops = ops;
|
||||
cdev->updated = false;
|
||||
|
|
@ -1410,7 +1509,11 @@ thermal_zone_device_register(const char *type, int trips, int mask,
|
|||
/* Bind cooling devices for this zone */
|
||||
bind_tz(tz);
|
||||
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
INIT_DEFERRABLE_WORK(&(tz->poll_queue), thermal_zone_device_check);
|
||||
#else
|
||||
INIT_DELAYED_WORK(&tz->poll_queue, thermal_zone_device_check);
|
||||
#endif
|
||||
|
||||
thermal_zone_device_reset(tz);
|
||||
/* Update the new thermal zone and mark it as already updated. */
|
||||
|
|
@ -1641,9 +1744,14 @@ static int thermal_pm_notify(struct notifier_block *nb,
|
|||
if (tz->ops->get_mode)
|
||||
tz->ops->get_mode(tz, &tz_mode);
|
||||
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
if (tz_mode == THERMAL_DEVICE_DISABLED ||
|
||||
tz->polling_delay == 0)
|
||||
continue;
|
||||
#else
|
||||
if (tz_mode == THERMAL_DEVICE_DISABLED)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
thermal_zone_device_init(tz);
|
||||
thermal_zone_device_update(tz,
|
||||
|
|
@ -1660,6 +1768,7 @@ static struct notifier_block thermal_pm_nb = {
|
|||
.notifier_call = thermal_pm_notify,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
static int __init thermal_init(void)
|
||||
{
|
||||
int result;
|
||||
|
|
@ -1737,3 +1846,48 @@ exit_netlink:
|
|||
|
||||
subsys_initcall(thermal_init);
|
||||
fs_initcall(thermal_netlink_init);
|
||||
#else
|
||||
static int __init thermal_init(void)
|
||||
{
|
||||
int result;
|
||||
|
||||
mutex_init(&poweroff_lock);
|
||||
result = thermal_register_governors();
|
||||
if (result)
|
||||
goto error;
|
||||
|
||||
result = class_register(&thermal_class);
|
||||
if (result)
|
||||
goto unregister_governors;
|
||||
|
||||
result = genetlink_init();
|
||||
if (result)
|
||||
goto unregister_class;
|
||||
|
||||
result = of_parse_thermal_zones();
|
||||
if (result)
|
||||
goto exit_netlink;
|
||||
|
||||
result = register_pm_notifier(&thermal_pm_nb);
|
||||
if (result)
|
||||
pr_warn("Thermal: Can not register suspend notifier, return %d\n",
|
||||
result);
|
||||
|
||||
return 0;
|
||||
|
||||
exit_netlink:
|
||||
genetlink_exit();
|
||||
unregister_class:
|
||||
class_unregister(&thermal_class);
|
||||
unregister_governors:
|
||||
thermal_unregister_governors();
|
||||
error:
|
||||
ida_destroy(&thermal_tz_ida);
|
||||
ida_destroy(&thermal_cdev_ida);
|
||||
mutex_destroy(&thermal_list_lock);
|
||||
mutex_destroy(&thermal_governor_lock);
|
||||
mutex_destroy(&poweroff_lock);
|
||||
return result;
|
||||
}
|
||||
fs_initcall(thermal_init);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -98,12 +98,6 @@ int of_thermal_get_ntrips(struct thermal_zone_device *);
|
|||
bool of_thermal_is_trip_valid(struct thermal_zone_device *, int);
|
||||
const struct thermal_trip *
|
||||
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
|
||||
static inline int of_parse_thermal_zones(void) { return 0; }
|
||||
static inline void of_thermal_destroy_zones(void) { }
|
||||
|
|
@ -121,6 +115,15 @@ of_thermal_get_trip_points(struct thermal_zone_device *tz)
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
#if (defined(CONFIG_QTI_THERMAL) && defined(CONFIG_THERMAL_OF))
|
||||
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
|
||||
static inline int of_thermal_aggregate_trip(struct thermal_zone_device *tz,
|
||||
enum thermal_trip_type type,
|
||||
int *low, int *high)
|
||||
|
|
|
|||
|
|
@ -107,7 +107,9 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
|
|||
if (!ret && *temp < crit_temp)
|
||||
*temp = tz->emul_temperature;
|
||||
}
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
trace_thermal_query_temp(tz, *temp);
|
||||
#endif
|
||||
mutex_unlock(&tz->lock);
|
||||
exit:
|
||||
return ret;
|
||||
|
|
@ -141,6 +143,11 @@ void thermal_zone_set_trips(struct thermal_zone_device *tz)
|
|||
high = trip_temp;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_QTI_THERMAL
|
||||
/* No need to change trip points */
|
||||
if (tz->prev_low_trip == low && tz->prev_high_trip == high)
|
||||
goto exit;
|
||||
#endif
|
||||
tz->prev_low_trip = low;
|
||||
tz->prev_high_trip = high;
|
||||
|
||||
|
|
@ -154,7 +161,9 @@ void thermal_zone_set_trips(struct thermal_zone_device *tz)
|
|||
ret = tz->ops->set_trips(tz, low, high);
|
||||
if (ret)
|
||||
dev_err(&tz->device, "Failed to set trips: %d\n", ret);
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
trace_thermal_set_trip(tz);
|
||||
#endif
|
||||
|
||||
exit:
|
||||
mutex_unlock(&tz->lock);
|
||||
|
|
@ -175,6 +184,7 @@ void thermal_cdev_update(struct thermal_cooling_device *cdev)
|
|||
|
||||
/* Make sure cdev enters the deepest cooling state */
|
||||
list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
if (list_is_first(&instance->cdev_node,
|
||||
&cdev->thermal_instances))
|
||||
dev_dbg(&cdev->device, "userspace->target=%lu\n",
|
||||
|
|
@ -182,6 +192,10 @@ void thermal_cdev_update(struct thermal_cooling_device *cdev)
|
|||
else
|
||||
dev_dbg(&cdev->device, "zone%d->target=%lu\n",
|
||||
instance->tz->id, instance->target);
|
||||
#else
|
||||
dev_dbg(&cdev->device, "zone%d->target=%lu\n",
|
||||
instance->tz->id, instance->target);
|
||||
#endif
|
||||
if (instance->target == THERMAL_NO_TARGET)
|
||||
continue;
|
||||
if (instance->target > target)
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ mode_show(struct device *dev, struct device_attribute *attr, char *buf)
|
|||
: "disabled");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
static int thermal_zone_device_clear(struct thermal_zone_device *tz)
|
||||
{
|
||||
struct thermal_instance *pos;
|
||||
|
|
@ -85,6 +86,7 @@ static int thermal_zone_device_clear(struct thermal_zone_device *tz)
|
|||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static ssize_t
|
||||
mode_store(struct device *dev, struct device_attribute *attr,
|
||||
|
|
@ -99,7 +101,11 @@ mode_store(struct device *dev, struct device_attribute *attr,
|
|||
if (!strncmp(buf, "enabled", sizeof("enabled") - 1))
|
||||
result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
|
||||
else if (!strncmp(buf, "disabled", sizeof("disabled") - 1))
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
result = thermal_zone_device_clear(tz);
|
||||
#else
|
||||
result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
|
||||
#endif
|
||||
else
|
||||
result = -EINVAL;
|
||||
|
||||
|
|
@ -371,24 +377,6 @@ sustainable_power_store(struct device *dev, struct device_attribute *devattr,
|
|||
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) \
|
||||
static ssize_t \
|
||||
name##_show(struct device *dev, struct device_attribute *devattr, \
|
||||
|
|
@ -440,8 +428,6 @@ static DEVICE_ATTR_RO(temp);
|
|||
static DEVICE_ATTR_RW(policy);
|
||||
static DEVICE_ATTR_RO(available_policies);
|
||||
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 */
|
||||
static DEVICE_ATTR_RW(mode);
|
||||
|
|
@ -457,8 +443,6 @@ static struct attribute *thermal_zone_dev_attrs[] = {
|
|||
&dev_attr_policy.attr,
|
||||
&dev_attr_available_policies.attr,
|
||||
&dev_attr_sustainable_power.attr,
|
||||
&dev_attr_passive_delay.attr,
|
||||
&dev_attr_polling_delay.attr,
|
||||
&dev_attr_k_po.attr,
|
||||
&dev_attr_k_pu.attr,
|
||||
&dev_attr_k_i.attr,
|
||||
|
|
@ -743,18 +727,19 @@ static ssize_t cur_state_show(struct device *dev, struct device_attribute *attr,
|
|||
return sprintf(buf, "%ld\n", state);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
static ssize_t
|
||||
cur_state_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct thermal_cooling_device *cdev = to_cooling_device(dev);
|
||||
unsigned long state;
|
||||
long state;
|
||||
struct thermal_instance *instance = NULL;
|
||||
|
||||
if (sscanf(buf, "%ld\n", &state) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
if ((long)state < 0)
|
||||
if (state < 0)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&cdev->lock);
|
||||
|
|
@ -768,6 +753,31 @@ cur_state_store(struct device *dev, struct device_attribute *attr,
|
|||
|
||||
return count;
|
||||
}
|
||||
#else
|
||||
static ssize_t
|
||||
cur_state_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct thermal_cooling_device *cdev = to_cooling_device(dev);
|
||||
long state;
|
||||
int result;
|
||||
|
||||
if (sscanf(buf, "%ld\n", &state) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
if ((long)state < 0)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&cdev->lock);
|
||||
|
||||
result = cdev->ops->set_cur_state(cdev, state);
|
||||
if (!result)
|
||||
thermal_cooling_device_stats_update(cdev, state);
|
||||
|
||||
mutex_unlock(&cdev->lock);
|
||||
return result ? result : count;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct device_attribute
|
||||
dev_attr_cdev_type = __ATTR(type, 0444, cdev_type_show, NULL);
|
||||
|
|
@ -817,8 +827,10 @@ void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev,
|
|||
{
|
||||
struct cooling_dev_stats *stats = cdev->stats;
|
||||
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
if (!stats)
|
||||
return;
|
||||
#endif
|
||||
|
||||
spin_lock(&stats->lock);
|
||||
|
||||
|
|
@ -841,8 +853,10 @@ static ssize_t total_trans_show(struct device *dev,
|
|||
struct cooling_dev_stats *stats = cdev->stats;
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
if (!stats)
|
||||
return -ENODEV;
|
||||
#endif
|
||||
|
||||
spin_lock(&stats->lock);
|
||||
ret = sprintf(buf, "%u\n", stats->total_trans);
|
||||
|
|
@ -860,8 +874,10 @@ time_in_state_ms_show(struct device *dev, struct device_attribute *attr,
|
|||
ssize_t len = 0;
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
if (!stats)
|
||||
return -ENODEV;
|
||||
#endif
|
||||
|
||||
spin_lock(&stats->lock);
|
||||
update_time_in_state(stats);
|
||||
|
|
@ -881,12 +897,17 @@ reset_store(struct device *dev, struct device_attribute *attr, const char *buf,
|
|||
{
|
||||
struct thermal_cooling_device *cdev = to_cooling_device(dev);
|
||||
struct cooling_dev_stats *stats = cdev->stats;
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
int i, states;
|
||||
|
||||
if (!stats)
|
||||
return -ENODEV;
|
||||
|
||||
states = stats->max_states;
|
||||
#else
|
||||
int i, states = stats->max_states;
|
||||
|
||||
#endif
|
||||
spin_lock(&stats->lock);
|
||||
|
||||
stats->total_trans = 0;
|
||||
|
|
@ -910,8 +931,10 @@ static ssize_t trans_table_show(struct device *dev,
|
|||
ssize_t len = 0;
|
||||
int i, j;
|
||||
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
if (!stats)
|
||||
return -ENODEV;
|
||||
#endif
|
||||
|
||||
len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n");
|
||||
len += snprintf(buf + len, PAGE_SIZE - len, " : ");
|
||||
|
|
|
|||
|
|
@ -444,8 +444,15 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int,
|
|||
struct thermal_cooling_device *);
|
||||
void thermal_zone_device_update(struct thermal_zone_device *,
|
||||
enum thermal_notify_event);
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
void thermal_zone_device_update_temp(struct thermal_zone_device *tz,
|
||||
enum thermal_notify_event event, int temp);
|
||||
#else
|
||||
static inline void thermal_zone_device_update_temp(
|
||||
struct thermal_zone_device *tz, enum thermal_notify_event event,
|
||||
int temp)
|
||||
{ }
|
||||
#endif
|
||||
void thermal_zone_set_trips(struct thermal_zone_device *);
|
||||
|
||||
struct thermal_cooling_device *thermal_cooling_device_register(const char *,
|
||||
|
|
@ -504,10 +511,6 @@ static inline int thermal_zone_unbind_cooling_device(
|
|||
static inline void thermal_zone_device_update(struct thermal_zone_device *tz,
|
||||
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 struct thermal_cooling_device *
|
||||
|
|
|
|||
|
|
@ -21,29 +21,6 @@ TRACE_DEFINE_ENUM(THERMAL_TRIP_ACTIVE);
|
|||
{ THERMAL_TRIP_PASSIVE, "PASSIVE"}, \
|
||||
{ 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,
|
||||
|
||||
TP_PROTO(struct thermal_zone_device *tz),
|
||||
|
|
@ -88,6 +65,7 @@ TRACE_EVENT(cdev_update,
|
|||
TP_printk("type=%s target=%lu", __get_str(type), __entry->target)
|
||||
);
|
||||
|
||||
#ifdef CONFIG_QTI_THERMAL
|
||||
TRACE_EVENT(thermal_zone_trip,
|
||||
|
||||
TP_PROTO(struct thermal_zone_device *tz, int trip,
|
||||
|
|
@ -118,6 +96,29 @@ TRACE_EVENT(thermal_zone_trip,
|
|||
show_tzt_type(__entry->trip_type))
|
||||
);
|
||||
|
||||
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_handle_trip,
|
||||
|
||||
TP_PROTO(struct thermal_zone_device *tz, int trip),
|
||||
|
|
@ -186,6 +187,33 @@ TRACE_EVENT(thermal_set_trip,
|
|||
__get_str(thermal_zone), __entry->id, __entry->low,
|
||||
__entry->high)
|
||||
);
|
||||
#else
|
||||
TRACE_EVENT(thermal_zone_trip,
|
||||
|
||||
TP_PROTO(struct thermal_zone_device *tz, int trip,
|
||||
enum thermal_trip_type trip_type),
|
||||
|
||||
TP_ARGS(tz, trip, trip_type),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(thermal_zone, tz->type)
|
||||
__field(int, id)
|
||||
__field(int, trip)
|
||||
__field(enum thermal_trip_type, trip_type)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(thermal_zone, tz->type);
|
||||
__entry->id = tz->id;
|
||||
__entry->trip = trip;
|
||||
__entry->trip_type = trip_type;
|
||||
),
|
||||
|
||||
TP_printk("thermal_zone=%s id=%d trip=%d trip_type=%s",
|
||||
__get_str(thermal_zone), __entry->id, __entry->trip,
|
||||
show_tzt_type(__entry->trip_type))
|
||||
);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_THERMAL
|
||||
TRACE_EVENT(thermal_power_cpu_get_power,
|
||||
|
|
|
|||
Loading…
Reference in a new issue