sched/power: add check for max possible frequency of cooling device
authorLukasz Luba <l.luba@partner.samsung.com>
Tue, 13 Nov 2018 16:40:21 +0000 (17:40 +0100)
committerLukasz Luba <l.luba@partner.samsung.com>
Fri, 17 May 2019 07:15:53 +0000 (09:15 +0200)
The patch adds basic check for possible state change.
The 'target' state is compared with maximum allowed for the single
cooling device.

Signed-off-by: Lukasz Luba <l.luba@partner.samsung.com>
kernel/sched/power.c

index a630f4a532ef30f8cdff0a8fadd1904e7fe361e8..cf56484f95ca60b2532a2c945e29efead9043ce9 100644 (file)
@@ -240,14 +240,14 @@ static int sched_power_reweight_cluster(int cpu, struct cpumask *cpus,
        mutex_unlock(&tz_list_lock);
 
        if (system_zone) {
-               pr_info("zone found\n");
+               /* pr_info("zone found\n"); */
                mutex_lock(&system_zone->lock);
                cluster_inst->weight = weight;
                mutex_unlock(&system_zone->lock);
                thermal_notify_framework(system_zone->tz,
                                         system_zone->trip_ctrl_alg.desired_id);
        } else {
-               pr_info("no such zone\n");
+               /* pr_info("no such zone\n"); */
                return -ENODEV;
        }
 
@@ -279,7 +279,7 @@ static int sched_power_handle_request(struct power_request *req)
 
        cpower = (&per_cpu(cpu_power, req->cpu));
 
-       pr_info("req->flags=%d\n", req->flags);
+       /* pr_info("req->flags=%d\n", req->flags); */
        switch (req->flags) {
        case SCHED_POWER_CPU_WEIGHT:
                break;
@@ -317,8 +317,7 @@ static void sched_power_work(struct kthread_work *work)
                cpower->weight = req.weight;
                raw_spin_unlock(&cpower->update_lock);
 
-               pr_info("cpower req poped\n");
-               /* thermal_cpu_cdev_set_weight(req.cpu, req.weight); */
+               /* pr_info("cpower req poped\n"); */
                ret = sched_power_handle_request(&req);
                if (!ret)
                        need_update = true;
@@ -638,23 +637,32 @@ static int throttle_single_cdev(struct _thermal_zone *zone)
 
 static int cooling_dev_set_state(struct _thermal_zone *zone,
                                 struct _cooling_dev *cooling,
-                                unsigned long target)
+                                unsigned long target, unsigned long *set_state)
 {
        struct thermal_cooling_device *cdev = cooling->cdev;
        unsigned long curr_state;
        int ret = 0;
 
-       cdev->ops->get_cur_state(cdev, &curr_state);
+       ret = cdev->ops->get_cur_state(cdev, &curr_state);
+
+       if (ret)
+               return ret;
 
        if (curr_state == target)
                return 0;
 
-       /* check if we can it go with higher freq for zone with a few devices*/
-       if (!zone->single_cooling_dev && cooling->max_single_state > target)
-               return -EINVAL;
-
-       if (zone->single_cooling_dev && cooling->max_single_state > target)
+       /* check if we can go with higher freq for zone with a few devices*/
+       if (zone->single_cooling_dev) {
+               /* we treat single-cooling-dev-zone as a guard for max temp */
                cooling->max_single_state = target;
+       } else {
+               if (cooling->max_single_state < target) {
+                       target = cooling->max_single_state;
+                       ret = -EAGAIN;
+               }
+       }
+
+       *set_state = target;
 
        mutex_lock(&cdev->lock);
        if (!cdev->ops->set_cur_state(cdev, target))
@@ -672,19 +680,22 @@ static int _set_power(struct _cooling_instance *inst, struct _thermal_zone *zone
                     u32 power)
 {
        int ret;
-       unsigned long state;
+       unsigned long state = 0, target;
        struct thermal_cooling_device *cdev;
        struct thermal_zone_device *tz = zone->tz;
 
        cdev = inst->cooling->cdev;
-       ret = cdev->ops->power2state(cdev, tz, power, &state);
-       if (ret)
-               return ret;
-
-       pr_info("inst_weight=%u, set_power=%u, state=%lu, temp=%d\n",
-               inst->weight, power, state, tz->temperature);
+       ret = cdev->ops->power2state(cdev, tz, power, &target);
        if (!ret) {
-               ret = cooling_dev_set_state(zone, inst->cooling, state);
+               ret = cooling_dev_set_state(zone, inst->cooling, target,
+                                           &state);
+               if (!ret)
+                       pr_info("inst_weight=%u, set_power=%u, target=%lu, state=%lu, temp=%d\n",
+                               inst->weight, power, target, state,
+                               tz->temperature);
+               else
+                       pr_info("_set_power: ret=%d\n, target=%lu, state=%lu\n",
+                               ret, target, state);
        }
 
        return ret;