All of lore.kernel.org
 help / color / mirror / Atom feed
From: Aisheng Dong <aisheng.dong@nxp.com>
To: "linux-pm@vger.kernel.org" <linux-pm@vger.kernel.org>
Cc: "linux-arm-kernel@lists.infradead.org" 
	<linux-arm-kernel@lists.infradead.org>,
	"dongas86@gmail.com" <dongas86@gmail.com>,
	"kernel@pengutronix.de" <kernel@pengutronix.de>,
	"shawnguo@kernel.org" <shawnguo@kernel.org>,
	Fabio Estevam <fabio.estevam@nxp.com>,
	dl-linux-imx <linux-imx@nxp.com>,
	"rjw@rjwysocki.net" <rjw@rjwysocki.net>,
	"ulf.hansson@linaro.org" <ulf.hansson@linaro.org>,
	"khilman@kernel.org" <khilman@kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Aisheng Dong <aisheng.dong@nxp.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Subject: [RFC PATCH 1/1] PM / Domains: Add multi PM domains support for attach_dev
Date: Thu, 27 Dec 2018 17:14:48 +0000	[thread overview]
Message-ID: <1545930550-9906-1-git-send-email-aisheng.dong@nxp.com> (raw)

Currently attach_dev() in power domain infrastructure still does
not support multi domains case as the struct device *dev passed
down from genpd_dev_pm_attach_by_id() is a virtual PD device, it
does not help for parsing the real device information from device
tree, e.g. Device/Power IDs, Clocks and it's unware of which real
power domain the device should attach.

Extend the framework a bit to store the multi PM domains information
in per-device struct generic_pm_domain_data, then power domain driver
could retrieve it for necessary operations during attach_dev().

Two new APIs genpd_is_mpd_device() and dev_gpd_mpd_data() are also
introduced to ease the driver operation.

Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Kevin Hilman <khilman@kernel.org>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
This patch is a follow-up work of the earlier discussion with Ulf Hansson
about the multi PM domains support for the attach_dev() function [1].
After a bit more thinking, this is a less intrusive implementation with
the mininum impact on the exist function definitions and calling follows.
One known little drawback is that we have to use the device driver private
data (device.drvdata) to pass down the multi domains information in a
earlier time. However, as multi PD devices are created by domain framework,
this seems to be safe to use it in domain core code as device driver
is not likely going to use it.
Anyway, if any better ideas, please let me know.

With the two new APIs, the using can be simply as:
static int xxx_attach_dev(struct generic_pm_domain *domain,
			  struct device *dev)
{
	...
	if (genpd_is_mpd_device(dev)) {
		mpd_data = dev_gpd_mpd_data(dev);
		np = mpd_data->parent->of_node;
		idx = mpd_data->index;
		//dts parsing
		...
	}
	...
}

[1] https://patchwork.kernel.org/patch/10658669/
---
 drivers/base/power/domain.c | 31 +++++++++++++++++++++++++++++++
 include/linux/pm_domain.h   | 23 +++++++++++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 7f38a92..1aa0918 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1343,6 +1343,9 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev,
 	gpd_data->td.effective_constraint_ns = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS;
 	gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier;
 
