All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jon Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
To: "Rafael J. Wysocki" <rjw-LthD3rsA81gm4RdzfppkhA@public.gmane.org>,
	Kevin Hilman <khilman-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Ulf Hansson <ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Thierry Reding
	<thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Kukjin Kim <kgene-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Krzysztof Kozlowski
	<k.kozlowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>,
	Alexander Aring
	<alex.aring-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Eric Anholt <eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org>,
	linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Jon Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Subject: [RFC PATCH 5/8] PM / Domains: Verify the PM domain is present when adding a provider
Date: Fri, 4 Mar 2016 11:23:51 +0000	[thread overview]
Message-ID: <1457090634-14785-6-git-send-email-jonathanh@nvidia.com> (raw)
In-Reply-To: <1457090634-14785-1-git-send-email-jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

When a PM domain provider is added, there is currently no way to tell if
the PM domain is actually present in the system. Naturally, the PM domain
provider should not be registered if the PM domain has not been added.
Nonetheless, to verify that the PM domain associated with a provider is
present, store the 'provider_data' in the PM domain structure when adding
the provider and make sure that the PM domain is found the list of PM
domains registered.

The of_genpd_add_provider_simple() and of_genpd_add_provider_onecell()
functions have been updated to store the 'provider_data' by default to
avoid having to modify all the current PM domain provider
implementations.

By doing this, we can also verify that the provider has been removed
from the list of providers before removing a PM domain.

Signed-off-by: Jon Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 drivers/base/power/domain.c | 74 +++++++++++++++++++++++++++++++++++++++++++--
 include/linux/pm_domain.h   | 13 +++++---
 2 files changed, 79 insertions(+), 8 deletions(-)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index c2ba1d6dbad3..72055fef6256 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1570,6 +1570,24 @@ static LIST_HEAD(of_genpd_providers);
 static DEFINE_MUTEX(of_genpd_mutex);
 
 /**
+ * pm_genpd_provider_present - Check if the provider's PM domain is present.
+ * @data: Provider data associated with the PM domain.
+ */
+static bool pm_genpd_provider_present(void *data)
+{
+	struct generic_pm_domain *gpd;
+
+	if (!data)
+		return false;
+
+	list_for_each_entry(gpd, &gpd_list, gpd_list_node)
+		if (gpd->provider_data == data)
+			return true;
+
+	return false;
+}
+
+/**
  * __of_genpd_xlate_simple() - Xlate function for direct node-domain mapping
  * @genpdspec: OF phandle args to map into a PM domain
  * @data: xlate function private data - pointer to struct generic_pm_domain
@@ -1625,9 +1643,15 @@ EXPORT_SYMBOL_GPL(__of_genpd_xlate_onecell);
  * @np: Device node pointer associated with the PM domain provider.
  * @xlate: Callback for decoding PM domain from phandle arguments.
  * @data: Context pointer for @xlate callback.
+ *
+ * The PM domain assocaited with the provider must have the
+ * 'provider_data' member of the PM domain structure populated with the
+ * same data pointer passed to this function. This is used to verify
+ * that the PM domain associated with the provider is present in the
+ * list of registered PM domains.
  */
