linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v2 0/2] Introduce multi PM domains helpers
@ 2020-03-04 12:19 Daniel Baluta
  2020-03-04 12:19 ` [RFC PATCH v2 1/2] PM / domains: " Daniel Baluta
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Daniel Baluta @ 2020-03-04 12:19 UTC (permalink / raw)
  To: rjw, len.brown, ranjani.sridharan
  Cc: daniel.baluta, aisheng.dong, ulf.hansson, festevam, alsa-devel,
	linux-pm, gregkh, s.hauer, khilman, linux-kernel, daniel.baluta,
	pierre-louis.bossart, paul.olaru, linux-imx, kernel, shawnguo,
	shengjiu.wang, linux-arm-kernel

From: Daniel Baluta <daniel.baluta@nxp.com>

i.MX8QXP/i.MX8QM has IPs that need multiple power domains to be up
in order to work. In order to help drivers, we introduce multi PM
domains helpers that are able to activate/deactivate multi PM domains.

First patch introduces the helpers and second patch demonstrates how
a driver can use them instead of hardcoding the PM domains handling.

Changes since v1: (addressed Ranjani's comments)
	- enhanced description for dev_multi_pm_attach return value
	- renamed exit_unroll_pm label to exit_detach_pm

Daniel Baluta (2):
  PM / domains: Introduce multi PM domains helpers
  ASoC: SOF: Use multi PM domains helpers

 drivers/base/power/common.c | 93 +++++++++++++++++++++++++++++++++++++
 include/linux/pm_domain.h   | 19 ++++++++
 sound/soc/sof/imx/imx8.c    | 60 ++++--------------------
 3 files changed, 121 insertions(+), 51 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [RFC PATCH v2 1/2] PM / domains: Introduce multi PM domains helpers
  2020-03-04 12:19 [RFC PATCH v2 0/2] Introduce multi PM domains helpers Daniel Baluta
@ 2020-03-04 12:19 ` Daniel Baluta
  2020-04-21 14:00   ` Ulf Hansson
  2020-03-04 12:19 ` [RFC PATCH v2 2/2] ASoC: SOF: Use " Daniel Baluta
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Daniel Baluta @ 2020-03-04 12:19 UTC (permalink / raw)
  To: rjw, len.brown, ranjani.sridharan
  Cc: daniel.baluta, aisheng.dong, ulf.hansson, festevam, alsa-devel,
	linux-pm, gregkh, s.hauer, khilman, linux-kernel, daniel.baluta,
	pierre-louis.bossart, paul.olaru, linux-imx, kernel, shawnguo,
	shengjiu.wang, linux-arm-kernel

From: Daniel Baluta <daniel.baluta@nxp.com>

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 <daniel.baluta@nxp.com>
---
 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


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH v2 2/2] ASoC: SOF: Use multi PM domains helpers
  2020-03-04 12:19 [RFC PATCH v2 0/2] Introduce multi PM domains helpers Daniel Baluta
  2020-03-04 12:19 ` [RFC PATCH v2 1/2] PM / domains: " Daniel Baluta
@ 2020-03-04 12:19 ` Daniel Baluta
  2020-03-04 17:37 ` [RFC PATCH v2 0/2] Introduce " Ranjani Sridharan
  2020-03-30  8:38 ` Daniel Baluta
  3 siblings, 0 replies; 7+ messages in thread
From: Daniel Baluta @ 2020-03-04 12:19 UTC (permalink / raw)
  To: rjw, len.brown, ranjani.sridharan
  Cc: daniel.baluta, aisheng.dong, ulf.hansson, festevam, alsa-devel,
	linux-pm, gregkh, s.hauer, khilman, linux-kernel, daniel.baluta,
	pierre-louis.bossart, paul.olaru, linux-imx, kernel, shawnguo,
	shengjiu.wang, linux-arm-kernel

From: Daniel Baluta <daniel.baluta@nxp.com>

Use dev_multi_pm_attach / dev_multi_pm_detach instead of the hardcoded
version.

Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
---
 sound/soc/sof/imx/imx8.c | 60 ++++++----------------------------------
 1 file changed, 9 insertions(+), 51 deletions(-)

diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c
index b692752b2178..2e7635b697cf 100644
--- a/sound/soc/sof/imx/imx8.c
+++ b/sound/soc/sof/imx/imx8.c
@@ -51,10 +51,7 @@ struct imx8_priv {
 	struct imx_sc_ipc *sc_ipc;
 
 	/* Power domain handling */
-	int num_domains;
-	struct device **pd_dev;
-	struct device_link **link;
-
+	struct dev_multi_pm_domain_data *mpd;
 };
 
 static void imx8_get_reply(struct snd_sof_dev *sdev)
@@ -207,7 +204,6 @@ static int imx8_probe(struct snd_sof_dev *sdev)
 	struct resource res;
 	u32 base, size;
 	int ret = 0;
-	int i;
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
@@ -218,45 +214,15 @@ static int imx8_probe(struct snd_sof_dev *sdev)
 	priv->sdev = sdev;
 
 	/* power up device associated power domains */
-	priv->num_domains = of_count_phandle_with_args(np, "power-domains",
-						       "#power-domain-cells");
-	if (priv->num_domains < 0) {
-		dev_err(sdev->dev, "no power-domains property in %pOF\n", np);
-		return priv->num_domains;
-	}
-
-	priv->pd_dev = devm_kmalloc_array(&pdev->dev, priv->num_domains,
-					  sizeof(*priv->pd_dev), GFP_KERNEL);
-	if (!priv->pd_dev)
-		return -ENOMEM;
-
-	priv->link = devm_kmalloc_array(&pdev->dev, priv->num_domains,
-					sizeof(*priv->link), GFP_KERNEL);
-	if (!priv->link)
-		return -ENOMEM;
-
-	for (i = 0; i < priv->num_domains; i++) {
-		priv->pd_dev[i] = dev_pm_domain_attach_by_id(&pdev->dev, i);
-		if (IS_ERR(priv->pd_dev[i])) {
-			ret = PTR_ERR(priv->pd_dev[i]);
-			goto exit_unroll_pm;
-		}
-		priv->link[i] = device_link_add(&pdev->dev, priv->pd_dev[i],
-						DL_FLAG_STATELESS |
-						DL_FLAG_PM_RUNTIME |
-						DL_FLAG_RPM_ACTIVE);
-		if (!priv->link[i]) {
-			ret = -ENOMEM;
-			dev_pm_domain_detach(priv->pd_dev[i], false);
-			goto exit_unroll_pm;
-		}
-	}
+	priv->mpd = dev_multi_pm_attach(&pdev->dev);
+	if (IS_ERR(priv->mpd))
+		return PTR_ERR(priv->mpd);
 
 	ret = imx_scu_get_handle(&priv->sc_ipc);
 	if (ret) {
 		dev_err(sdev->dev, "Cannot obtain SCU handle (err = %d)\n",
 			ret);
-		goto exit_unroll_pm;
+		goto exit_detach_pm;
 	}
 
 	priv->ipc_dev = platform_device_register_data(sdev->dev, "imx-dsp",
@@ -264,7 +230,7 @@ static int imx8_probe(struct snd_sof_dev *sdev)
 						      pdev, sizeof(*pdev));
 	if (IS_ERR(priv->ipc_dev)) {
 		ret = PTR_ERR(priv->ipc_dev);
-		goto exit_unroll_pm;
+		goto exit_detach_pm;
 	}
 
 	priv->dsp_ipc = dev_get_drvdata(&priv->ipc_dev->dev);
@@ -328,26 +294,18 @@ static int imx8_probe(struct snd_sof_dev *sdev)
 
 exit_pdev_unregister:
 	platform_device_unregister(priv->ipc_dev);
