Adds implementation of trip flags and temeprature for 'switch_on' and 'desired' temperature for control algorithm.
Signed-off-by: Lukasz Luba l.luba@partner.samsung.com --- kernel/sched/power.c | 78 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-)
diff --git a/kernel/sched/power.c b/kernel/sched/power.c index c66c8dca2465..3ae497d2ba34 100644 --- a/kernel/sched/power.c +++ b/kernel/sched/power.c @@ -470,11 +470,19 @@ fs_initcall(sched_power_init);
/////////////////thermal governor////////////////////////
+struct trip_ctrl_alg { + int switch_on_id; + int switch_on_temp; + int desired_id; + int desired_temp; +}; + struct _thermal_zone { struct thermal_zone_device *tz; bool single_cooling_dev; struct list_head node; struct list_head cooling_list; + struct trip_ctrl_alg trip_ctrl_alg; };
struct _cooling_dev { @@ -649,6 +657,68 @@ static bool cdev_in_instance_list(struct _thermal_zone *zone, return false; }
+static int sched_power_setup_trips(struct _thermal_zone *zone) +{ + int i; + struct thermal_zone_device *tz = zone->tz; + enum thermal_trip_ctrl_alg alg_flag; + int ret; + int temp; + + zone->trip_ctrl_alg.switch_on_id = -EINVAL; + zone->trip_ctrl_alg.desired_id = -EINVAL; + + for (i = 0; i < tz->trips; i++) { + ret = tz->ops->get_trip_ctrl_alg_flag(tz, i, + &alg_flag); + if (ret < 0) + continue; + + switch (alg_flag) { + case THERMAL_TRIP_CTRL_ALG_SWITCH_ON: + zone->trip_ctrl_alg.switch_on_id = i; + break; + case THERMAL_TRIP_CTRL_ALG_DESIRED: + zone->trip_ctrl_alg.desired_id = i; + break; + default: break; + } + } + + if (zone->trip_ctrl_alg.desired_id >= 0) { + int trip; + + trip = zone->trip_ctrl_alg.desired_id; + ret = tz->ops->get_trip_temp(tz, trip, &temp); + if (!ret) { + zone->trip_ctrl_alg.desired_temp = temp; + } else { + zone->trip_ctrl_alg.desired_id = -EINVAL; + pr_warn("missing 'desired' temp\n"); + } + + trip = zone->trip_ctrl_alg.switch_on_id; + if (trip >= 0) { + ret = tz->ops->get_trip_temp(tz, trip, &temp); + if (!ret) { + zone->trip_ctrl_alg.switch_on_temp = temp; + } else { + zone->trip_ctrl_alg.switch_on_id = -EINVAL; + pr_warn("missing desired' temp\n"); + } + } else { + pr_warn("missing 'swith_on' temp\n"); + } + } + + if (zone->trip_ctrl_alg.desired_id < 0) { + pr_warn("could not find temperature settings\n"); + ret = -EINVAL; + } + + return 0; +} + static int sched_power_gov_bind(struct thermal_zone_device *tz) { struct thermal_instance *inst; @@ -656,7 +726,7 @@ static int sched_power_gov_bind(struct thermal_zone_device *tz) struct _cooling_dev *cooling, *prev_cooling = NULL; struct _cooling_instance *_inst, *tmp; struct thermal_cooling_device *cdev; - int i = 0; + int i = 0, ret; int cpu; int cpus_size; struct cpumask *cpumask; @@ -723,6 +793,12 @@ static int sched_power_gov_bind(struct thermal_zone_device *tz) zone->single_cooling_dev = (i == 1 ? true : false); zone->tz = tz;
+ ret = sched_power_setup_trips(zone); + if (ret < 0) { + pr_info("lack of temp settings in DT allowing to control \ + the algorithm\n"); + } + mutex_lock(&tz_list_lock); list_add(&zone->node, &tz_list); mutex_unlock(&tz_list_lock);