Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp4371811imm; Wed, 30 May 2018 04:32:35 -0700 (PDT) X-Google-Smtp-Source: ADUXVKIFy7GPlw3zWAYY+Cbn5eHFysBE8Pi+gFPDh4zKmfPcg/VM181oEy1sUwtwWBXPHS8fqzTq X-Received: by 2002:a17:902:ba93:: with SMTP id k19-v6mr2403072pls.379.1527679955647; Wed, 30 May 2018 04:32:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527679955; cv=none; d=google.com; s=arc-20160816; b=aOHWlJ8nGKIQYzQhM1SQKx7oUWa9wP9ArhBgKm68eH/wuFfCf73Q9DiuolIJc16wKR 6G8fEbogiXQlz7dWGfhRcmFErs0PJa3aEo+XGxFaSrSPy1pzpuDA24OhcQre7Y57CG0S PQkqp9GEFzL8bOCeleUvPpLj0svLYOyk6JCdzOtcGfzgrAa7WjvIX2U8QEh+7LWVNHjt TqPbWLKZXb9HnlySzYM0fVl7laVEacm6Clhg3qhN0xbwHrt4aluTw6JwTpzSvuU/0Y/F Lr2XM+puJwXdn5CFme+pO9NYXznCTCqholHrOZ+/wklexyTiDUw4f/l9ta7G4JUxwlm5 QxaQ== 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 :references:in-reply-to:mime-version:dkim-signature :arc-authentication-results; bh=fFSI0D6AqVsj3sxcoKrzA4JDh+1jiM9f355xVaOCc2M=; b=tJ71sIT1GnBMEtC8CKSFLR8W0NNlTUtCP+Kwxk4KJ8vR9iqMPBCPvkJ3NvzufLggHi mmsDM3DGyEF3smgnyjqJ3anwovPfjZXB3lbjxpwlI98Y9Z2M2Wp60m7khqjTU6Wn2X5/ FVhf/WEkoFdKbF2pxTLdVkpT0vBCbhfvrNdTempOsr674EDCDjLww42+xbUQ3e0+BXlh aBbr7ysBXuI+FNAgMaB4E63pZTrM32r74ut1tRw/DLzaGu1S5sDTQaLuvJZaAt2V7+hE bkWNBftMgrZM5aImCoDfxO5APYfPLLph2wDs98wCp5GwlK0rpS4+nFHq962mLFgp0SD3 wMWw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=HZTSDqJE; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 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. [209.132.180.67]) by mx.google.com with ESMTP id c17-v6si12471018pfk.93.2018.05.30.04.32.21; Wed, 30 May 2018 04:32:35 -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; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=HZTSDqJE; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 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 S1752880AbeE3Lbd (ORCPT + 99 others); Wed, 30 May 2018 07:31:33 -0400 Received: from mail-io0-f193.google.com ([209.85.223.193]:40047 "EHLO mail-io0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751655AbeE3Lb3 (ORCPT ); Wed, 30 May 2018 07:31:29 -0400 Received: by mail-io0-f193.google.com with SMTP id g14-v6so21202085ioc.7 for ; Wed, 30 May 2018 04:31:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=fFSI0D6AqVsj3sxcoKrzA4JDh+1jiM9f355xVaOCc2M=; b=HZTSDqJEL6ILuC31xD9LjN3luPERHXVg5wfDS+tf0P8opz1xvio4APfvlZ5pgUjbgZ +hG1oLp7n8itbKM1a7WTFCfPMRftNYXT0eG63vqUzs7FRABJbISk0WPGWHiqLUo7imGY oirLGV7cjUYp4VEBLxjcoyl+Ptvpo+3Mg7Spg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=fFSI0D6AqVsj3sxcoKrzA4JDh+1jiM9f355xVaOCc2M=; b=AKNyUkcXNOFOdq66uGwhLU94+dUKKyHC+rVDkyZZlaNuErCfZINHJ86eko0WDAj9fS cfP6r5+d4Uj21X04BnOHZZqFX9JLYRSnX51y1U2EeRv7m5upss+jo3dYYJSgpCnTY1J4 sLw2jAFS+2rNObGt8zyORI692CCORMeGOEPeAt7TW1Lqa1NhgwtBXAxmUaqQRNFiYKuc VTGJtNxIkn/v7AE9wQOUEluHddRyPvlVX1WnYL5In6HAiTfoQk6OamDXoEf4GWoD0n5J +exJHqyZKCuPkjBTb8DzHRWSs/yg4EDhOKlRV6ZdBDxX+2714vyeC/vRfUjau29P4zWB cMpQ== X-Gm-Message-State: ALKqPwdxnHx8fz8Wc4w6u519l8Q5/+nPTX39SSlfZjQWo/9Ei0rFVgsU N+aAm2h0VsaU/mv0V9GZijgigPJkPDF3QSTNH/o1Vw== X-Received: by 2002:a6b:c6c9:: with SMTP id w192-v6mr1773892iof.131.1527679888393; Wed, 30 May 2018 04:31:28 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a02:c054:0:0:0:0:0 with HTTP; Wed, 30 May 2018 04:31:27 -0700 (PDT) In-Reply-To: References: <20180529100421.31022-1-ulf.hansson@linaro.org> <20180529100421.31022-10-ulf.hansson@linaro.org> From: Ulf Hansson Date: Wed, 30 May 2018 13:31:27 +0200 Message-ID: Subject: Re: [PATCH v2 9/9] PM / Domains: Add dev_pm_domain_attach_by_id() to manage multi PM domains To: Jon Hunter Cc: "Rafael J . Wysocki" , Linux PM , Greg Kroah-Hartman , Geert Uytterhoeven , Todor Tomov , Rajendra Nayak , Viresh Kumar , Vincent Guittot , Kevin Hilman , Linux Kernel Mailing List , Linux ARM , linux-tegra@vger.kernel.org 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 30 May 2018 at 11:19, Jon Hunter wrote: > Hi Ulf, > > On 29/05/18 11:04, Ulf Hansson wrote: >> The existing dev_pm_domain_attach() function, allows a single PM domain to >> be attached per device. To be able to support devices that are partitioned >> across multiple PM domains, let's introduce a new interface, >> dev_pm_domain_attach_by_id(). >> >> The dev_pm_domain_attach_by_id() returns a new allocated struct device with >> the corresponding attached PM domain. This enables for example a driver to >> operate on the new device from a power management point of view. The driver >> may then also benefit from using the received device, to set up so called >> device-links towards its original device. Depending on the situation, these >> links may then be dynamically changed. > > I have given this series a go with Tegra updating the XHCI driver to make > use of these new APIs. Good news it does appear to work fine for Tegra, > however, initially when looking at the device_link_add() API ... > > /** > * device_link_add - Create a link between two devices. > * @consumer: Consumer end of the link. > * @supplier: Supplier end of the link. > * @flags: Link flags. > > ... I had assumed that the 'consumer' device would be the actual XHCI > device (in the case of Tegra) and the 'supplier' device would be the new > genpd device. However, this did not work and I got the following WARN on > boot ... > > [ 2.050929] ---[ end trace eff0b5265e530c92 ]--- > [ 2.055567] WARNING: CPU: 2 PID: 1 at drivers/base/core.c:446 device_links_driver_bound+0xc0/0xd0 > [ 2.064422] Modules linked in: > [ 2.067471] CPU: 2 PID: 1 Comm: swapper/0 Tainted: G W 4.17.0-rc7-next-20180529-00011-g4faf0dc0ebf3-dirty #32 > [ 2.078667] Hardware name: Google Pixel C (DT) > [ 2.083101] pstate: 80000005 (Nzcv daif -PAN -UAO) > [ 2.087881] pc : device_links_driver_bound+0xc0/0xd0 > [ 2.092832] lr : device_links_driver_bound+0x20/0xd0 > > Switching the Tegra XHCI device to be the 'supplier' and genpd device to > be the 'consumer' does work, but is this correct? Seems to be opposite to It shall be the opposite. The Tegra XHCI device shall be the consumer. > what I expected. Maybe I am missing something? The problem you get is because the device returned from dev_pm_domain_attach_by_id(), let's call it genpd_dev, doesn't have the a driver. You need to use a couple of device links flag, something like this: link = device_link_add(dev, genpd_dev, DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE); Moreover, you also need these commits, depending if you are running on something else than Rafael's tree. a0504aecba76 PM / runtime: Drop usage count for suppliers at device link removal 1e8378619841 PM / runtime: Fixup reference counting of device link suppliers at probe > >> The new interface is typically called by drivers during their probe phase, >> in case they manages devices which uses multiple PM domains. If that is the >> case, the driver also becomes responsible of managing the detaching of the >> PM domains, which typically should be done at the remove phase. Detaching >> is done by calling the existing dev_pm_domain_detach() function and for >> each of the received devices from dev_pm_domain_attach_by_id(). >> >> Note, currently its only genpd that supports multiple PM domains per >> device, but dev_pm_domain_attach_by_id() can easily by extended to cover >> other PM domain types, if/when needed. >> >> Signed-off-by: Ulf Hansson >> --- >> >> Changes in v2: >> - Fixed comments from Jon. Clarified function descriptions/changelog and >> return ERR_PTR(-EEXIST) in case a PM domain is already assigned. >> - Fix build error when CONFIG_PM is unset. >> >> --- >> drivers/base/power/common.c | 43 ++++++++++++++++++++++++++++++++++--- >> include/linux/pm_domain.h | 7 ++++++ >> 2 files changed, 47 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c >> index 7ae62b6355b8..5e5ea0c239de 100644 >> --- a/drivers/base/power/common.c >> +++ b/drivers/base/power/common.c >> @@ -116,14 +116,51 @@ int dev_pm_domain_attach(struct device *dev, bool power_on) >> } >> EXPORT_SYMBOL_GPL(dev_pm_domain_attach); >> >> +/** >> + * dev_pm_domain_attach_by_id - Attach a device to one of its PM domains. >> + * @dev: Device to attach. > > Nit ... I still don't think this is the device we are attaching to, but the > device the PM domains are associated with. IOW we are using this device to > lookup the PM domains. Right. I forgot to update that part of the description. What about: dev_pm_domain_attach_by_id - Associate a device with one of its PM domains. @dev: The device used to lookup the PM domain. > >> + * @index: The index of the PM domain. >> + * >> + * As @dev may only be attached to a single PM domain, the backend PM domain >> + * provider creates a virtual device to attach instead. If attachment succeeds, >> + * the ->detach() callback in the struct dev_pm_domain are assigned by the >> + * corresponding backend attach function, as to deal with detaching of the >> + * created virtual device. >> + * >> + * This function should typically be invoked by a driver during the probe phase, >> + * in case its device requires power management through multiple PM domains. The >> + * driver may benefit from using the received device, to configure device-links >> + * towards its original device. Depending on the use-case and if needed, the >> + * links may be dynamically changed by the driver, which allows it to control >> + * the power to the PM domains independently from each other. >> + * >> + * Callers must ensure proper synchronization of this function with power >> + * management callbacks. >> + * >> + * Returns the virtual created device when successfully attached to its PM >> + * domain, NULL in case @dev don't need a PM domain, else an ERR_PTR(). >> + * Note that, to detach the returned virtual device, the driver shall call >> + * dev_pm_domain_detach() on it, typically during the remove phase. >> + */ >> +struct device *dev_pm_domain_attach_by_id(struct device *dev, >> + unsigned int index) >> +{ >> + if (dev->pm_domain) >> + return ERR_PTR(-EEXIST); >> + >> + return genpd_dev_pm_attach_by_id(dev, index); >> +} >> +EXPORT_SYMBOL_GPL(dev_pm_domain_attach_by_id); >> + >> /** >> * dev_pm_domain_detach - Detach a device from its PM domain. >> * @dev: Device to detach. >> * @power_off: Used to indicate whether we should power off the device. >> * >> - * This functions will reverse the actions from dev_pm_domain_attach() and thus >> - * try to detach the @dev from its PM domain. Typically it should be invoked >> - * from subsystem level code during the remove phase. >> + * This functions will reverse the actions from dev_pm_domain_attach() and >> + * dev_pm_domain_attach_by_id(), thus it detaches @dev from its PM domain. >> + * Typically it should be invoked during the remove phase, either from >> + * subsystem level code or from drivers. >> * >> * Callers must ensure proper synchronization of this function with power >> * management callbacks. >> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h >> index 82458e8e2e01..9206a4fef9ac 100644 >> --- a/include/linux/pm_domain.h >> +++ b/include/linux/pm_domain.h >> @@ -299,6 +299,8 @@ 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 device *dev_pm_domain_attach_by_id(struct device *dev, >> + unsigned int index); >> void dev_pm_domain_detach(struct device *dev, bool power_off); >> void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd); >> #else >> @@ -306,6 +308,11 @@ static inline int dev_pm_domain_attach(struct device *dev, bool power_on) >> { >> return 0; >> } >> +static inline struct device *dev_pm_domain_attach_by_id(struct device *dev, >> + unsigned int index) >> +{ >> + return NULL; >> +} >> static inline void dev_pm_domain_detach(struct device *dev, bool power_off) {} >> static inline void dev_pm_domain_set(struct device *dev, >> struct dev_pm_domain *pd) {} >> > > My only other comments on this series are ... > > 1. I think it would be nice to have an dev_pm_domain_attach_by_name() and > that the DT binding has a 'power-domain-names' property. I think it makes sense, but my plan was to do that as second step on top. Are you okay with that as well? > 2. I am wondering if there could be value in having a > dev_pm_domain_attach_link_all() helper which would attach and link all > PM domains at once. Perhaps it can be useful, yes! However, maybe we can postpone that to after this series. I want to keep the series as simple as possible, then we can build upon it. Kind regards Uffe