Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp3205550imm; Tue, 29 May 2018 03:07:15 -0700 (PDT) X-Google-Smtp-Source: AB8JxZqlDtxRr8Z7OsIccoykdZgmf2zcvrq4+4wO9UCiPYoOM6H9WlHeHs/s6dv1+E6XkXCJS9t/ X-Received: by 2002:a62:4353:: with SMTP id q80-v6mr16804679pfa.228.1527588435179; Tue, 29 May 2018 03:07:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527588435; cv=none; d=google.com; s=arc-20160816; b=dsQCBGjz+Wn3BqZAopfYmVLzZAc/Xq5I+Mmwy3IOkHT4WiAaPhz3HxA8QUhlFLUUE7 X8uo5lL8NbqQ2VFdx7Ts1SFIvfBvs6ZTBOvNWGlTKhrcRdeFruASIMlc651MZVi/VM9x HWtSItrQRa/FUrOAUhnDDCjLyZ0gx7NuTLqDo6QXaJYe6n/NRD/htUTe8rJi+T2UaVc1 qYpEZY97bCiK50YKAlDv2HRZfzsH4nVoDqLaYT2fQNLH1MOzp77WSjAlaBILulq6WOPO 0XtoAAu80ESL4eQbqFuQkMk4x1bfOFF94RgFJygUcLqEJM/fzcNnYuVoK0HnbTLgc1bH PTyg== 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=26+aFTQcf8NYAmN2QvZuXP7NjVudzK5mSbJ9dDrOxiE=; b=0fMS+dOE7p8Ar5FPdedH8ks39t8IEIo6hLnPt5bglKpuEqfg1nuFoULL/kTqivqP8m AjYGPxeuUZkORXTr1Vdc++ZuteusIklYXThcl9wzKBB1aVv3orDr93u0dYn3Oq9Bu1h0 OKd2o1u3LhUyVVCFJkmxH3UNT0yoA07sCh2QB36/E8xb2NGEUFoKCAwA/PfrKY254RvY LGu+3CpYXoZVqeleh0lvzDcCk7FCwMhOB27yy8O5UcnnyZmmvvKZ1ZeFWTYH8Cn6o7Ls r2+dqSzfuO6eK9qoT5rw7dVv7R+wINMON28sGtHtxQF5W6AeaVy4Pld234bKx0JGz5qw GDdA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ecNCmJsd; 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 34-v6si31610304plc.346.2018.05.29.03.07.01; Tue, 29 May 2018 03:07:15 -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=ecNCmJsd; 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 S932968AbeE2KF1 (ORCPT + 99 others); Tue, 29 May 2018 06:05:27 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:51669 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932975AbeE2KEo (ORCPT ); Tue, 29 May 2018 06:04:44 -0400 Received: by mail-wm0-f66.google.com with SMTP id r15-v6so11247219wmc.1 for ; Tue, 29 May 2018 03:04:43 -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=26+aFTQcf8NYAmN2QvZuXP7NjVudzK5mSbJ9dDrOxiE=; b=ecNCmJsd9VWpG9MyI81I76oV8PL2zVXy1+IbyAK/4m8OCwk65hXqimHuJsJCkwrs2S sqUpv45VVoDFv4ZGBXkOy9Tn38tMC/XRQAkR6OAUrDoe79YKVhiQMYrSbMdSpjAKOAtw en1I3yRfN7ewd4NHbeWuXayE7NZdmPC9kqQTg= 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=26+aFTQcf8NYAmN2QvZuXP7NjVudzK5mSbJ9dDrOxiE=; b=TDNMv4awwD4OH3Ik7kKNdob+7bEPj90fhBG8aWaFvAz4OTGiVFPKoD8J3CU1DdvQvS 9n48PXdO5Ir09hOoFVtgjz/yFJLAgsxbePosOLsDYILf4MKLS2+NsruK30l4MYhoqO8I WUA8dEPliq9ZjpZS6LOuvbN4Wos4bREuoQJA04tbxzD600TZdcoIR8CdWvdgCv40wlKY KxVkHlz48ZaFH1M4nP0C9Yy1I8uFAI+ziafWd0QGJTR1c7LvwGLh+VaDQDziHF5tg54D l6zFKQ5KJ3dHO1Mdc8motj1NeON0I1YBrClcMtOpjlL3OgyZOWI/njbEcJjipnzHCvVy yeWQ== X-Gm-Message-State: ALKqPwdHFko8DSHycb+5xmobNWyhKq58WFh0QzCQSVbHuCZU0vQVmdA6 QJXGCoNrtszYc7PY93ChNM0mvQ== X-Received: by 2002:a2e:9d95:: with SMTP id c21-v6mr10799697ljj.89.1527588282866; Tue, 29 May 2018 03:04:42 -0700 (PDT) Received: from localhost.localdomain (h-158-174-22-210.NA.cust.bahnhof.se. [158.174.22.210]) by smtp.gmail.com with ESMTPSA id e21-v6sm2561718lfg.74.2018.05.29.03.04.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 May 2018 03:04:42 -0700 (PDT) From: Ulf Hansson To: "Rafael J . Wysocki" , linux-pm@vger.kernel.org Cc: Ulf Hansson , Greg Kroah-Hartman , Jon Hunter , Geert Uytterhoeven , Todor Tomov , Rajendra Nayak , Viresh Kumar , Vincent Guittot , Kevin Hilman , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-tegra@vger.kernel.org Subject: [PATCH v2 9/9] PM / Domains: Add dev_pm_domain_attach_by_id() to manage multi PM domains Date: Tue, 29 May 2018 12:04:21 +0200 Message-Id: <20180529100421.31022-10-ulf.hansson@linaro.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180529100421.31022-1-ulf.hansson@linaro.org> References: <20180529100421.31022-1-ulf.hansson@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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. 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. + * @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) {} -- 2.17.0