Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp178661ybz; Tue, 21 Apr 2020 07:04:38 -0700 (PDT) X-Google-Smtp-Source: APiQypIsj0dk8swxy6S3U0RmIjMaHgQEcPKL2TK0zF+LsP+x0cvrYXoczVGf3iPyR791LggrhHsc X-Received: by 2002:a50:a68a:: with SMTP id e10mr18749121edc.113.1587477877414; Tue, 21 Apr 2020 07:04:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1587477877; cv=none; d=google.com; s=arc-20160816; b=X6jRJ3IYRFnZ6ICkJsukC0SdxX5xQARBkBPBK+IHfpX3779iLKP5KCQdpPabalcMpY h7ctXf5TiPw1owCqIzeoExf3grssKKaXl/gmpxaHUm7CNO5V165+jJL1dGrF3Jp3SoD0 ZaMnhckyf962a4zoWUSyjmQYC7PpGLb+/If2RZp+bgkHgIaEfWb/PpgmCPFii2TvOqvs c1bISSxm9EMOIAo7cwJkZtO1bBMXK2H+xSC857xEu8EvbTFR81hKX+jL3ejYad5++NrL 0MPAOiUbGSHk//KnkaEqcIY4zsvOZd7iS/1sFAGVGhPBJ1HyQ65iZit8otJdoKo7Uruq kohA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=3ufO0oc55SP4ppmrO49IkerUiLNfh37ywo2Lik40Adk=; b=NGah6DbZCt2jhNR4pxN7TsI5kzCYqxL2d2PlriIDmLI1L5JTR0UXJWp9s2PWsapxnN +0eup8kfSWDIbiL5XR8HgeGsAEeSjTfsoD/CSTq4KFal1zK9iAaKT9ISGIJ3oCNWEpx4 Nc35kR8mt7D/j55vesr4mcgEketAEfAVtM5GQ5OhJ9/W62B90CAHUiLF7FU6VjwiwBJy KAj53gX3Gl1qUc3acIiS0NoEorIa38hqYsQugvx9FbgDWsyE7thcfOa0iBzRVLqmUU6Q JFOVaDlW8LrQG8E51NuZaaw74idsHTikb+3JCjhNlnMI0c3iLMG9cSE3GZ+A8qsnDaPV vS5g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=kCcz+Vvy; 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=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id cx18si1662500edb.73.2020.04.21.07.04.08; Tue, 21 Apr 2020 07:04:37 -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; dkim=pass header.i=@linaro.org header.s=google header.b=kCcz+Vvy; 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=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728874AbgDUOAr (ORCPT + 99 others); Tue, 21 Apr 2020 10:00:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44178 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1728772AbgDUOAq (ORCPT ); Tue, 21 Apr 2020 10:00:46 -0400 Received: from mail-vs1-xe42.google.com (mail-vs1-xe42.google.com [IPv6:2607:f8b0:4864:20::e42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A42A2C061A41 for ; Tue, 21 Apr 2020 07:00:46 -0700 (PDT) Received: by mail-vs1-xe42.google.com with SMTP id o3so8461182vsd.4 for ; Tue, 21 Apr 2020 07:00:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=3ufO0oc55SP4ppmrO49IkerUiLNfh37ywo2Lik40Adk=; b=kCcz+VvyC/0IdI5gEKgvRf59mDcFEWTu/D1Ov9OACQKF1YEkdo/czGTGb09gPZe9nz CfsRp2cuik7vLYUVXc/zRZIz/M1iAydX8PM+/hsH0pTD5HFXabDTfMSk9eFgJkf3ycO7 HwuB5lGEuv0muapa9Iicl4fVKvJVOBKTUwZNnrjM1HewRbx4nfgTaatf1/BoG80s61zW zUZqNfnUAgdZ4NNjRfNyQ7RzgUiJnjKAU5TERSmQGAsn+H+9jQpQp0sn66wVsw8QKIBy 9i+kJngnYZVql2Yc/4MY3Wcxtw20Jw09IHP0gKmV2Uy8DOQ/gPTUZZAHunscQ2NmHS2m LbgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=3ufO0oc55SP4ppmrO49IkerUiLNfh37ywo2Lik40Adk=; b=LYG/m3e3RuXlzPZfdTz88zBWo7N92p8XFFWF9dhQqySqhUY5J4AjpuQZaED8dVrrXz PB8ztVlr5i9ccnocps3ZC6CRRN5mdzDaTeDiL/+T6kfbgbgf93t7Eu9aJGw5i3js+GXY WJTnalOqgoSaMW4XoCssh9QAuXwBGg/WFCllIpWuM5k26l5M61eo3NF95CqtKimnHYTZ rGBxiezCAKIrfgocTL8F0JLznU3cEDBzMGDoyGGUAnwqSgLNIYVVX6/gWt1fafEu2Pfa lHRPmzu4CSeO+5quZjp296ZbWtBFsWJfCdVBVrct1PogqegGBHJ6QMpwThkOzS9QFoGw lDMQ== X-Gm-Message-State: AGi0PubaK3igfHxWaDN5pvx4+W6xp5HgLTAZ3i+qAoyRwsKVcR0PK5Wi RlKaEQGkeJ3bSNxe/nnaHGQ8VHwdppePhcRwnhkM0Q== X-Received: by 2002:a67:8b09:: with SMTP id n9mr15252066vsd.191.1587477645532; Tue, 21 Apr 2020 07:00:45 -0700 (PDT) MIME-Version: 1.0 References: <20200304121943.28989-1-daniel.baluta@oss.nxp.com> <20200304121943.28989-2-daniel.baluta@oss.nxp.com> In-Reply-To: <20200304121943.28989-2-daniel.baluta@oss.nxp.com> From: Ulf Hansson Date: Tue, 21 Apr 2020 16:00:09 +0200 Message-ID: Subject: Re: [RFC PATCH v2 1/2] PM / domains: Introduce multi PM domains helpers To: Daniel Baluta Cc: "Rafael J. Wysocki" , Len Brown , ranjani.sridharan@linux.intel.com, Aisheng Dong , Fabio Estevam , alsa-devel@alsa-project.org, Linux PM , Greg Kroah-Hartman , Sascha Hauer , Kevin Hilman , Linux Kernel Mailing List , Daniel Baluta , Pierre-Louis Bossart , paul.olaru@nxp.com, dl-linux-imx , Sascha Hauer , Shawn Guo , shengjiu.wang@nxp.com, Linux ARM Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, 4 Mar 2020 at 13:20, Daniel Baluta wrote: > > From: Daniel Baluta > > This patch introduces helpers support for multi PM domains. > > API consists of: > > 1) dev_multi_pm_attach - powers up all PM domains associated with a given > device. Because we can attach one PM domain per device, we create > virtual devices (children of initial device) and associate PM domains > one per virtual device. > > 2) dev_multi_pm_detach - detaches all virtual devices from PM domains > attached with. > > Signed-off-by: Daniel Baluta First, apologize for the delay. In general I don't mind adding helpers that can be used to decrease open coding. However, in this case, I wonder how useful the helpers would really be. More precisely, according to the information I have, a device may not always need all of its PM domains to be turned on together, but perhaps only a subset of them. Depending on the current use case that is running. Of course, some cases follow your expectations, but as stated, some others do not. Do you have an idea how many users that would be able to switch to these new APIs as of today? Kind regards Uffe > --- > drivers/base/power/common.c | 93 +++++++++++++++++++++++++++++++++++++ > include/linux/pm_domain.h | 19 ++++++++ > 2 files changed, 112 insertions(+) > > diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c > index bbddb267c2e6..6d1f142833b1 100644 > --- a/drivers/base/power/common.c > +++ b/drivers/base/power/common.c > @@ -228,3 +228,96 @@ void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd) > device_pm_check_callbacks(dev); > } > EXPORT_SYMBOL_GPL(dev_pm_domain_set); > + > +/** > + * dev_multi_pm_attach - power up device associated power domains > + * @dev: The device used to lookup the PM domains > + * > + * Parse device's OF node to find all PM domains specifiers. For each power > + * domain found, create a virtual device and associate it with the > + * current power domain. > + * > + * This function should typically be invoked by a driver during the > + * probe phase, in the case its device requires power management through > + * multiple PM domains. > + * > + * Returns a pointer to @dev_multi_pm_domain_data if successfully attached PM > + * domains, NULL when the device doesn't need a PM domain or when single > + * power-domains exists for it, else an ERR_PTR() in case of > + * failures. > + */ > +struct dev_multi_pm_domain_data *dev_multi_pm_attach(struct device *dev) > +{ > + struct dev_multi_pm_domain_data *mpd, *retp; > + int num_domains; > + int i; > + > + num_domains = of_count_phandle_with_args(dev->of_node, "power-domains", > + "#power-domain-cells"); > + if (num_domains < 2) > + return NULL; > + > + mpd = devm_kzalloc(dev, GFP_KERNEL, sizeof(*mpd)); > + if (!mpd) > + return ERR_PTR(-ENOMEM); > + > + mpd->dev = dev; > + mpd->num_domains = num_domains; > + > + mpd->virt_devs = devm_kmalloc_array(dev, mpd->num_domains, > + sizeof(*mpd->virt_devs), > + GFP_KERNEL); > + if (!mpd->virt_devs) > + return ERR_PTR(-ENOMEM); > + > + mpd->links = devm_kmalloc_array(dev, mpd->num_domains, > + sizeof(*mpd->links), GFP_KERNEL); > + if (!mpd->links) > + return ERR_PTR(-ENOMEM); > + > + for (i = 0; i < mpd->num_domains; i++) { > + mpd->virt_devs[i] = dev_pm_domain_attach_by_id(dev, i); > + if (IS_ERR(mpd->virt_devs[i])) { > + retp = (struct dev_multi_pm_domain_data *) > + mpd->virt_devs[i]; > + goto exit_unroll_pm; > + } > + mpd->links[i] = device_link_add(dev, mpd->virt_devs[i], > + DL_FLAG_STATELESS | > + DL_FLAG_PM_RUNTIME | > + DL_FLAG_RPM_ACTIVE); > + if (!mpd->links[i]) { > + retp = ERR_PTR(-ENOMEM); > + dev_pm_domain_detach(mpd->virt_devs[i], false); > + goto exit_unroll_pm; > + } > + } > + return mpd; > + > +exit_unroll_pm: > + while (--i >= 0) { > + device_link_del(mpd->links[i]); > + dev_pm_domain_detach(mpd->virt_devs[i], false); > + } > + > + return retp; > +} > +EXPORT_SYMBOL(dev_multi_pm_attach); > + > +/** > + * dev_multi_pm_detach - Detach a device from its PM domains. > + * Each multi power domain is attached to a virtual children device > + * > + * @mpd: multi power domains data, contains the association between > + * virtul device and PM domain > + */ > +void dev_multi_pm_detach(struct dev_multi_pm_domain_data *mpd) > +{ > + int i; > + > + for (i = 0; i < mpd->num_domains; i++) { > + device_link_del(mpd->links[i]); > + dev_pm_domain_detach(mpd->virt_devs[i], false); > + } > +} > +EXPORT_SYMBOL(dev_multi_pm_detach); > diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h > index 9ec78ee53652..5bcb35150af2 100644 > --- a/include/linux/pm_domain.h > +++ b/include/linux/pm_domain.h > @@ -183,6 +183,13 @@ struct generic_pm_domain_data { > void *data; > }; > > +struct dev_multi_pm_domain_data { > + struct device *dev; /* parent device */ > + struct device **virt_devs; /* virtual children links */ > + struct device_link **links; /* links parent <-> virtual children */ > + int num_domains; > +}; > + > #ifdef CONFIG_PM_GENERIC_DOMAINS > static inline struct generic_pm_domain_data *to_gpd_data(struct pm_domain_data *pdd) > { > @@ -369,18 +376,27 @@ struct generic_pm_domain *of_genpd_remove_last(struct device_node *np) > > #ifdef CONFIG_PM > int dev_pm_domain_attach(struct device *dev, bool power_on); > +struct dev_multi_pm_domain_data *dev_multi_pm_attach(struct device *dev); > struct device *dev_pm_domain_attach_by_id(struct device *dev, > unsigned int index); > struct device *dev_pm_domain_attach_by_name(struct device *dev, > const char *name); > void dev_pm_domain_detach(struct device *dev, bool power_off); > int dev_pm_domain_start(struct device *dev); > +void dev_multi_pm_detach(struct dev_multi_pm_domain_data *mpd); > void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd); > + > #else > static inline int dev_pm_domain_attach(struct device *dev, bool power_on) > { > return 0; > } > + > +struct dev_multi_pm_domain_data *dev_multi_pm_attach(struct device *dev) > +{ > + return NULL; > +} > + > static inline struct device *dev_pm_domain_attach_by_id(struct device *dev, > unsigned int index) > { > @@ -396,6 +412,9 @@ static inline int dev_pm_domain_start(struct device *dev) > { > return 0; > } > + > +void dev_multi_pm_detach(struct dev_multi_pm_domain_data *mpd) {} > + > static inline void dev_pm_domain_set(struct device *dev, > struct dev_pm_domain *pd) {} > #endif > -- > 2.17.1 >