-int __of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
-			void *data)
+static int __of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
+				   void *data)
 {
 	struct of_genpd_provider *cp;
 
@@ -1635,6 +1659,13 @@ int __of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
 	if (!cp)
 		return -ENOMEM;
 
+	mutex_lock(&gpd_list_lock);
+
+	if (!pm_genpd_provider_present(data)) {
+		mutex_unlock(&gpd_list_lock);
+		return -EINVAL;
+	}
+
 	cp->node = of_node_get(np);
 	cp->data = data;
 	cp->xlate = xlate;
@@ -1642,11 +1673,48 @@ int __of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
 	mutex_lock(&of_genpd_mutex);
 	list_add(&cp->link, &of_genpd_providers);
 	mutex_unlock(&of_genpd_mutex);
+	mutex_unlock(&gpd_list_lock);
 	pr_debug("Added domain provider from %s\n", np->full_name);
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(__of_genpd_add_provider);
+
+/**
+ * of_genpd_add_provider_simple() - Register a simple PM domain provider
+ * @np: Device node pointer associated with the PM domain provider.
+ * @genpd: Pointer to PM domain associated with the PM domain provider.
+ */
+int of_genpd_add_provider_simple(struct device_node *np,
+				 struct generic_pm_domain *genpd)
+{
+	if (!np || !genpd)
+		return -EINVAL;
+
+	genpd->provider_data = genpd;
+
+	return __of_genpd_add_provider(np, __of_genpd_xlate_simple, genpd);
+}
+EXPORT_SYMBOL_GPL(of_genpd_add_provider_simple);
+
+/**
+ * of_genpd_add_provider_onecell() - Register a onecell PM domain provider
+ * @np: Device node pointer associated with the PM domain provider.
+ * @data: Pointer to the data associated with the PM domain provider.
+ */
+int of_genpd_add_provider_onecell(struct device_node *np,
+				  struct genpd_onecell_data *data)
+{
+	unsigned int i;
+
+	if (!np || !data)
+		return -EINVAL;
+
+	for (i = 0; i < data->num_domains; i++)
+		data->domains[i]->provider_data = data;
+
+	return __of_genpd_add_provider(np, __of_genpd_xlate_onecell, data);
+}
+EXPORT_SYMBOL_GPL(of_genpd_add_provider_onecell);
 
 /**
  * of_genpd_del_provider() - Remove a previously registered PM domain provider
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 510512d5390e..bed84413546f 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -53,6 +53,7 @@ struct generic_pm_domain {
 	struct mutex lock;
 	struct dev_power_governor *gov;
 	struct work_struct power_off_work;
+	void *provider_data;
 	const char *name;
 	atomic_t sd_count;	/* Number of subdomains with power "on" */
 	enum gpd_status status;	/* Current state of the domain */
@@ -193,8 +194,10 @@ typedef struct generic_pm_domain *(*genpd_xlate_t)(struct of_phandle_args *args,
 						void *data);
 
 #ifdef CONFIG_PM_GENERIC_DOMAINS_OF
-int __of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
-			void *data);
+int of_genpd_add_provider_simple(struct device_node *np,
+				 struct generic_pm_domain *genpd);
+int of_genpd_add_provider_onecell(struct device_node *np,
+				  struct genpd_onecell_data *data);
 void of_genpd_del_provider(struct device_node *np);
 struct generic_pm_domain *__of_genpd_xlate_simple(
 					struct of_phandle_args *genpdspec,
@@ -235,18 +238,18 @@ static inline int genpd_dev_pm_attach(struct device *dev)
 {
 	return -ENODEV;
 }
-#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
 
 static inline int of_genpd_add_provider_simple(struct device_node *np,
 					struct generic_pm_domain *genpd)
 {
-	return __of_genpd_add_provider(np, __of_genpd_xlate_simple, genpd);
+	return -ENOTSUPP;
 }
 static inline int of_genpd_add_provider_onecell(struct device_node *np,
 					struct genpd_onecell_data *data)
 {
-	return __of_genpd_add_provider(np, __of_genpd_xlate_onecell, data);
+	return -ENOTSUPP;
 }
+#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
 
 #ifdef CONFIG_PM
 extern int dev_pm_domain_attach(struct device *dev, bool power_on);
-- 
2.1.4

WARNING: multiple messages have this Message-ID (diff)
From: jonathanh@nvidia.com (Jon Hunter)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC PATCH 5/8] PM / Domains: Verify the PM domain is present when adding a provider
Date: Fri, 4 Mar 2016 11:23:51 +0000	[thread overview]
Message-ID: <1457090634-14785-6-git-send-email-jonathanh@nvidia.com> (raw)
In-Reply-To: <1457090634-14785-1-git-send-email-jonathanh@nvidia.com>

