Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp4661263pxv; Tue, 6 Jul 2021 06:23:50 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz/Uxze1w40QCMVl948U5eQnHgUwsUBQRmUVdaCJNWPLfooA7UUVNpoJZto8lW5sQwEk8pU X-Received: by 2002:a05:6402:c10:: with SMTP id co16mr22396638edb.192.1625577830468; Tue, 06 Jul 2021 06:23:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1625577830; cv=none; d=google.com; s=arc-20160816; b=hkL0hqWtOIeWjRABwvHMeHHk4u5Uw7k4Q2lnR1s2u5JKpewNjUtwijdSYCyn55DGyl 9ISZiEzotAAMuiUbx53kxCzwKrGW+vwY9UZwmcNh3HPvP8H4kQ1OVvjs5I6OwihHHyYp HnMNo2+QPOK4HWgVnhnV80q/wHOEVm3UTKv4kQUpe2iC/M/2SrVLbhKa8gIGngDcj8hc /lX/x2VdveVYmPpk67zexkhMmFyBa5D3pW8U/DQxldljtN7lpV4rjc0jr3ANu7IaFx1T /8lGUZgo7D/0nwAE9dX0aqZxcPiq+th+BxtkbiMB1K4rNgsomwz5Xy/dmYU4YDtUcJpy FpNw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from; bh=Exwv0aqKqCEAEgUsRVD0rx7g+MxA3VvUJiSfSAnGyyE=; b=iCKTDOiu4cko4Ifv+DghnQtS5I8rp1qkYFdCp/GSod7szxDfdqLsk6ifr/TWReLzmC TSr9jYSsCOqVB7AB3FkQ92w3DgTNdZyFd6xngjGXcgFSXEkQfj8evm/TsBYsA3mU3N2n cQiMmugQGo35yn7my/lApVjIU/6W4Y/j0RCUhvYcpxnWGqjRpCxqU/co+Rl3NbOas1mc 6KdYrHruBagClsIInNzWNfNdFbrb8O7/ZmfV1nyUhOpCWGDCPSzoHSqbeN+liOATntWU ltaJUx7QG18edrJfjJyS229qDUVTXmPy2S5sWEncWls+MA9FoyTuAdZNqwzotWHcWj44 vukg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id ds15si6704861ejc.696.2021.07.06.06.23.26; Tue, 06 Jul 2021 06:23:50 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231944AbhGFNVe (ORCPT + 99 others); Tue, 6 Jul 2021 09:21:34 -0400 Received: from foss.arm.com ([217.140.110.172]:42182 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231843AbhGFNVa (ORCPT ); Tue, 6 Jul 2021 09:21:30 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0EB341FB; Tue, 6 Jul 2021 06:18:52 -0700 (PDT) Received: from e123648.arm.com (unknown [10.57.7.228]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id D91383F73B; Tue, 6 Jul 2021 06:18:49 -0700 (PDT) From: Lukasz Luba To: linux-kernel@vger.kernel.org, daniel.lezcano@linaro.org Cc: linux-pm@vger.kernel.org, amitk@kernel.org, rui.zhang@intel.com, lukasz.luba@arm.com, dietmar.eggemann@arm.com, Chris.Redpath@arm.com, Beata.Michalska@arm.com, viresh.kumar@linaro.org, rjw@rjwysocki.net, amit.kachhap@gmail.com Subject: [RFC PATCH v2 5/6] thermal/core/power allocator: Prepare power actors and calm down when not used Date: Tue, 6 Jul 2021 14:18:27 +0100 Message-Id: <20210706131828.22309-6-lukasz.luba@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210706131828.22309-1-lukasz.luba@arm.com> References: <20210706131828.22309-1-lukasz.luba@arm.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The cooling devices in thermal zone can support an interface for preparation to work with thermal governor. They should be properly setup before the first throttling happens, which means the internal power tracking mechanism should be ready. When the IPA is not used or thermal zone is disabled the power tracking can be stopped. Thus, add the code which handles cooling device proper setup for the operation with IPA. Signed-off-by: Lukasz Luba --- drivers/thermal/gov_power_allocator.c | 71 +++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/drivers/thermal/gov_power_allocator.c b/drivers/thermal/gov_power_allocator.c index 13e375751d22..678fb544c8af 100644 --- a/drivers/thermal/gov_power_allocator.c +++ b/drivers/thermal/gov_power_allocator.c @@ -53,6 +53,8 @@ static inline s64 div_frac(s64 x, s64 y) * struct power_allocator_params - parameters for the power allocator governor * @allocated_tzp: whether we have allocated tzp for this thermal zone and * it needs to be freed on unbind + * @actors_ready: set to 1 when power actors are properly setup or set to + * -EINVAL when there were errors during preparation * @err_integral: accumulated error in the PID controller. * @prev_err: error in the previous iteration of the PID controller. * Used to calculate the derivative term. @@ -68,6 +70,7 @@ static inline s64 div_frac(s64 x, s64 y) */ struct power_allocator_params { bool allocated_tzp; + int actors_ready; s64 err_integral; s32 prev_err; int trip_switch_on; @@ -693,9 +696,20 @@ static int power_allocator_bind(struct thermal_zone_device *tz) static void power_allocator_unbind(struct thermal_zone_device *tz) { struct power_allocator_params *params = tz->governor_data; + struct thermal_instance *instance; dev_dbg(&tz->device, "Unbinding from thermal zone %d\n", tz->id); + /* Calm down cooling devices and stop monitoring mechanims */ + list_for_each_entry(instance, &tz->thermal_instances, tz_node) { + struct thermal_cooling_device *cdev = instance->cdev; + + if (!cdev_is_power_actor(cdev)) + continue; + if (cdev->ops->change_governor) + cdev->ops->change_governor(cdev, false); + } + if (params->allocated_tzp) { kfree(tz->tzp); tz->tzp = NULL; @@ -705,6 +719,51 @@ static void power_allocator_unbind(struct thermal_zone_device *tz) tz->governor_data = NULL; } +static int prepare_power_actors(struct thermal_zone_device *tz) +{ + struct power_allocator_params *params = tz->governor_data; + struct thermal_instance *instance; + int ret; + + if (params->actors_ready > 0) + return 0; + + if (params->actors_ready < 0) + return -EINVAL; + + mutex_lock(&tz->lock); + + list_for_each_entry(instance, &tz->thermal_instances, tz_node) { + struct thermal_cooling_device *cdev = instance->cdev; + + if (!cdev_is_power_actor(cdev)) + continue; + if (cdev->ops->change_governor) { + ret = cdev->ops->change_governor(cdev, true); + if (ret) + goto clean_up; + } + } + + mutex_unlock(&tz->lock); + params->actors_ready = 1; + return 0; + +clean_up: + list_for_each_entry(instance, &tz->thermal_instances, tz_node) { + struct thermal_cooling_device *cdev = instance->cdev; + + if (!cdev_is_power_actor(cdev)) + continue; + if (cdev->ops->change_governor) + cdev->ops->change_governor(cdev, false); + } + + mutex_unlock(&tz->lock); + params->actors_ready = -EINVAL; + return -EINVAL; +} + static int power_allocator_throttle(struct thermal_zone_device *tz, int trip) { int ret; @@ -719,6 +778,18 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip) if (trip != params->trip_max_desired_temperature) return 0; + /* + * If we are called for the first time (e.g. after enabling thermal + * zone), setup properly power actors + */ + ret = prepare_power_actors(tz); + if (ret) { + dev_warn_once(&tz->device, + "Failed to setup IPA power actors: %d\n", + ret); + return ret; + } + ret = tz->ops->get_trip_temp(tz, params->trip_switch_on, &switch_on_temp); if (!ret && (tz->temperature < switch_on_temp)) { -- 2.17.1