From patchwork Wed Aug 8 07:08:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 143611 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp482839ljj; Wed, 8 Aug 2018 00:08:33 -0700 (PDT) X-Google-Smtp-Source: AA+uWPyDfku0AcKxTkTGoBKVGaxBZoyWubZZcJFGlsSBxrUHwq+5JyvwvfAYY3mTQVgNDMDmo3n7 X-Received: by 2002:a17:902:3a5:: with SMTP id d34-v6mr1419947pld.98.1533712112891; Wed, 08 Aug 2018 00:08:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533712112; cv=none; d=google.com; s=arc-20160816; b=SL4CqF8qM7JeU4iwJHbM8IOx/P+NyTyCkg4DsSF13qTTVZLpwjWKqvUVlkc1Kw+waH S/9nh/0hh48hz/s/MLEv1l3YCrb56dJFPC9rSpM+0Pz73i4U82UESFFQLsM7omBxXuuc 7VFdfCe3S5Tc0AdyeEXLDkCXzSDhqDTfjUS9qKtIE6JryNntd+g6U+BErSfyKHcgYBJG cWC+pp2aTE+ZjcFyeCEfLwOoGBGjYB8fX6F7uj8kvQNaolBDRRtqD5427frXzq76KMxW qepQMH3uNX1tavoubdPH7vl/EAMmfjGGnLaGAQPk3ZmAilUii6F25jHOLrDQ1zbTNuXP 3oeA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=gm9pLZvgHT14Zk0drMD8vpxnkk6DbI5R03/WpG4qYKs=; b=HZGeTwM37Bpiq477LedyngnHCssCf6z3ejUhDrUTSQnwJ2AblE00wxP7xIf7E/uNyV 7upFhUScb1LqGG2WDglHjsWu/xFTSgcNiJyy2qEzOZ0D2UFjmCei3p6hv7eoMfBSXIe6 BFf3MSyYUZ8Y+OGcqq10smvafl79PmqBCYi9fHYCm+yXKgxbEoqpvtrUqD1Tcha8t+Lo M63VJvlMAnpBxW6VFYrDFzMkAe4MoHKqMf7RQYnbrBITgm417yqW9hlFkTrHBLzgE04I ymEu1yw3aTA3IDOkn+G6BKlOsOtW4y5zA8l/ZEyl4aqdIFj7MDC5teYU7qcB/UsMDnyj u4Zw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=bCwMejHF; spf=pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r10-v6si3798373pgm.535.2018.08.08.00.08.32; Wed, 08 Aug 2018 00:08:32 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=bCwMejHF; spf=pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726990AbeHHJ0u (ORCPT + 10 others); Wed, 8 Aug 2018 05:26:50 -0400 Received: from mail-pl0-f65.google.com ([209.85.160.65]:38295 "EHLO mail-pl0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726542AbeHHJ0t (ORCPT ); Wed, 8 Aug 2018 05:26:49 -0400 Received: by mail-pl0-f65.google.com with SMTP id u11-v6so620849plq.5 for ; Wed, 08 Aug 2018 00:08:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=gm9pLZvgHT14Zk0drMD8vpxnkk6DbI5R03/WpG4qYKs=; b=bCwMejHFXQ4lYtRT2SHjB7CvnPeB8qFrZq7HNK1SeoUB40TDLyxGPkQgW0VlvhlJlW ghm5MTKi6ddH/TnMEunBkqawf+Q/EJvKY6c545FE4ue2mBOuw5qJsqPShr+xT40PqGL2 K3P2f29vxo0m8t6AuPYWp8uMFshPh0j7Bll9c= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=gm9pLZvgHT14Zk0drMD8vpxnkk6DbI5R03/WpG4qYKs=; b=NeBw8hx4sZ6AL2LaI7qjZ+HANub+poep6XzPkPFNtceohuedjK+Qha3Y9KXdvDDt5O ViRrMGYSW7uQ54ZRbCAr1QrP4BjikEu06YAA0Mh+FB6nJ0Bjv3HgjzktIIUuETzRjKGi oB4ejhW0cddeg2BVNstOUNC9VSCcIF/pKS8fYQ+GBex0Jbl7hXwrIlBRDx9QsmhumMJq IDXuYndO/PcHXeXwi5Hrhf70QLDSAjBuA1HXb9Fk39zNTx+M1t59P6DLd3ZZW/NVL3/1 9O2+0PCIXpJzxBLqVF+R/sHOqS2xshlDbZS9GJ23YYHHAJsbqw8M/3EMPPNCK7uoLPnm t1oA== X-Gm-Message-State: AOUpUlE93b6c/3xu3rOZNKK8emv7VUtSCGuFho91kVYQnZzUOPcMT4AN eyHYfa8Jb1+P/Zg5nMVTb85ZAQ== X-Received: by 2002:a17:902:8303:: with SMTP id bd3-v6mr1413214plb.329.1533712109890; Wed, 08 Aug 2018 00:08:29 -0700 (PDT) Received: from localhost ([122.172.42.13]) by smtp.gmail.com with ESMTPSA id w13-v6sm3147084pgs.89.2018.08.08.00.08.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 08 Aug 2018 00:08:28 -0700 (PDT) From: Viresh Kumar To: Zhang Rui , Eduardo Valentin Cc: Viresh Kumar , Vincent Guittot , Daniel Lezcano , linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH V2] of: thermal: Allow multiple devices to share cooling map Date: Wed, 8 Aug 2018 12:38:14 +0530 Message-Id: <438c3792a41b31629fb702c919ad244db97c0283.1533711976.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.18.0.rc1.242.g61856ae69a2c In-Reply-To: References: Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org A cooling map entry may now contain a list of phandles and their arguments representing multiple devices which share the trip point. This patch updates the thermal OF core to parse them properly. The trip point and contribution value is shared by multiple cooling devices now and so a new structure is created, struct __thermal_cooling_bind_param, which represents a cooling device and its min/max states and the existing struct __thermal_bind_params now contains an array of this new cooling device structure. Tested on Hikey960. Signed-off-by: Viresh Kumar --- V2: - Updated commit log to include new structures information - Updated two error messages to give better error log drivers/thermal/of-thermal.c | 142 +++++++++++++++++++++++++---------- 1 file changed, 103 insertions(+), 39 deletions(-) -- 2.18.0.rc1.242.g61856ae69a2c diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index 977a8307fbb1..16b890a4fb50 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c @@ -19,22 +19,33 @@ /*** Private data structures to represent thermal device tree data ***/ /** - * struct __thermal_bind_param - a match between trip and cooling device + * struct __thermal_cooling_bind_param - a cooling device for a trip point * @cooling_device: a pointer to identify the referred cooling device - * @trip_id: the trip point index - * @usage: the percentage (from 0 to 100) of cooling contribution * @min: minimum cooling state used at this trip point * @max: maximum cooling state used at this trip point */ -struct __thermal_bind_params { +struct __thermal_cooling_bind_param { struct device_node *cooling_device; - unsigned int trip_id; - unsigned int usage; unsigned long min; unsigned long max; }; +/** + * struct __thermal_bind_param - a match between trip and cooling device + * @tcbp: a pointer to an array of cooling devices + * @count: number of elements in array + * @trip_id: the trip point index + * @usage: the percentage (from 0 to 100) of cooling contribution + */ + +struct __thermal_bind_params { + struct __thermal_cooling_bind_param *tcbp; + unsigned int count; + unsigned int trip_id; + unsigned int usage; +}; + /** * struct __thermal_zone - internal representation of a thermal zone * @mode: current thermal zone device mode (enabled/disabled) @@ -192,25 +203,31 @@ static int of_thermal_bind(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev) { struct __thermal_zone *data = thermal->devdata; - int i; + struct __thermal_bind_params *tbp; + struct __thermal_cooling_bind_param *tcbp; + int i, j; if (!data || IS_ERR(data)) return -ENODEV; /* find where to bind */ for (i = 0; i < data->num_tbps; i++) { - struct __thermal_bind_params *tbp = data->tbps + i; + tbp = data->tbps + i; - if (tbp->cooling_device == cdev->np) { - int ret; + for (j = 0; j < tbp->count; j++) { + tcbp = tbp->tcbp + j; - ret = thermal_zone_bind_cooling_device(thermal, + if (tcbp->cooling_device == cdev->np) { + int ret; + + ret = thermal_zone_bind_cooling_device(thermal, tbp->trip_id, cdev, - tbp->max, - tbp->min, + tcbp->max, + tcbp->min, tbp->usage); - if (ret) - return ret; + if (ret) + return ret; + } } } @@ -221,22 +238,28 @@ static int of_thermal_unbind(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev) { struct __thermal_zone *data = thermal->devdata; - int i; + struct __thermal_bind_params *tbp; + struct __thermal_cooling_bind_param *tcbp; + int i, j; if (!data || IS_ERR(data)) return -ENODEV; /* find where to unbind */ for (i = 0; i < data->num_tbps; i++) { - struct __thermal_bind_params *tbp = data->tbps + i; + tbp = data->tbps + i; + + for (j = 0; j < tbp->count; j++) { + tcbp = tbp->tcbp + j; - if (tbp->cooling_device == cdev->np) { - int ret; + if (tcbp->cooling_device == cdev->np) { + int ret; - ret = thermal_zone_unbind_cooling_device(thermal, - tbp->trip_id, cdev); - if (ret) - return ret; + ret = thermal_zone_unbind_cooling_device(thermal, + tbp->trip_id, cdev); + if (ret) + return ret; + } } } @@ -652,8 +675,9 @@ static int thermal_of_populate_bind_params(struct device_node *np, int ntrips) { struct of_phandle_args cooling_spec; + struct __thermal_cooling_bind_param *__tcbp; struct device_node *trip; - int ret, i; + int ret, i, count; u32 prop; /* Default weight. Usage is optional */ @@ -680,20 +704,44 @@ static int thermal_of_populate_bind_params(struct device_node *np, goto end; } - ret = of_parse_phandle_with_args(np, "cooling-device", "#cooling-cells", - 0, &cooling_spec); - if (ret < 0) { - pr_err("missing cooling_device property\n"); + count = of_count_phandle_with_args(np, "cooling-device", + "#cooling-cells"); + if (!count) { + pr_err("Add a cooling_device property with at least one device\n"); goto end; } - __tbp->cooling_device = cooling_spec.np; - if (cooling_spec.args_count >= 2) { /* at least min and max */ - __tbp->min = cooling_spec.args[0]; - __tbp->max = cooling_spec.args[1]; - } else { - pr_err("wrong reference to cooling device, missing limits\n"); + + __tcbp = kcalloc(count, sizeof(*__tcbp), GFP_KERNEL); + if (!__tcbp) + goto end; + + for (i = 0; i < count; i++) { + ret = of_parse_phandle_with_args(np, "cooling-device", + "#cooling-cells", i, &cooling_spec); + if (ret < 0) { + pr_err("Invalid cooling-device entry\n"); + goto free_tcbp; + } + + __tcbp[i].cooling_device = cooling_spec.np; + + if (cooling_spec.args_count >= 2) { /* at least min and max */ + __tcbp[i].min = cooling_spec.args[0]; + __tcbp[i].max = cooling_spec.args[1]; + } else { + pr_err("wrong reference to cooling device, missing limits\n"); + } } + __tbp->tcbp= __tcbp; + __tbp->count = count; + + goto end; + +free_tcbp: + for (i = i - 1; i >= 0; i--) + of_node_put(__tcbp[i].cooling_device); + kfree(__tcbp); end: of_node_put(trip); @@ -900,8 +948,16 @@ __init *thermal_of_build_thermal_zone(struct device_node *np) return tz; free_tbps: - for (i = i - 1; i >= 0; i--) - of_node_put(tz->tbps[i].cooling_device); + for (i = i - 1; i >= 0; i--) { + struct __thermal_bind_params *tbp = tz->tbps + i; + int j; + + for (j = 0; j < tbp->count; j++) + of_node_put(tbp->tcbp[j].cooling_device); + + kfree(tbp->tcbp); + } + kfree(tz->tbps); free_trips: for (i = 0; i < tz->ntrips; i++) @@ -917,10 +973,18 @@ __init *thermal_of_build_thermal_zone(struct device_node *np) static inline void of_thermal_free_zone(struct __thermal_zone *tz) { - int i; + struct __thermal_bind_params *tbp; + int i, j; + + for (i = 0; i < tz->num_tbps; i++) { + tbp = tz->tbps + i; + + for (j = 0; j < tbp->count; j++) + of_node_put(tbp->tcbp[j].cooling_device); + + kfree(tbp->tcbp); + } - for (i = 0; i < tz->num_tbps; i++) - of_node_put(tz->tbps[i].cooling_device); kfree(tz->tbps); for (i = 0; i < tz->ntrips; i++) of_node_put(tz->trips[i].np);