When a PM domain provider is added, there is currently no way to tell if
the PM domain is actually present in the system. Naturally, the PM domain
provider should not be registered if the PM domain has not been added.
Nonetheless, to verify that the PM domain associated with a provider is
present, store the 'provider_data' in the PM domain structure when adding
the provider and make sure that the PM domain is found the list of PM
domains registered.

The of_genpd_add_provider_simple() and of_genpd_add_provider_onecell()
functions have been updated to store the 'provider_data' by default to
avoid having to modify all the current PM domain provider
implementations.

By doing this, we can also verify that the provider has been removed
from the list of providers before removing a PM domain.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/base/power/domain.c | 74 +++++++++++++++++++++++++++++++++++++++++++--
 include/linux/pm_domain.h   | 13 +++++---
 2 files changed, 79 insertions(+), 8 deletions(-)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index c2ba1d6dbad3..72055fef6256 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1570,6 +1570,24 @@ static LIST_HEAD(of_genpd_providers);
 static DEFINE_MUTEX(of_genpd_mutex);
 
 /**
+ * pm_genpd_provider_present - Check if the provider's PM domain is present.
+ * @data: Provider data associated with the PM domain.
+ */
+static bool pm_genpd_provider_present(void *data)
+{
+	struct generic_pm_domain *gpd;
+
+	if (!data)
+		return false;
+
+	list_for_each_entry(gpd, &gpd_list, gpd_list_node)
+		if (gpd->provider_data == data)
+			return true;
+
+	return false;
+}
+
+/**
  * __of_genpd_xlate_simple() - Xlate function for direct node-domain mapping
  * @genpdspec: OF phandle args to map into a PM domain
  * @data: xlate function private data - pointer to struct generic_pm_domain
@@ -1625,9 +1643,15 @@ EXPORT_SYMBOL_GPL(__of_genpd_xlate_onecell);
  * @np: Device node pointer associated with the PM domain provider.
  * @xlate: Callback for decoding PM domain from phandle arguments.
  * @data: Context pointer for @xlate callback.
+ *
+ * The PM domain assocaited with the provider must have the
+ * 'provider_data' member of the PM domain structure populated with the
+ * same data pointer passed to this function. This is used to verify
+ * that the PM domain associated with the provider is present in the
+ * list of registered PM domains.
  */
