From: Lukasz Luba Date: Thu, 8 Nov 2018 11:03:16 +0000 (+0100) Subject: sched/power: add support of trip control algorithm X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e6e99b3d74bca4ffff89ba1f770872be2f8b1749;p=platform%2Fkernel%2Flinux-exynos.git sched/power: add support of trip control algorithm Adds implementation of trip flags and temeprature for 'switch_on' and 'desired' temperature for control algorithm. Signed-off-by: Lukasz Luba --- 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 @@ handle_cooling_instance: 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);