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 | 51 +++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 20 deletions(-)
diff --git a/kernel/sched/power.c b/kernel/sched/power.c index a630f4a532ef..cf56484f95ca 100644 --- a/kernel/sched/power.c +++ b/kernel/sched/power.c @@ -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;