+	if (genpd_is_mpd_device(dev))
+		gpd_data->mpd_data = dev_get_drvdata(dev);
+
 	spin_lock_irq(&dev->power.lock);
 
 	if (dev->power.subsys_data->domain_data) {
@@ -2179,6 +2182,7 @@ EXPORT_SYMBOL_GPL(of_genpd_remove_last);
 
 static void genpd_release_dev(struct device *dev)
 {
+	kfree(dev->driver_data);
 	kfree(dev);
 }
 
@@ -2320,6 +2324,20 @@ int genpd_dev_pm_attach(struct device *dev)
 EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
 
 /**
+ * genpd_is_mpd_device - Check if a device is associated with multi PM domains
+ * @dev: Device to check.
+ */
+
+bool genpd_is_mpd_device(struct device *dev)
+{
+	if (!dev || (dev && !dev->bus))
+		return false;
+
+	return dev->bus == &genpd_bus_type;
+};
+EXPORT_SYMBOL_GPL(genpd_is_mpd_device);
+
+/**
  * genpd_dev_pm_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.
@@ -2338,6 +2356,7 @@ EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
 struct device *genpd_dev_pm_attach_by_id(struct device *dev,
 					 unsigned int index)
 {
+	struct pm_domain_mpd_data *mpd_data;
 	struct device *genpd_dev;
 	int num_domains;
 	int ret;
@@ -2366,6 +2385,18 @@ struct device *genpd_dev_pm_attach_by_id(struct device *dev,
 		return ERR_PTR(ret);
 	}
 
+	/* Allocate multi power domains data */
+	mpd_data = kzalloc(sizeof(*mpd_data), GFP_KERNEL);
+	if (!mpd_data) {
+		device_unregister(genpd_dev);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	mpd_data->parent = dev;
+	mpd_data->index = index;
+
+	dev_set_drvdata(genpd_dev, mpd_data);
+
 	/* Try to attach the device to the PM domain at the specified index. */
 	ret = __genpd_dev_pm_attach(genpd_dev, dev->of_node, index, false);
 	if (ret < 1) {
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 3b5d728..106d4e7 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -144,6 +144,11 @@ struct gpd_timing_data {
 	bool cached_suspend_ok;
 };
 
+struct pm_domain_mpd_data {
+	struct device *parent;
+	unsigned int index;
+};
+
 struct pm_domain_data {
 	struct list_head list_node;
 	struct device *dev;
@@ -151,6 +156,7 @@ struct pm_domain_data {
 
 struct generic_pm_domain_data {
 	struct pm_domain_data base;
+	struct pm_domain_mpd_data *mpd_data;
 	struct gpd_timing_data td;
 	struct notifier_block nb;
 	unsigned int performance_state;
@@ -262,10 +268,17 @@ unsigned int of_genpd_opp_to_performance_state(struct device *dev,
 				struct device_node *np);
 
 int genpd_dev_pm_attach(struct device *dev);
+bool genpd_is_mpd_device(struct device *dev);
 struct device *genpd_dev_pm_attach_by_id(struct device *dev,
 					 unsigned int index);
 struct device *genpd_dev_pm_attach_by_name(struct device *dev,
 					   char *name);
+
+static inline struct pm_domain_mpd_data *dev_gpd_mpd_data(struct device *dev)
+{
+	return dev_gpd_data(dev)->mpd_data;
+}
+
 #else /* !CONFIG_PM_GENERIC_DOMAINS_OF */
 static inline int of_genpd_add_provider_simple(struct device_node *np,
 					struct generic_pm_domain *genpd)
@@ -311,6 +324,11 @@ static inline int genpd_dev_pm_attach(struct device *dev)
 	return 0;
 }
 
+static bool genpd_is_mpd_device(struct device *dev)
+{
+	return false;
+}
+
 static inline struct device *genpd_dev_pm_attach_by_id(struct device *dev,
 						       unsigned int index)
 {
@@ -323,6 +341,11 @@ static inline struct device *genpd_dev_pm_attach_by_name(struct device *dev,
 	return NULL;
 }
 
+static inline struct pm_domain_mpd_data *dev_gpd_mpd_data(struct device *dev)
+{
+	return ERR_PTR(-ENOSYS);
+}
+
 static inline
 struct generic_pm_domain *of_genpd_remove_last(struct device_node *np)
 {
-- 
2.7.4


WARNING: multiple messages have this Message-ID (diff)
From: Aisheng Dong <aisheng.dong@nxp.com>
To: "linux-pm@vger.kernel.org" <linux-pm@vger.kernel.org>
Cc: Aisheng Dong <aisheng.dong@nxp.com>,
	"ulf.hansson@linaro.org" <ulf.hansson@linaro.org>,
	"dongas86@gmail.com" <dongas86@gmail.com>,
	"khilman@kernel.org" <khilman@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	"rjw@rjwysocki.net" <rjw@rjwysocki.net>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	dl-linux-imx <linux-imx@nxp.com>,
	"kernel@pengutronix.de" <kernel@pengutronix.de>,
	Fabio Estevam <fabio.estevam@nxp.com>,
	"shawnguo@kernel.org" <shawnguo@kernel.org>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>
Subject: [RFC PATCH 1/1] PM / Domains: Add multi PM domains support for attach_dev
Date: Thu, 27 Dec 2018 17:14:48 +0000	[thread overview]
Message-ID: <1545930550-9906-1-git-send-email-aisheng.dong@nxp.com> (raw)

Currently attach_dev() in power domain infrastructure still does
not support multi domains case as the struct device *dev passed
down from genpd_dev_pm_attach_by_id() is a virtual PD device, it
does not help for parsing the real device information from device
tree, e.g. Device/Power IDs, Clocks and it's unware of which real
power domain the device should attach.

Extend the framework a bit to store the multi PM domains information
in per-device struct generic_pm_domain_data, then power domain driver
could retrieve it for necessary operations during attach_dev().

Two new APIs genpd_is_mpd_device() and dev_gpd_mpd_data() are also
introduced to ease the driver operation.

Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Kevin Hilman <khilman@kernel.org>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
This patch is a follow-up work of the earlier discussion with Ulf Hansson
about the multi PM domains support for the attach_dev() function [1].
After a bit more thinking, this is a less intrusive implementation with
the mininum impact on the exist function definitions and calling follows.
One known little drawback is that we have to use the device driver private
data (device.drvdata) to pass down the multi domains information in a
earlier time. However, as multi PD devices are created by domain framework,
this seems to be safe to use it in domain core code as device driver
is not likely going to use it.
Anyway, if any better ideas, please let me know.

With the two new APIs, the using can be simply as:
static int xxx_attach_dev(struct generic_pm_domain *domain,
			  struct device *dev)
{
	...
	if (genpd_is_mpd_device(dev)) {
		mpd_data = dev_gpd_mpd_data(dev);
		np = mpd_data->parent->of_node;
		idx = mpd_data->index;
		//dts parsing
		...
	}
	...
}

[1] https://patchwork.kernel.org/patch/10658669/
---
 drivers/base/power/domain.c | 31 +++++++++++++++++++++++++++++++
 include/linux/pm_domain.h   | 23 +++++++++++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 7f38a92..1aa0918 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1343,6 +1343,9 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev,
 	gpd_data->td.effective_constraint_ns = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS;
 	gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier;
 
+	if (genpd_is_mpd_device(dev))
+		gpd_data->mpd_data = dev_get_drvdata(dev);
+
 	spin_lock_irq(&dev->power.lock);
 
 	if (dev->power.subsys_data->domain_data) {
@@ -2179,6 +2182,7 @@ EXPORT_SYMBOL_GPL(of_genpd_remove_last);
 
 static void genpd_release_dev(struct device *dev)
 {
+	kfree(dev->driver_data);
 	kfree(dev);
 }
 
@@ -2320,6 +2324,20 @@ int genpd_dev_pm_attach(struct device *dev)
 EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
 
 /**
+ * genpd_is_mpd_device - Check if a device is associated with multi PM domains
+ * @dev: Device to check.
+ */
+
+bool genpd_is_mpd_device(struct device *dev)
+{
+	if (!dev || (dev && !dev->bus))
+		return false;
+
+	return dev->bus == &genpd_bus_type;
+};
+EXPORT_SYMBOL_GPL(genpd_is_mpd_device);
+
+/**
  * genpd_dev_pm_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.
@@ -2338,6 +2356,7 @@ EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
 struct device *genpd_dev_pm_attach_by_id(struct device *dev,
 					 unsigned int index)
 {
+	struct pm_domain_mpd_data *mpd_data;
 	struct device *genpd_dev;
 	int num_domains;
 	int ret;
@@ -2366,6 +2385,18 @@ struct device *genpd_dev_pm_attach_by_id(struct device *dev,
 		return ERR_PTR(ret);
 	}
 
+	/* Allocate multi power domains data */
+	mpd_data = kzalloc(sizeof(*mpd_data), GFP_KERNEL);
+	if (!mpd_data) {
+		device_unregister(genpd_dev);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	mpd_data->parent = dev;
+	mpd_data->index = index;
+
+	dev_set_drvdata(genpd_dev, mpd_data);
+
 	/* Try to attach the device to the PM domain at the specified index. */
 	ret = __genpd_dev_pm_attach(genpd_dev, dev->of_node, index, false);
 	if (ret < 1) {
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 3b5d728..106d4e7 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -144,6 +144,11 @@ struct gpd_timing_data {
 	bool cached_suspend_ok;
 };
 
+struct pm_domain_mpd_data {
+	struct device *parent;
+	unsigned int index;
+};
+
 struct pm_domain_data {
 	struct list_head list_node;
 	struct device *dev;
@@ -151,6 +156,7 @@ struct pm_domain_data {
 
 struct generic_pm_domain_data {
 	struct pm_domain_data base;
+	struct pm_domain_mpd_data *mpd_data;
 	struct gpd_timing_data td;
 	struct notifier_block nb;
 	unsigned int performance_state;
@@ -262,10 +268,17 @@ unsigned int of_genpd_opp_to_performance_state(struct device *dev,
 				struct device_node *np);
 
 int genpd_dev_pm_attach(struct device *dev);
+bool genpd_is_mpd_device(struct device *dev);
 struct device *genpd_dev_pm_attach_by_id(struct device *dev,
 					 unsigned int index);
 struct device *genpd_dev_pm_attach_by_name(struct device *dev,
 					   char *name);
+
+static inline struct pm_domain_mpd_data *dev_gpd_mpd_data(struct device *dev)
+{
+	return dev_gpd_data(dev)->mpd_data;
+}
+
 #else /* !CONFIG_PM_GENERIC_DOMAINS_OF */
 static inline int of_genpd_add_provider_simple(struct device_node *np,
 					struct generic_pm_domain *genpd)
@@ -311,6 +324,11 @@ static inline int genpd_dev_pm_attach(struct device *dev)
 	return 0;
 }
 
+static bool genpd_is_mpd_device(struct device *dev)
+{
+	return false;
+}
+
 static inline struct device *genpd_dev_pm_attach_by_id(struct device *dev,
 						       unsigned int index)
 {
@@ -323,6 +341,11 @@ static inline struct device *genpd_dev_pm_attach_by_name(struct device *dev,
 	return NULL;
 }
 
+static inline struct pm_domain_mpd_data *dev_gpd_mpd_data(struct device *dev)
+{
+	return ERR_PTR(-ENOSYS);
+}
+
 static inline
 struct generic_pm_domain *of_genpd_remove_last(struct device_node *np)
 {
-- 
2.7.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

             reply	other threads:[~2018-12-27 17:14 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-27 17:14 Aisheng Dong [this message]
2018-12-27 17:14 ` [RFC PATCH 1/1] PM / Domains: Add multi PM domains support for attach_dev Aisheng Dong
2018-12-27 17:14 ` Aisheng Dong
2018-12-28 15:36 ` Ulf Hansson
2018-12-28 15:36   ` Ulf Hansson
2018-12-28 15:36   ` Ulf Hansson
2018-12-29  6:43   ` Aisheng Dong
2018-12-29  6:43     ` Aisheng Dong
2018-12-29  6:43     ` Aisheng Dong
2019-01-02 10:49     ` Ulf Hansson
2019-01-02 10:49       ` Ulf Hansson
2019-01-02 10:49       ` Ulf Hansson
2019-01-02 16:29       ` Aisheng Dong
2019-01-02 16:29         ` Aisheng Dong
2019-01-02 16:29         ` Aisheng Dong
2019-01-03 21:10         ` Ulf Hansson
2019-01-03 21:10           ` Ulf Hansson
2019-01-03 21:10           ` Ulf Hansson
2019-01-04  3:50           ` Aisheng Dong
2019-01-04  3:50             ` Aisheng Dong
2019-01-04  3:50             ` Aisheng Dong
2019-02-05  9:39             ` Ulf Hansson
2019-02-05  9:39               ` Ulf Hansson
2019-02-05  9:39               ` Ulf Hansson

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=1545930550-9906-1-git-send-email-aisheng.dong@nxp.com \
    --to=aisheng.dong@nxp.com \
    --cc=dongas86@gmail.com \
    --cc=fabio.estevam@nxp.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=kernel@pengutronix.de \
    --cc=khilman@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-imx@nxp.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=rjw@rjwysocki.net \
    --cc=shawnguo@kernel.org \
    --cc=ulf.hansson@linaro.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.