From patchwork Fri Sep 11 12:02:02 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 53454 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f197.google.com (mail-wi0-f197.google.com [209.85.212.197]) by patches.linaro.org (Postfix) with ESMTPS id B684A215BF for ; Fri, 11 Sep 2015 12:03:16 +0000 (UTC) Received: by wicuu12 with SMTP id uu12sf17754556wic.2 for ; Fri, 11 Sep 2015 05:03:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:in-reply-to:references :sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe; bh=8LPJM4k/TksdysGlsarb9FYIqI3+U/HptvZfoLX1u9U=; b=GcZUnDE3h6466Lkbg/oG7AaMxwVx+pRWJcaiNndCdsgPwWqrV38XqmJqiWQxjSQkB/ jqw0iy2BukayM4IB5zI7wHbgVpcQB9ovYpb1D+G4bD1J+UxDGthogmG77IinXI6zBJTS 9fLZema+7zxVqOLI+HXE1lPcK8ImM9nupiXmAh7PWAfXKB0Zj9BoOHtiEgRMUs1rMBYh SEGODJtPuFljQeG/MdotSiFwEgPWrbsI9P6CPvwE4sdzcFbIR8rvOjiZtUqLWPBDUyY6 Pos/rO13vNIYRtbtXIQCKYc6gfAMi5w70QPycNsicaOF3bTQ/93zsE4lCfFr6kSy3GqG jgnA== X-Gm-Message-State: ALoCoQnh7icTsro1uZ/z05zV9MgFnxhTxBQn60TwQLQHEYncaMpGBXK8QSt+SVdnviBxgQ9Qodl5 X-Received: by 10.180.12.205 with SMTP id a13mr559651wic.4.1441972996079; Fri, 11 Sep 2015 05:03:16 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.43.229 with SMTP id z5ls323276lal.8.gmail; Fri, 11 Sep 2015 05:03:15 -0700 (PDT) X-Received: by 10.152.37.105 with SMTP id x9mr1588125laj.91.1441972995876; Fri, 11 Sep 2015 05:03:15 -0700 (PDT) Received: from mail-lb0-f177.google.com (mail-lb0-f177.google.com. [209.85.217.177]) by mx.google.com with ESMTPS id dy8si21764lbb.55.2015.09.11.05.03.15 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 11 Sep 2015 05:03:15 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.177 as permitted sender) client-ip=209.85.217.177; Received: by lbcao8 with SMTP id ao8so38292461lbc.3 for ; Fri, 11 Sep 2015 05:03:15 -0700 (PDT) X-Received: by 10.112.219.70 with SMTP id pm6mr40371355lbc.41.1441972995746; Fri, 11 Sep 2015 05:03:15 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.59.35 with SMTP id w3csp1545170lbq; Fri, 11 Sep 2015 05:03:14 -0700 (PDT) X-Received: by 10.60.55.9 with SMTP id n9mr36517688oep.67.1441972994293; Fri, 11 Sep 2015 05:03:14 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z9si3178obg.100.2015.09.11.05.03.13; Fri, 11 Sep 2015 05:03:14 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753124AbbIKMDL (ORCPT + 28 others); Fri, 11 Sep 2015 08:03:11 -0400 Received: from mail-pa0-f46.google.com ([209.85.220.46]:33136 "EHLO mail-pa0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752850AbbIKMDI (ORCPT ); Fri, 11 Sep 2015 08:03:08 -0400 Received: by pacex6 with SMTP id ex6so73873890pac.0 for ; Fri, 11 Sep 2015 05:03:08 -0700 (PDT) X-Received: by 10.68.231.5 with SMTP id tc5mr96150004pbc.54.1441972987869; Fri, 11 Sep 2015 05:03:07 -0700 (PDT) Received: from localhost ([122.171.186.190]) by smtp.gmail.com with ESMTPSA id bh5sm88484pbc.5.2015.09.11.05.03.06 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 11 Sep 2015 05:03:07 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , nm@ti.com, sboyd@codeaurora.org Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, rob.herring@linaro.org, lee.jones@linaro.org, Viresh Kumar , Bartlomiej Zolnierkiewicz , Dmitry Torokhov , Greg Kroah-Hartman , Len Brown , linux-kernel@vger.kernel.org (open list), Pavel Machek Subject: [PATCH 06/16] PM / OPP: Create separate structure for regulator/supplies Date: Fri, 11 Sep 2015 17:32:02 +0530 Message-Id: <2013881992cb510495503ee11360a02a7d79a037.1441972771.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.4.0 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: viresh.kumar@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.177 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Support for multiple regulators will be added later, until then move all power-supply related information in a separate structure. To make allocating/freeing memory for these supply structures easy, allocate memory for them along with opp. Signed-off-by: Viresh Kumar --- drivers/base/power/opp/core.c | 57 ++++++++++++++++++++++++++-------------- drivers/base/power/opp/debugfs.c | 9 ++++--- drivers/base/power/opp/opp.h | 29 ++++++++++++++------ 3 files changed, 63 insertions(+), 32 deletions(-) diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index 463417b6838c..14e5fa10be2d 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c @@ -127,7 +127,7 @@ unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) if (IS_ERR_OR_NULL(tmp_opp) || !tmp_opp->available) pr_err("%s: Invalid parameters\n", __func__); else - v = tmp_opp->u_volt; + v = tmp_opp->supplies[0].u_volt; return v; } @@ -491,13 +491,14 @@ struct device_list_opp *_add_list_dev(const struct device *dev, /** * _add_device_opp() - Find device OPP table or allocate a new one * @dev: device for which we do this operation + * @supply_count: Number of supplies available for each OPP. * * It tries to find an existing table first, if it couldn't find one, it * allocates a new OPP table and returns that. * * Return: valid device_opp pointer if success, else NULL. */ -static struct device_opp *_add_device_opp(struct device *dev) +static struct device_opp *_add_device_opp(struct device *dev, int supply_count) { struct device_opp *dev_opp; struct device_list_opp *list_dev; @@ -515,6 +516,7 @@ static struct device_opp *_add_device_opp(struct device *dev) if (!dev_opp) return NULL; + dev_opp->supply_count = supply_count; INIT_LIST_HEAD(&dev_opp->dev_list); list_dev = _add_list_dev(dev, dev_opp); @@ -652,24 +654,31 @@ void dev_pm_opp_remove(struct device *dev, unsigned long freq) } EXPORT_SYMBOL_GPL(dev_pm_opp_remove); -static struct dev_pm_opp *_allocate_opp(struct device *dev, - struct device_opp **dev_opp) +static struct dev_pm_opp * +_allocate_opp(struct device *dev, struct device_opp **dev_opp, int supply_count) { struct dev_pm_opp *opp; + size_t size = sizeof(*opp); + + /* Memory for the OPP and its supplies is allocated together */ + size += supply_count * sizeof(*opp->supplies); /* allocate new OPP node */ - opp = kzalloc(sizeof(*opp), GFP_KERNEL); + opp = kzalloc(size, GFP_KERNEL); if (!opp) return NULL; INIT_LIST_HEAD(&opp->node); - *dev_opp = _add_device_opp(dev); + *dev_opp = _add_device_opp(dev, supply_count); if (!*dev_opp) { kfree(opp); return NULL; } + /* Supplies points to the memory right after the opp */ + opp->supplies = (struct opp_supply *)(opp + 1); + return opp; } @@ -699,10 +708,12 @@ static int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, /* Duplicate OPPs */ dev_warn(dev, "%s: duplicate OPPs detected. Existing: freq: %lu, volt: %lu, enabled: %d. New: freq: %lu, volt: %lu, enabled: %d\n", - __func__, opp->rate, opp->u_volt, opp->available, - new_opp->rate, new_opp->u_volt, new_opp->available); + __func__, opp->rate, opp->supplies[0].u_volt, + opp->available, new_opp->rate, + new_opp->supplies[0].u_volt, new_opp->available); - return opp->available && new_opp->u_volt == opp->u_volt ? + return opp->available && + opp->supplies[0].u_volt == new_opp->supplies[0].u_volt ? 0 : -EEXIST; } @@ -754,7 +765,7 @@ static int _opp_add_v1(struct device *dev, unsigned long freq, long u_volt, /* Hold our list modification lock here */ mutex_lock(&dev_opp_list_lock); - new_opp = _allocate_opp(dev, &dev_opp); + new_opp = _allocate_opp(dev, &dev_opp, 1); if (!new_opp) { ret = -ENOMEM; goto unlock; @@ -762,7 +773,7 @@ static int _opp_add_v1(struct device *dev, unsigned long freq, long u_volt, /* populate the opp table */ new_opp->rate = freq; - new_opp->u_volt = u_volt; + new_opp->supplies[0].u_volt = u_volt; new_opp->available = true; new_opp->dynamic = dynamic; @@ -789,6 +800,7 @@ static int _opp_add_v1(struct device *dev, unsigned long freq, long u_volt, /* TODO: Support multiple regulators */ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev) { + struct opp_supply *supply = &opp->supplies[0]; u32 microvolt[3] = {0}; u32 val; int count, ret; @@ -812,12 +824,12 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev) return -EINVAL; } - opp->u_volt = microvolt[0]; - opp->u_volt_min = microvolt[1]; - opp->u_volt_max = microvolt[2]; + supply->u_volt = microvolt[0]; + supply->u_volt_min = microvolt[1]; + supply->u_volt_max = microvolt[2]; if (!of_property_read_u32(opp->np, "opp-microamp", &val)) - opp->u_amp = val; + supply->u_amp = val; return 0; } @@ -826,6 +838,7 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev) * _opp_add_static_v2() - Allocate static OPPs (As per 'v2' DT bindings) * @dev: device for which we do this operation * @np: device node + * @supply_count: Number of supplies available for each OPP * * This function adds an opp definition to the opp list and returns status. The * opp can be controlled using dev_pm_opp_enable/disable functions and may be @@ -845,10 +858,12 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev) * -ENOMEM Memory allocation failure * -EINVAL Failed parsing the OPP node */ -static int _opp_add_static_v2(struct device *dev, struct device_node *np) +static int _opp_add_static_v2(struct device *dev, struct device_node *np, + int supply_count) { struct device_opp *dev_opp; struct dev_pm_opp *new_opp; + struct opp_supply *supply; u64 rate; u32 val; int ret; @@ -856,7 +871,7 @@ static int _opp_add_static_v2(struct device *dev, struct device_node *np) /* Hold our list modification lock here */ mutex_lock(&dev_opp_list_lock); - new_opp = _allocate_opp(dev, &dev_opp); + new_opp = _allocate_opp(dev, &dev_opp, supply_count); if (!new_opp) { ret = -ENOMEM; goto unlock; @@ -906,9 +921,10 @@ static int _opp_add_static_v2(struct device *dev, struct device_node *np) mutex_unlock(&dev_opp_list_lock); + supply = &new_opp->supplies[0]; pr_debug("%s: turbo:%d rate:%lu uv:%lu uvmin:%lu uvmax:%lu latency:%lu\n", - __func__, new_opp->turbo, new_opp->rate, new_opp->u_volt, - new_opp->u_volt_min, new_opp->u_volt_max, + __func__, new_opp->turbo, new_opp->rate, supply->u_volt, + supply->u_volt_min, supply->u_volt_max, new_opp->clock_latency_ns); /* @@ -1195,7 +1211,8 @@ static int _of_add_opp_table_v2(struct device *dev, struct device_node *opp_np) for_each_available_child_of_node(opp_np, np) { count++; - ret = _opp_add_static_v2(dev, np); + /* Todo: Add support for multiple supplies */ + ret = _opp_add_static_v2(dev, np, 1); if (ret) { dev_err(dev, "%s: Failed to add OPP, %d\n", __func__, ret); diff --git a/drivers/base/power/opp/debugfs.c b/drivers/base/power/opp/debugfs.c index 865cbfa24640..e6ba29c04513 100644 --- a/drivers/base/power/opp/debugfs.c +++ b/drivers/base/power/opp/debugfs.c @@ -34,6 +34,7 @@ void opp_debug_remove_one(struct dev_pm_opp *opp) int opp_debug_create_one(struct dev_pm_opp *opp, struct device_opp *dev_opp) { struct dentry *pdentry = dev_opp->dentry; + struct opp_supply *supply = &opp->supplies[0]; struct dentry *d; char name[15]; @@ -59,18 +60,18 @@ int opp_debug_create_one(struct dev_pm_opp *opp, struct device_opp *dev_opp) return -ENOMEM; if (!debugfs_create_u32("u_volt_target", S_IRUGO, d, - (u32 *)&opp->u_volt)) + (u32 *)&supply->u_volt)) return -ENOMEM; if (!debugfs_create_u32("u_volt_min", S_IRUGO, d, - (u32 *)&opp->u_volt_min)) + (u32 *)&supply->u_volt_min)) return -ENOMEM; if (!debugfs_create_u32("u_volt_max", S_IRUGO, d, - (u32 *)&opp->u_volt_max)) + (u32 *)&supply->u_volt_max)) return -ENOMEM; - if (!debugfs_create_u32("u_amp", S_IRUGO, d, (u32 *)&opp->u_amp)) + if (!debugfs_create_u32("u_amp", S_IRUGO, d, (u32 *)&supply->u_amp)) return -ENOMEM; if (!debugfs_create_u32("clock_latency_ns", S_IRUGO, d, diff --git a/drivers/base/power/opp/opp.h b/drivers/base/power/opp/opp.h index 0e4c27fb0c4a..a7a6917d6fbd 100644 --- a/drivers/base/power/opp/opp.h +++ b/drivers/base/power/opp/opp.h @@ -39,6 +39,22 @@ */ /** + * struct opp_supply - Per power-supply structure + * @u_volt: Target voltage in microvolts corresponding to this OPP + * @u_volt_min: Minimum voltage in microvolts corresponding to this OPP + * @u_volt_max: Maximum voltage in microvolts corresponding to this OPP + * @u_amp: Maximum current drawn by the device in microamperes + * + * This structure stores the OPP power-supply information for a given device. + */ +struct opp_supply { + unsigned long u_volt; + unsigned long u_volt_min; + unsigned long u_volt_max; + unsigned long u_amp; +}; + +/** * struct dev_pm_opp - Generic OPP description structure * @node: opp list node. The nodes are maintained throughout the lifetime * of boot. It is expected only an optimal set of OPPs are @@ -52,10 +68,7 @@ * @available: true/false - marks if this OPP as available or not * @turbo: true if turbo (boost) OPP * @rate: Frequency in hertz - * @u_volt: Target voltage in microvolts corresponding to this OPP - * @u_volt_min: Minimum voltage in microvolts corresponding to this OPP - * @u_volt_max: Maximum voltage in microvolts corresponding to this OPP - * @u_amp: Maximum current drawn by the device in microamperes + * @supplies: Array of power-supplies for the device. * @clock_latency_ns: Latency (in nanoseconds) of switching to this OPP's * frequency from any other OPP's frequency. * @dev_opp: points back to the device_opp struct this opp belongs to @@ -73,10 +86,8 @@ struct dev_pm_opp { bool turbo; unsigned long rate; - unsigned long u_volt; - unsigned long u_volt_min; - unsigned long u_volt_max; - unsigned long u_amp; + struct opp_supply *supplies; + unsigned long clock_latency_ns; struct device_opp *dev_opp; @@ -123,6 +134,7 @@ struct device_list_opp { * @dev_list: list of devices that share these OPPs * @opp_list: list of opps * @np: struct device_node pointer for opp's DT node. + * @supply_count: Number of power-supplies * @shared_opp: OPP is shared between multiple devices. * @dentry: debugfs dentry pointer of the real device directory (not links). * @dentry_name: Name of the real dentry. @@ -145,6 +157,7 @@ struct device_opp { struct device_node *np; unsigned long clock_latency_ns_max; + unsigned int supply_count; bool shared_opp; struct dev_pm_opp *suspend_opp;