-int __of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
-			void *data)
+static int __of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
+				   void *data)
 {
 	struct of_genpd_provider *cp;
 
@@ -1635,6 +1659,13 @@ int __of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
 	if (!cp)
 		return -ENOMEM;
 
+	mutex_lock(&gpd_list_lock);
+
+	if (!pm_genpd_provider_present(data)) {
+		mutex_unlock(&gpd_list_lock);
+		return -EINVAL;
+	}
+
 	cp->node = of_node_get(np);
 	cp->data = data;
 	cp->xlate = xlate;
@@ -1642,11 +1673,48 @@ int __of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
 	mutex_lock(&of_genpd_mutex);
 	list_add(&cp->link, &of_genpd_providers);
 	mutex_unlock(&of_genpd_mutex);
+	mutex_unlock(&gpd_list_lock);
 	pr_debug("Added domain provider from %s\n", np->full_name);
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(__of_genpd_add_provider);
+
+/**
+ * of_genpd_add_provider_simple() - Register a simple PM domain provider
+ * @np: Device node pointer associated with the PM domain provider.
+ * @genpd: Pointer to PM domain associated with the PM domain provider.
+ */
+int of_genpd_add_provider_simple(struct device_node *np,
+				 struct generic_pm_domain *genpd)
+{
+	if (!np || !genpd)
+		return -EINVAL;
+
+	genpd->provider_data = genpd;
+
+	return __of_genpd_add_provider(np, __of_genpd_xlate_simple, genpd);
+}
+EXPORT_SYMBOL_GPL(of_genpd_add_provider_simple);
+
+/**
+ * of_genpd_add_provider_onecell() - Register a onecell PM domain provider
+ * @np: Device node pointer associated with the PM domain provider.
+ * @data: Pointer to the data associated with the PM domain provider.
+ */
+int of_genpd_add_provider_onecell(struct device_node *np,
+				  struct genpd_onecell_data *data)
+{
+	unsigned int i;
+
+	if (!np || !data)
+		return -EINVAL;
+
+	for (i = 0; i < data->num_domains; i++)
+		data->domains[i]->provider_data = data;
+
+	return __of_genpd_add_provider(np, __of_genpd_xlate_onecell, data);
+}
+EXPORT_SYMBOL_GPL(of_genpd_add_provider_onecell);
 
 /**
  * of_genpd_del_provider() - Remove a previously registered PM domain provider
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 510512d5390e..bed84413546f 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -53,6 +53,7 @@ struct generic_pm_domain {
 	struct mutex lock;
 	struct dev_power_governor *gov;
 	struct work_struct power_off_work;
+	void *provider_data;
 	const char *name;
 	atomic_t sd_count;	/* Number of subdomains with power "on" */
 	enum gpd_status status;	/* Current state of the domain */
@@ -193,8 +194,10 @@ typedef struct generic_pm_domain *(*genpd_xlate_t)(struct of_phandle_args *args,
 						void *data);
 
 #ifdef CONFIG_PM_GENERIC_DOMAINS_OF
-int __of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
-			void *data);
+int of_genpd_add_provider_simple(struct device_node *np,
+				 struct generic_pm_domain *genpd);
+int of_genpd_add_provider_onecell(struct device_node *np,
+				  struct genpd_onecell_data *data);
 void of_genpd_del_provider(struct device_node *np);
 struct generic_pm_domain *__of_genpd_xlate_simple(
 					struct of_phandle_args *genpdspec,
@@ -235,18 +238,18 @@ static inline int genpd_dev_pm_attach(struct device *dev)
 {
 	return -ENODEV;
 }
-#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
 
 static inline int of_genpd_add_provider_simple(struct device_node *np,
 					struct generic_pm_domain *genpd)
 {
-	return __of_genpd_add_provider(np, __of_genpd_xlate_simple, genpd);
+	return -ENOTSUPP;
 }
 static inline int of_genpd_add_provider_onecell(struct device_node *np,
 					struct genpd_onecell_data *data)
 {
-	return __of_genpd_add_provider(np, __of_genpd_xlate_onecell, data);
+	return -ENOTSUPP;
 }
+#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
 
 #ifdef CONFIG_PM
 extern int dev_pm_domain_attach(struct device *dev, bool power_on);
-- 
2.1.4

  parent reply	other threads:[~2016-03-04 11:23 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-04 11:23 [RFC PATCH 0/8] PM / Domains: Add support for removing PM domains Jon Hunter
2016-03-04 11:23 ` Jon Hunter
2016-03-04 11:23 ` [RFC PATCH 3/8] staging: board: Remove calls to of_genpd_get_from_provider() Jon Hunter
2016-03-04 11:23   ` Jon Hunter
2016-03-04 11:23 ` [RFC PATCH 4/8] PM / Domains: Don't expose generic_pm_domain structure Jon Hunter
2016-03-04 11:23   ` Jon Hunter
2016-08-05 11:55   ` Ulf Hansson
2016-08-05 11:55     ` Ulf Hansson
     [not found] ` <1457090634-14785-1-git-send-email-jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-03-04 11:23   ` [RFC PATCH 1/8] PM / Domains: Add new helper functions for device-tree Jon Hunter
2016-03-04 11:23     ` Jon Hunter
2016-06-22 11:00     ` Jon Hunter
2016-06-22 11:00       ` Jon Hunter
2016-06-22 14:58     ` Jon Hunter
2016-06-22 14:58       ` Jon Hunter
2016-06-22 15:08       ` Ulf Hansson
2016-06-22 15:08         ` Ulf Hansson
2016-06-22 15:22         ` Jon Hunter
2016-06-22 15:22           ` Jon Hunter
2016-06-22 15:36           ` Ulf Hansson
2016-06-22 15:36             ` Ulf Hansson
2016-03-04 11:23   ` [RFC PATCH 2/8] ARM: EXYNOS: Remove calls to of_genpd_get_from_provider() Jon Hunter
2016-03-04 11:23     ` Jon Hunter
2016-03-04 11:23   ` Jon Hunter [this message]
2016-03-04 11:23     ` [RFC PATCH 5/8] PM / Domains: Verify the PM domain is present when adding a provider Jon Hunter
2016-08-05 11:57     ` Ulf Hansson
2016-08-05 11:57       ` Ulf Hansson
2016-03-04 11:23   ` [RFC PATCH 7/8] PM / Domains: Prepare for adding support to remove PM domains Jon Hunter
2016-03-04 11:23     ` Jon Hunter
2016-03-04 12:33   ` [RFC PATCH 0/8] PM / Domains: Add support for removing " Ulf Hansson
2016-03-04 12:33     ` Ulf Hansson
     [not found]     ` <CAPDyKFq3hNARzjSOoP+-NmcgfSWzG6GDmh7qVX6yx6QPgN9Arw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-03-28 12:38       ` Jon Hunter
2016-03-28 12:38         ` Jon Hunter
     [not found]         ` <56F925D9.3080703-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-06-06 13:19           ` Jon Hunter
2016-06-06 13:19             ` Jon Hunter
2016-06-15 14:46   ` Ulf Hansson
2016-06-15 14:46     ` Ulf Hansson
2016-03-04 11:23 ` [RFC PATCH 6/8] PM / Domains: Remove a provider by referencing the data pointer Jon Hunter
2016-03-04 11:23   ` Jon Hunter
     [not found]   ` <1457090634-14785-7-git-send-email-jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-06-15 14:38     ` Ulf Hansson
2016-06-15 14:38       ` Ulf Hansson
2016-06-21 13:47       ` Jon Hunter
2016-06-21 13:47         ` Jon Hunter
     [not found]         ` <5769455C.9010809-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-07-11 13:14           ` Jon Hunter
2016-07-11 13:14             ` Jon Hunter
2016-08-05 11:55           ` Ulf Hansson
2016-08-05 11:55             ` Ulf Hansson
     [not found]             ` <CAPDyKFovC07Z9y-4RQ4MKGtjJx5w1D8er3Fv-8HF2qyTKgVViQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-08-11 16:39               ` Jon Hunter
2016-08-11 16:39                 ` Jon Hunter
     [not found]                 ` <18ad702c-83fe-fd6d-89ae-57e6f2715860-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-08-12  0:24                   ` Rafael J. Wysocki
2016-08-12  0:24                     ` Rafael J. Wysocki
2016-06-21 14:45     ` Jon Hunter
2016-06-21 14:45       ` Jon Hunter
2016-03-04 11:23 ` [RFC PATCH 8/8] PM / Domains: Add support for removing PM domains Jon Hunter
2016-03-04 11:23   ` Jon Hunter
     [not found]   ` <1457090634-14785-9-git-send-email-jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-06-15 14:33     ` Ulf Hansson
2016-06-15 14:33       ` Ulf Hansson
2016-06-21 14:08       ` Jon Hunter
2016-06-21 14:08         ` Jon Hunter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1457090634-14785-6-git-send-email-jonathanh@nvidia.com \
    --to=jonathanh-ddmlm1+adcrqt0dzr+alfa@public.gmane.org \
    --cc=alex.aring-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org \
    --cc=k.kozlowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org \
    --cc=kgene-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=khilman-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=rjw-LthD3rsA81gm4RdzfppkhA@public.gmane.org \
    --cc=thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.