sched/power: add support of trip control algorithm
authorLukasz Luba <l.luba@partner.samsung.com>
Thu, 8 Nov 2018 11:03:16 +0000 (12:03 +0100)
committerLukasz Luba <l.luba@partner.samsung.com>
Fri, 17 May 2019 07:15:47 +0000 (09:15 +0200)
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

index c66c8dca246583ae9e5549c0288259d87e793a38..3ae497d2ba34bb11bf7385e3330c27993f9a6952 100644 (file)
@@ -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);