-exit_unroll_pm:
-	while (--i >= 0) {
-		device_link_del(priv->link[i]);
-		dev_pm_domain_detach(priv->pd_dev[i], false);
-	}
-
+exit_detach_pm:
+	dev_multi_pm_detach(priv->mpd);
 	return ret;
 }
 
 static int imx8_remove(struct snd_sof_dev *sdev)
 {
 	struct imx8_priv *priv = (struct imx8_priv *)sdev->private;
-	int i;
 
 	platform_device_unregister(priv->ipc_dev);
 
-	for (i = 0; i < priv->num_domains; i++) {
-		device_link_del(priv->link[i]);
-		dev_pm_domain_detach(priv->pd_dev[i], false);
-	}
+	dev_multi_pm_detach(priv->mpd);
 
 	return 0;
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH v2 0/2] Introduce multi PM domains helpers
  2020-03-04 12:19 [RFC PATCH v2 0/2] Introduce multi PM domains helpers Daniel Baluta
  2020-03-04 12:19 ` [RFC PATCH v2 1/2] PM / domains: " Daniel Baluta
  2020-03-04 12:19 ` [RFC PATCH v2 2/2] ASoC: SOF: Use " Daniel Baluta
@ 2020-03-04 17:37 ` Ranjani Sridharan
  2020-03-30  8:38 ` Daniel Baluta
  3 siblings, 0 replies; 7+ messages in thread
From: Ranjani Sridharan @ 2020-03-04 17:37 UTC (permalink / raw)
  To: Daniel Baluta, rjw, len.brown
  Cc: aisheng.dong, pierre-louis.bossart, ulf.hansson, linux-pm,
	gregkh, s.hauer, alsa-devel, daniel.baluta, linux-kernel,
	paul.olaru, khilman, linux-imx, kernel, shawnguo, festevam,
	shengjiu.wang, linux-arm-kernel

On Wed, 2020-03-04 at 14:19 +0200, Daniel Baluta wrote:
> From: Daniel Baluta <daniel.baluta@nxp.com>
> 
> i.MX8QXP/i.MX8QM has IPs that need multiple power domains to be up
> in order to work. In order to help drivers, we introduce multi PM
> domains helpers that are able to activate/deactivate multi PM
> domains.
> 
> First patch introduces the helpers and second patch demonstrates how
> a driver can use them instead of hardcoding the PM domains handling.
> 
> Changes since v1: (addressed Ranjani's comments)
> 	- enhanced description for dev_multi_pm_attach return value
> 	- renamed exit_unroll_pm label to exit_detach_pm
> 
> Daniel Baluta (2):
>   PM / domains: Introduce multi PM domains helpers
>   ASoC: SOF: Use multi PM domains helpers
Both patches LGTM. Thanks Daniel.

Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH v2 0/2] Introduce multi PM domains helpers
  2020-03-04 12:19 [RFC PATCH v2 0/2] Introduce multi PM domains helpers Daniel Baluta
                   ` (2 preceding siblings ...)
  2020-03-04 17:37 ` [RFC PATCH v2 0/2] Introduce " Ranjani Sridharan
@ 2020-03-30  8:38 ` Daniel Baluta
  3 siblings, 0 replies; 7+ messages in thread
From: Daniel Baluta @ 2020-03-30  8:38 UTC (permalink / raw)
  To: Daniel Baluta, Aisheng Dong, Ulf Hansson, rafael.j.wysocki
  Cc: rjw, Brown, Len, Ranjani Sridharan, Fabio Estevam, Linux-ALSA,
	linux-pm, Greg Kroah-Hartman, Sascha Hauer, khilman,
	Linux Kernel Mailing List, Daniel Baluta, Pierre-Louis Bossart,
	Paul Olaru, dl-linux-imx, Pengutronix Kernel Team, Shawn Guo,
	S.j. Wang, linux-arm-kernel

Rafael / Ulf / Aisheng,

Any comments?

On Wed, Mar 4, 2020 at 2:20 PM Daniel Baluta <daniel.baluta@oss.nxp.com> wrote:
>
> From: Daniel Baluta <daniel.baluta@nxp.com>
>
> i.MX8QXP/i.MX8QM has IPs that need multiple power domains to be up
> in order to work. In order to help drivers, we introduce multi PM
> domains helpers that are able to activate/deactivate multi PM domains.
>
> First patch introduces the helpers and second patch demonstrates how
> a driver can use them instead of hardcoding the PM domains handling.
>
> Changes since v1: (addressed Ranjani's comments)
>         - enhanced description for dev_multi_pm_attach return value
>         - renamed exit_unroll_pm label to exit_detach_pm
>
> Daniel Baluta (2):
>   PM / domains: Introduce multi PM domains helpers
>   ASoC: SOF: Use multi PM domains helpers
>
>  drivers/base/power/common.c | 93 +++++++++++++++++++++++++++++++++++++
>  include/linux/pm_domain.h   | 19 ++++++++
>  sound/soc/sof/imx/imx8.c    | 60 ++++--------------------
>  3 files changed, 121 insertions(+), 51 deletions(-)
>
> --
> 2.17.1
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH v2 1/2] PM / domains: Introduce multi PM domains helpers
  2020-03-04 12:19 ` [RFC PATCH v2 1/2] PM / domains: " Daniel Baluta
@ 2020-04-21 14:00   ` Ulf Hansson
  2020-04-21 14:18     ` Daniel Baluta
  0 siblings, 1 reply; 7+ messages in thread
From: Ulf Hansson @ 2020-04-21 14:00 UTC (permalink / raw)
  To: Daniel Baluta
  Cc: Rafael J. Wysocki, Len Brown, ranjani.sridharan, Aisheng Dong,
	Fabio Estevam, alsa-devel, Linux PM, Greg Kroah-Hartman,
	Sascha Hauer, Kevin Hilman, Linux Kernel Mailing List,
	Daniel Baluta, Pierre-Louis Bossart, paul.olaru, dl-linux-imx,
	Sascha Hauer, Shawn Guo, shengjiu.wang, Linux ARM

On Wed, 4 Mar 2020 at 13:20, Daniel Baluta <daniel.baluta@oss.nxp.com> wrote:
>
> From: Daniel Baluta <daniel.baluta@nxp.com>
>
> 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 <daniel.baluta@nxp.com>

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
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH v2 1/2] PM / domains: Introduce multi PM domains helpers
  2020-04-21 14:00   ` Ulf Hansson
@ 2020-04-21 14:18     ` Daniel Baluta
  0 siblings, 0 replies; 7+ messages in thread
From: Daniel Baluta @ 2020-04-21 14:18 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Daniel Baluta, Aisheng Dong, Len Brown, Linux-ALSA, Linux PM,
	Greg Kroah-Hartman, Sascha Hauer, Kevin Hilman,
	Rafael J. Wysocki, Ranjani Sridharan, Daniel Baluta,
	Linux Kernel Mailing List, Paul Olaru, dl-linux-imx,
	Sascha Hauer, Pierre-Louis Bossart, Shawn Guo, Fabio Estevam,
	S.j. Wang, Linux ARM, Anson Huang

On Tue, Apr 21, 2020 at 5:01 PM Ulf Hansson <ulf.hansson@linaro.org> wrote:
>
> On Wed, 4 Mar 2020 at 13:20, Daniel Baluta <daniel.baluta@oss.nxp.com> wrote:
> >
> > From: Daniel Baluta <daniel.baluta@nxp.com>
> >
> > 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 <daniel.baluta@nxp.com>
>
> 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?

IMX Sound Open Firmware driver will immediately be available
to use this new API.

https://elixir.bootlin.com/linux/latest/source/sound/soc/sof/imx/imx8.c#L221

Aside, from that there are the ACM clock modules for i.MX8QXP / i.MX8QM. Also,
looking at our internal tree there are XUVI, VPU, DPU drivers that need multi
power domain support.

Anson, Aisheng do you have a number of users on your side for
multi power domain?

thanks,
daniel.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-04-21 14:19 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-04 12:19 [RFC PATCH v2 0/2] Introduce multi PM domains helpers Daniel Baluta
2020-03-04 12:19 ` [RFC PATCH v2 1/2] PM / domains: " Daniel Baluta
2020-04-21 14:00   ` Ulf Hansson
2020-04-21 14:18     ` Daniel Baluta
2020-03-04 12:19 ` [RFC PATCH v2 2/2] ASoC: SOF: Use " Daniel Baluta
2020-03-04 17:37 ` [RFC PATCH v2 0/2] Introduce " Ranjani Sridharan
2020-03-30  8:38 ` Daniel Baluta

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).