All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] link regulator consumer with driver
@ 2018-07-05 14:25 Pascal PAILLET-LME
  2018-07-05 14:25 ` [PATCH 1/3] driver core: Add device_link_remove function Pascal PAILLET-LME
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Pascal PAILLET-LME @ 2018-07-05 14:25 UTC (permalink / raw)
  To: gregkh, lgirdwood, broonie, linux-kernel, benjamin.gaignard
  Cc: Pascal PAILLET-LME

From: pascal paillet <p.paillet@st.com>

The goal of this patch-set is to ensure that a regulator driver is not suspended
before regulator consumer. Currently this is done by implementing suspend_late()
ops in the regulator driver but this is painful for an I2C controlled regulator.
Instead, the proposal is to add a device link between the driver and the consumer
at regulator core framework level.
To avoid storing the link pointer in the regulator core structure, we create
device_link_remove() function that use the same argument as device_link_add().

pascal paillet (3):
  driver core: Add device_link_remove function
  regulator: core: Link consumer with regulator driver
  regulator: core: Change suspend_late to suspend

 drivers/base/core.c              | 30 +++++++++++++++++++++++++++
 drivers/regulator/core.c         | 44 ++++++++++++++++++++++++++--------------
 include/linux/device.h           |  1 +
 include/linux/regulator/driver.h |  2 +-
 4 files changed, 61 insertions(+), 16 deletions(-)

-- 
1.9.1

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

* [PATCH 2/3] regulator: core: Link consumer with regulator driver
  2018-07-05 14:25 [PATCH 0/3] link regulator consumer with driver Pascal PAILLET-LME
  2018-07-05 14:25 ` [PATCH 1/3] driver core: Add device_link_remove function Pascal PAILLET-LME
@ 2018-07-05 14:25 ` Pascal PAILLET-LME
  2018-07-05 16:53   ` Mark Brown
  2018-07-05 17:55   ` Applied "regulator: core: Link consumer with regulator driver" to the regulator tree Mark Brown
  2018-07-05 14:25 ` [PATCH 3/3] regulator: core: Change suspend_late to suspend Pascal PAILLET-LME
  2 siblings, 2 replies; 13+ messages in thread
From: Pascal PAILLET-LME @ 2018-07-05 14:25 UTC (permalink / raw)
  To: gregkh, lgirdwood, broonie, linux-kernel, benjamin.gaignard
  Cc: Pascal PAILLET-LME

From: pascal paillet <p.paillet@st.com>

Add a device link between the consumer and the driver so that
the consumer is not suspended before the driver. The goal is to avoid
implementing suspend_late ops in regulator drivers.

Signed-off-by: pascal paillet <p.paillet@st.com>
---
 drivers/regulator/core.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 6ed568b..607ec47 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1740,6 +1740,8 @@ struct regulator *_regulator_get(struct device *dev, const char *id,
 			rdev->use_count = 0;
 	}
 
+	device_link_add(dev, &rdev->dev, DL_FLAG_STATELESS);
+
 	return regulator;
 }
 
@@ -1829,9 +1831,21 @@ static void _regulator_put(struct regulator *regulator)
 
 	debugfs_remove_recursive(regulator->debugfs);
 
-	/* remove any sysfs entries */
-	if (regulator->dev)
+	if (regulator->dev) {
+		int count = 0;
+		struct regulator *r;
+
+		list_for_each_entry(r, &rdev->consumer_list, list)
+			if (r->dev == regulator->dev)
+				count++;
+
+		if (count == 1)
+			device_link_remove(regulator->dev, &rdev->dev);
+
+		/* remove any sysfs entries */
 		sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
+	}
+
 	regulator_lock(rdev);
 	list_del(&regulator->list);
 
-- 
1.9.1

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

* [PATCH 1/3] driver core: Add device_link_remove function
  2018-07-05 14:25 [PATCH 0/3] link regulator consumer with driver Pascal PAILLET-LME
@ 2018-07-05 14:25 ` Pascal PAILLET-LME
  2018-07-05 16:54   ` Mark Brown
  2018-07-05 17:55   ` Applied "driver core: Add device_link_remove function" to the regulator tree Mark Brown
  2018-07-05 14:25 ` [PATCH 2/3] regulator: core: Link consumer with regulator driver Pascal PAILLET-LME
  2018-07-05 14:25 ` [PATCH 3/3] regulator: core: Change suspend_late to suspend Pascal PAILLET-LME
  2 siblings, 2 replies; 13+ messages in thread
From: Pascal PAILLET-LME @ 2018-07-05 14:25 UTC (permalink / raw)
  To: gregkh, lgirdwood, broonie, linux-kernel, benjamin.gaignard
  Cc: Pascal PAILLET-LME

From: pascal paillet <p.paillet@st.com>

Device_link_remove uses the same arguments than device_link_add. The Goal
is to avoid storing the link pointer.

Signed-off-by: pascal paillet <p.paillet@st.com>
---
 drivers/base/core.c    | 30 ++++++++++++++++++++++++++++++
 include/linux/device.h |  1 +
 2 files changed, 31 insertions(+)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index 36622b5..3b380b1 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -365,6 +365,36 @@ void device_link_del(struct device_link *link)
 }
 EXPORT_SYMBOL_GPL(device_link_del);
 
+/**
+ * device_link_remove - remove a link between two devices.
+ * @consumer: Consumer end of the link.
+ * @supplier: Supplier end of the link.
+ *
+ * The caller must ensure proper synchronization of this function with runtime
+ * PM.
+ */
+void device_link_remove(void *consumer, struct device *supplier)
+{
+	struct device_link *link;
+
+	if (WARN_ON(consumer == supplier))
+		return;
+
+	device_links_write_lock();
+	device_pm_lock();
+
+	list_for_each_entry(link, &supplier->links.consumers, s_node) {
+		if (link->consumer == consumer) {
+			kref_put(&link->kref, __device_link_del);
+			break;
+		}
+	}
+
+	device_pm_unlock();
+	device_links_write_unlock();
+}
+EXPORT_SYMBOL_GPL(device_link_remove);
+
 static void device_links_missing_supplier(struct device *dev)
 {
 	struct device_link *link;
diff --git a/include/linux/device.h b/include/linux/device.h
index 055a69d..9c1c3b1 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1316,6 +1316,7 @@ extern void devm_device_remove_group(struct device *dev,
 struct device_link *device_link_add(struct device *consumer,
 				    struct device *supplier, u32 flags);
 void device_link_del(struct device_link *link);
+void device_link_remove(void *consumer, struct device *supplier);
 
 #ifdef CONFIG_PRINTK
 
-- 
1.9.1

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

* [PATCH 3/3] regulator: core: Change suspend_late to suspend
  2018-07-05 14:25 [PATCH 0/3] link regulator consumer with driver Pascal PAILLET-LME
  2018-07-05 14:25 ` [PATCH 1/3] driver core: Add device_link_remove function Pascal PAILLET-LME
  2018-07-05 14:25 ` [PATCH 2/3] regulator: core: Link consumer with regulator driver Pascal PAILLET-LME
@ 2018-07-05 14:25 ` Pascal PAILLET-LME
  2018-07-05 17:08   ` Applied "regulator: core: Change suspend_late to suspend" to the regulator tree Mark Brown
  2 siblings, 1 reply; 13+ messages in thread
From: Pascal PAILLET-LME @ 2018-07-05 14:25 UTC (permalink / raw)
  To: gregkh, lgirdwood, broonie, linux-kernel, benjamin.gaignard
  Cc: Pascal PAILLET-LME

From: pascal paillet <p.paillet@st.com>

Change suspend_late ops to suspend normal ops. The goal is to avoid
requesting all the regulator drivers to be operational in suspend late
phase.

Signed-off-by: pascal paillet <p.paillet@st.com>
---
 drivers/regulator/core.c         | 26 +++++++++++++-------------
 include/linux/regulator/driver.h |  2 +-
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 607ec47..bb1324f 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -4455,7 +4455,7 @@ void regulator_unregister(struct regulator_dev *rdev)
 EXPORT_SYMBOL_GPL(regulator_unregister);
 
 #ifdef CONFIG_SUSPEND
-static int _regulator_suspend_late(struct device *dev, void *data)
+static int _regulator_suspend(struct device *dev, void *data)
 {
 	struct regulator_dev *rdev = dev_to_rdev(dev);
 	suspend_state_t *state = data;
@@ -4469,20 +4469,20 @@ static int _regulator_suspend_late(struct device *dev, void *data)
 }
 
 /**
- * regulator_suspend_late - prepare regulators for system wide suspend
+ * regulator_suspend - prepare regulators for system wide suspend
  * @state: system suspend state
  *
  * Configure each regulator with it's suspend operating parameters for state.
  */
-static int regulator_suspend_late(struct device *dev)
+static int regulator_suspend(struct device *dev)
 {
 	suspend_state_t state = pm_suspend_target_state;
 
 	return class_for_each_device(&regulator_class, NULL, &state,
-				     _regulator_suspend_late);
+				     _regulator_suspend);
 }
 
-static int _regulator_resume_early(struct device *dev, void *data)
+static int _regulator_resume(struct device *dev, void *data)
 {
 	int ret = 0;
 	struct regulator_dev *rdev = dev_to_rdev(dev);
@@ -4495,35 +4495,35 @@ static int _regulator_resume_early(struct device *dev, void *data)
 
 	regulator_lock(rdev);
 
-	if (rdev->desc->ops->resume_early &&
+	if (rdev->desc->ops->resume &&
 	    (rstate->enabled == ENABLE_IN_SUSPEND ||
 	     rstate->enabled == DISABLE_IN_SUSPEND))
-		ret = rdev->desc->ops->resume_early(rdev);
+		ret = rdev->desc->ops->resume(rdev);
 
 	regulator_unlock(rdev);
 
 	return ret;
 }
 
-static int regulator_resume_early(struct device *dev)
+static int regulator_resume(struct device *dev)
 {
 	suspend_state_t state = pm_suspend_target_state;
 
 	return class_for_each_device(&regulator_class, NULL, &state,
-				     _regulator_resume_early);
+				     _regulator_resume);
 }
 
 #else /* !CONFIG_SUSPEND */
 
-#define regulator_suspend_late	NULL
-#define regulator_resume_early	NULL
+#define regulator_suspend	NULL
+#define regulator_resume	NULL
 
 #endif /* !CONFIG_SUSPEND */
 
 #ifdef CONFIG_PM
 static const struct dev_pm_ops __maybe_unused regulator_pm_ops = {
-	.suspend_late	= regulator_suspend_late,
-	.resume_early	= regulator_resume_early,
+	.suspend	= regulator_suspend,
+	.resume		= regulator_resume,
 };
 #endif
 
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index fc2dc8d..3a0302b 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -220,7 +220,7 @@ struct regulator_ops {
 	/* set regulator suspend operating mode (defined in consumer.h) */
 	int (*set_suspend_mode) (struct regulator_dev *, unsigned int mode);
 
-	int (*resume_early)(struct regulator_dev *rdev);
+	int (*resume)(struct regulator_dev *rdev);
 
 	int (*set_pull_down) (struct regulator_dev *);
 };
-- 
1.9.1

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

* Re: [PATCH 2/3] regulator: core: Link consumer with regulator driver
  2018-07-05 14:25 ` [PATCH 2/3] regulator: core: Link consumer with regulator driver Pascal PAILLET-LME
@ 2018-07-05 16:53   ` Mark Brown
  2018-07-05 17:53     ` gregkh
  2018-07-05 17:55   ` Applied "regulator: core: Link consumer with regulator driver" to the regulator tree Mark Brown
  1 sibling, 1 reply; 13+ messages in thread
From: Mark Brown @ 2018-07-05 16:53 UTC (permalink / raw)
  To: Pascal PAILLET-LME, gregkh; +Cc: lgirdwood, linux-kernel, benjamin.gaignard

[-- Attachment #1: Type: text/plain, Size: 474 bytes --]

On Thu, Jul 05, 2018 at 02:25:56PM +0000, Pascal PAILLET-LME wrote:
> From: pascal paillet <p.paillet@st.com>
> 
> Add a device link between the consumer and the driver so that
> the consumer is not suspended before the driver. The goal is to avoid
> implementing suspend_late ops in regulator drivers.

This looks good but I'll wait for Greg's review of the link
functionality - Greg, is it OK to apply this via the regulator tree or
do you want a shared branch?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 1/3] driver core: Add device_link_remove function
  2018-07-05 14:25 ` [PATCH 1/3] driver core: Add device_link_remove function Pascal PAILLET-LME
@ 2018-07-05 16:54   ` Mark Brown
  2018-07-05 17:55   ` Applied "driver core: Add device_link_remove function" to the regulator tree Mark Brown
  1 sibling, 0 replies; 13+ messages in thread
From: Mark Brown @ 2018-07-05 16:54 UTC (permalink / raw)
  To: Pascal PAILLET-LME; +Cc: gregkh, lgirdwood, linux-kernel, benjamin.gaignard

[-- Attachment #1: Type: text/plain, Size: 281 bytes --]

On Thu, Jul 05, 2018 at 02:25:56PM +0000, Pascal PAILLET-LME wrote:
> From: pascal paillet <p.paillet@st.com>
> 
> Device_link_remove uses the same arguments than device_link_add. The Goal
> is to avoid storing the link pointer.

Reviwed-by: Mark Brown <broonie@kernel.org>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Applied "regulator: core: Change suspend_late to suspend" to the regulator tree
  2018-07-05 14:25 ` [PATCH 3/3] regulator: core: Change suspend_late to suspend Pascal PAILLET-LME
@ 2018-07-05 17:08   ` Mark Brown
  0 siblings, 0 replies; 13+ messages in thread
From: Mark Brown @ 2018-07-05 17:08 UTC (permalink / raw)
  To: pascal paillet
  Cc: Mark Brown, gregkh, lgirdwood, broonie, linux-kernel,
	benjamin.gaignard, Pascal PAILLET-LME, linux-kernel

The patch

   regulator: core: Change suspend_late to suspend

has been applied to the regulator tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

From 0380cf7dbaca75c524e34b30979f0806124fa8e6 Mon Sep 17 00:00:00 2001
From: pascal paillet <p.paillet@st.com>
Date: Thu, 5 Jul 2018 14:25:57 +0000
Subject: [PATCH] regulator: core: Change suspend_late to suspend

Change suspend_late ops to suspend normal ops. The goal is to avoid
requesting all the regulator drivers to be operational in suspend late
phase.

Signed-off-by: pascal paillet <p.paillet@st.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 drivers/regulator/core.c         | 26 +++++++++++++-------------
 include/linux/regulator/driver.h |  2 +-
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 6ed568b96c0e..da9b0fed8330 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -4441,7 +4441,7 @@ void regulator_unregister(struct regulator_dev *rdev)
 EXPORT_SYMBOL_GPL(regulator_unregister);
 
 #ifdef CONFIG_SUSPEND
-static int _regulator_suspend_late(struct device *dev, void *data)
+static int _regulator_suspend(struct device *dev, void *data)
 {
 	struct regulator_dev *rdev = dev_to_rdev(dev);
 	suspend_state_t *state = data;
@@ -4455,20 +4455,20 @@ static int _regulator_suspend_late(struct device *dev, void *data)
 }
 
 /**
- * regulator_suspend_late - prepare regulators for system wide suspend
+ * regulator_suspend - prepare regulators for system wide suspend
  * @state: system suspend state
  *
  * Configure each regulator with it's suspend operating parameters for state.
  */
-static int regulator_suspend_late(struct device *dev)
+static int regulator_suspend(struct device *dev)
 {
 	suspend_state_t state = pm_suspend_target_state;
 
 	return class_for_each_device(&regulator_class, NULL, &state,
-				     _regulator_suspend_late);
+				     _regulator_suspend);
 }
 
-static int _regulator_resume_early(struct device *dev, void *data)
+static int _regulator_resume(struct device *dev, void *data)
 {
 	int ret = 0;
 	struct regulator_dev *rdev = dev_to_rdev(dev);
@@ -4481,35 +4481,35 @@ static int _regulator_resume_early(struct device *dev, void *data)
 
 	regulator_lock(rdev);
 
-	if (rdev->desc->ops->resume_early &&
+	if (rdev->desc->ops->resume &&
 	    (rstate->enabled == ENABLE_IN_SUSPEND ||
 	     rstate->enabled == DISABLE_IN_SUSPEND))
-		ret = rdev->desc->ops->resume_early(rdev);
+		ret = rdev->desc->ops->resume(rdev);
 
 	regulator_unlock(rdev);
 
 	return ret;
 }
 
-static int regulator_resume_early(struct device *dev)
+static int regulator_resume(struct device *dev)
 {
 	suspend_state_t state = pm_suspend_target_state;
 
 	return class_for_each_device(&regulator_class, NULL, &state,
-				     _regulator_resume_early);
+				     _regulator_resume);
 }
 
 #else /* !CONFIG_SUSPEND */
 
-#define regulator_suspend_late	NULL
-#define regulator_resume_early	NULL
+#define regulator_suspend	NULL
+#define regulator_resume	NULL
 
 #endif /* !CONFIG_SUSPEND */
 
 #ifdef CONFIG_PM
 static const struct dev_pm_ops __maybe_unused regulator_pm_ops = {
-	.suspend_late	= regulator_suspend_late,
-	.resume_early	= regulator_resume_early,
+	.suspend	= regulator_suspend,
+	.resume		= regulator_resume,
 };
 #endif
 
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index dea96ee39fdc..0fd8fbb74763 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -220,7 +220,7 @@ struct regulator_ops {
 	/* set regulator suspend operating mode (defined in consumer.h) */
 	int (*set_suspend_mode) (struct regulator_dev *, unsigned int mode);
 
-	int (*resume_early)(struct regulator_dev *rdev);
+	int (*resume)(struct regulator_dev *rdev);
 
 	int (*set_pull_down) (struct regulator_dev *);
 };
-- 
2.18.0.rc2


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

* Re: [PATCH 2/3] regulator: core: Link consumer with regulator driver
  2018-07-05 16:53   ` Mark Brown
@ 2018-07-05 17:53     ` gregkh
  0 siblings, 0 replies; 13+ messages in thread
From: gregkh @ 2018-07-05 17:53 UTC (permalink / raw)
  To: Mark Brown; +Cc: Pascal PAILLET-LME, lgirdwood, linux-kernel, benjamin.gaignard

On Thu, Jul 05, 2018 at 05:53:51PM +0100, Mark Brown wrote:
> On Thu, Jul 05, 2018 at 02:25:56PM +0000, Pascal PAILLET-LME wrote:
> > From: pascal paillet <p.paillet@st.com>
> > 
> > Add a device link between the consumer and the driver so that
> > the consumer is not suspended before the driver. The goal is to avoid
> > implementing suspend_late ops in regulator drivers.
> 
> This looks good but I'll wait for Greg's review of the link
> functionality - Greg, is it OK to apply this via the regulator tree or
> do you want a shared branch?

You can take it through the regulator tree, no objection from me:
	Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

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

* Applied "regulator: core: Link consumer with regulator driver" to the regulator tree
  2018-07-05 14:25 ` [PATCH 2/3] regulator: core: Link consumer with regulator driver Pascal PAILLET-LME
  2018-07-05 16:53   ` Mark Brown
@ 2018-07-05 17:55   ` Mark Brown
       [not found]     ` <CGME20180709111753eucas1p1f32e66fb2f7ea3216097cd72a132355d@eucas1p1.samsung.com>
  1 sibling, 1 reply; 13+ messages in thread
From: Mark Brown @ 2018-07-05 17:55 UTC (permalink / raw)
  To: pascal paillet
  Cc: Mark Brown, gregkh, lgirdwood, broonie, linux-kernel,
	benjamin.gaignard, Pascal PAILLET-LME, linux-kernel

The patch

   regulator: core: Link consumer with regulator driver

has been applied to the regulator tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

From ed1ae2dd9f242c7a36e8e39100f6a7f6bcdfdd89 Mon Sep 17 00:00:00 2001
From: pascal paillet <p.paillet@st.com>
Date: Thu, 5 Jul 2018 14:25:56 +0000
Subject: [PATCH] regulator: core: Link consumer with regulator driver

Add a device link between the consumer and the driver so that
the consumer is not suspended before the driver. The goal is to avoid
implementing suspend_late ops in regulator drivers.

Signed-off-by: pascal paillet <p.paillet@st.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 drivers/regulator/core.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index da9b0fed8330..bb1324f93143 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1740,6 +1740,8 @@ struct regulator *_regulator_get(struct device *dev, const char *id,
 			rdev->use_count = 0;
 	}
 
+	device_link_add(dev, &rdev->dev, DL_FLAG_STATELESS);
+
 	return regulator;
 }
 
@@ -1829,9 +1831,21 @@ static void _regulator_put(struct regulator *regulator)
 
 	debugfs_remove_recursive(regulator->debugfs);
 
-	/* remove any sysfs entries */
-	if (regulator->dev)
+	if (regulator->dev) {
+		int count = 0;
+		struct regulator *r;
+
+		list_for_each_entry(r, &rdev->consumer_list, list)
+			if (r->dev == regulator->dev)
+				count++;
+
+		if (count == 1)
+			device_link_remove(regulator->dev, &rdev->dev);
+
+		/* remove any sysfs entries */
 		sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
+	}
+
 	regulator_lock(rdev);
 	list_del(&regulator->list);
 
-- 
2.18.0.rc2


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

* Applied "driver core: Add device_link_remove function" to the regulator tree
  2018-07-05 14:25 ` [PATCH 1/3] driver core: Add device_link_remove function Pascal PAILLET-LME
  2018-07-05 16:54   ` Mark Brown
@ 2018-07-05 17:55   ` Mark Brown
  1 sibling, 0 replies; 13+ messages in thread
From: Mark Brown @ 2018-07-05 17:55 UTC (permalink / raw)
  To: pascal paillet
  Cc: Greg Kroah-Hartman, Mark Brown, gregkh, lgirdwood, broonie,
	linux-kernel, benjamin.gaignard, Pascal PAILLET-LME,
	linux-kernel

The patch

   driver core: Add device_link_remove function

has been applied to the regulator tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

From d8842211b6f63d3f069df973d137de0a85964965 Mon Sep 17 00:00:00 2001
From: pascal paillet <p.paillet@st.com>
Date: Thu, 5 Jul 2018 14:25:56 +0000
Subject: [PATCH] driver core: Add device_link_remove function

Device_link_remove uses the same arguments than device_link_add. The Goal
is to avoid storing the link pointer.

Signed-off-by: pascal paillet <p.paillet@st.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 drivers/base/core.c    | 30 ++++++++++++++++++++++++++++++
 include/linux/device.h |  1 +
 2 files changed, 31 insertions(+)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index 36622b52e419..3b380b1f2768 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -365,6 +365,36 @@ void device_link_del(struct device_link *link)
 }
 EXPORT_SYMBOL_GPL(device_link_del);
 
+/**
+ * device_link_remove - remove a link between two devices.
+ * @consumer: Consumer end of the link.
+ * @supplier: Supplier end of the link.
+ *
+ * The caller must ensure proper synchronization of this function with runtime
+ * PM.
+ */
+void device_link_remove(void *consumer, struct device *supplier)
+{
+	struct device_link *link;
+
+	if (WARN_ON(consumer == supplier))
+		return;
+
+	device_links_write_lock();
+	device_pm_lock();
+
+	list_for_each_entry(link, &supplier->links.consumers, s_node) {
+		if (link->consumer == consumer) {
+			kref_put(&link->kref, __device_link_del);
+			break;
+		}
+	}
+
+	device_pm_unlock();
+	device_links_write_unlock();
+}
+EXPORT_SYMBOL_GPL(device_link_remove);
+
 static void device_links_missing_supplier(struct device *dev)
 {
 	struct device_link *link;
diff --git a/include/linux/device.h b/include/linux/device.h
index 055a69dbcd18..9c1c3b1d5e11 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1316,6 +1316,7 @@ extern const char *dev_driver_string(const struct device *dev);
 struct device_link *device_link_add(struct device *consumer,
 				    struct device *supplier, u32 flags);
 void device_link_del(struct device_link *link);
+void device_link_remove(void *consumer, struct device *supplier);
 
 #ifdef CONFIG_PRINTK
 
-- 
2.18.0.rc2


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

* Re: Applied "regulator: core: Link consumer with regulator driver" to the regulator tree
       [not found]     ` <CGME20180709111753eucas1p1f32e66fb2f7ea3216097cd72a132355d@eucas1p1.samsung.com>
@ 2018-07-09 11:17       ` Marek Szyprowski
  2018-07-09 12:13         ` Benjamin Gaignard
  0 siblings, 1 reply; 13+ messages in thread
From: Marek Szyprowski @ 2018-07-09 11:17 UTC (permalink / raw)
  To: Mark Brown, pascal paillet
  Cc: gregkh, lgirdwood, linux-kernel, benjamin.gaignard,
	Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz

Dear All,

On 2018-07-05 19:55, Mark Brown wrote:
> The patch
>
>     regulator: core: Link consumer with regulator driver
>
> has been applied to the regulator tree at
>
>     https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git
>
> All being well this means that it will be integrated into the linux-next
> tree (usually sometime in the next 24 hours) and sent to Linus during
> the next merge window (or sooner if it is a bug fix), however if
> problems are discovered then the patch may be dropped or reverted.
>
> You may get further e-mails resulting from automated or manual testing
> and review of the tree, please engage with people reporting problems and
> send followup patches addressing any issues that are reported if needed.
>
> If any updates are required or you are submitting further changes they
> should be sent as incremental updates against current git, existing
> patches will not be replaced.
>
> Please add any relevant lists and maintainers to the CCs when replying
> to this mail.
>
> Thanks,
> Mark
>
> >From ed1ae2dd9f242c7a36e8e39100f6a7f6bcdfdd89 Mon Sep 17 00:00:00 2001
> From: pascal paillet <p.paillet@st.com>
> Date: Thu, 5 Jul 2018 14:25:56 +0000
> Subject: [PATCH] regulator: core: Link consumer with regulator driver
>
> Add a device link between the consumer and the driver so that
> the consumer is not suspended before the driver. The goal is to avoid
> implementing suspend_late ops in regulator drivers.
>
> Signed-off-by: pascal paillet <p.paillet@st.com>
> Signed-off-by: Mark Brown <broonie@kernel.org>

This patch triggers the following warning on several Exynos SoC based 
boards:

------------[ cut here ]------------
WARNING: CPU: 1 PID: 1 at drivers/base/core.c:108 
device_is_dependent+0xa4/0xb4
Modules linked in:
CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.18.0-rc3-next-20180706 #112
Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[<c0113200>] (unwind_backtrace) from [<c010edd0>] (show_stack+0x10/0x14)
[<c010edd0>] (show_stack) from [<c0a4b6e8>] (dump_stack+0x98/0xc4)
[<c0a4b6e8>] (dump_stack) from [<c0127b90>] (__warn+0x10c/0x124)
[<c0127b90>] (__warn) from [<c0127cbc>] (warn_slowpath_null+0x40/0x48)
[<c0127cbc>] (warn_slowpath_null) from [<c0580464>] 
(device_is_dependent+0xa4/0xb4)
[<c0580464>] (device_is_dependent) from [<c058037c>] 
(device_for_each_child+0x50/0x94)
[<c058037c>] (device_for_each_child) from [<c05803e0>] 
(device_is_dependent+0x20/0xb4)
[<c05803e0>] (device_is_dependent) from [<c0581bcc>] 
(device_link_add+0x70/0x2a8)
[<c0581bcc>] (device_link_add) from [<c04e4134>] (_regulator_get+0xbc/0x270)
[<c04e4134>] (_regulator_get) from [<c04e4350>] 
(regulator_bulk_get+0x60/0xcc)
[<c04e4350>] (regulator_bulk_get) from [<c05b4e40>] 
(wm8994_i2c_probe+0x334/0x8ec)
[<c05b4e40>] (wm8994_i2c_probe) from [<c06d8d98>] 
(i2c_device_probe+0x240/0x2b8)
[<c06d8d98>] (i2c_device_probe) from [<c05857d8>] 
(driver_probe_device+0x2dc/0x4ac)
[<c05857d8>] (driver_probe_device) from [<c0585ad0>] 
(__driver_attach+0x128/0x144)
[<c0585ad0>] (__driver_attach) from [<c0583668>] 
(bus_for_each_dev+0x68/0xb4)
[<c0583668>] (bus_for_each_dev) from [<c0584968>] 
(bus_add_driver+0x1a8/0x268)
[<c0584968>] (bus_add_driver) from [<c0586c48>] (driver_register+0x78/0x10c)
[<c0586c48>] (driver_register) from [<c06d9ca4>] 
(i2c_register_driver+0x3c/0xa8)
[<c06d9ca4>] (i2c_register_driver) from [<c0103188>] 
(do_one_initcall+0x8c/0x4b0)
[<c0103188>] (do_one_initcall) from [<c0f01268>] 
(kernel_init_freeable+0x3e4/0x570)
[<c0f01268>] (kernel_init_freeable) from [<c0a6503c>] 
(kernel_init+0x8/0x10c)
[<c0a6503c>] (kernel_init) from [<c01010b4>] (ret_from_fork+0x14/0x20)
Exception stack(0xee8c9fb0 to 0xee8c9ff8)
...
---[ end trace 4ed89cca1d70ea82 ]---

The above stack comes from Exynos5250 Arndale board
(arch/arm/boot/dts/exynos5250-arndale.dts), where wm8994 codec tries to get
regulator, which is provided by its parent mfd device. Similar issue can be
observed on Exynos4412-based Trats2 and Exynos5433 TM2(e) boards.

It looks that some more checks have to be done before adding a link between
regulator consumer and regulator driver, because it is not that uncommon 
that
regulator consumer shares the parent device with regulator provider.

> ---
>   drivers/regulator/core.c | 18 ++++++++++++++++--
>   1 file changed, 16 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
> index da9b0fed8330..bb1324f93143 100644
> --- a/drivers/regulator/core.c
> +++ b/drivers/regulator/core.c
> @@ -1740,6 +1740,8 @@ struct regulator *_regulator_get(struct device *dev, const char *id,
>   			rdev->use_count = 0;
>   	}
>   
> +	device_link_add(dev, &rdev->dev, DL_FLAG_STATELESS);
> +
>   	return regulator;
>   }
>   
> @@ -1829,9 +1831,21 @@ static void _regulator_put(struct regulator *regulator)
>   
>   	debugfs_remove_recursive(regulator->debugfs);
>   
> -	/* remove any sysfs entries */
> -	if (regulator->dev)
> +	if (regulator->dev) {
> +		int count = 0;
> +		struct regulator *r;
> +
> +		list_for_each_entry(r, &rdev->consumer_list, list)
> +			if (r->dev == regulator->dev)
> +				count++;
> +
> +		if (count == 1)
> +			device_link_remove(regulator->dev, &rdev->dev);
> +
> +		/* remove any sysfs entries */
>   		sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
> +	}
> +
>   	regulator_lock(rdev);
>   	list_del(&regulator->list);
>   

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


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

* Re: Applied "regulator: core: Link consumer with regulator driver" to the regulator tree
  2018-07-09 11:17       ` Marek Szyprowski
@ 2018-07-09 12:13         ` Benjamin Gaignard
  2018-07-09 12:26           ` Mark Brown
  0 siblings, 1 reply; 13+ messages in thread
From: Benjamin Gaignard @ 2018-07-09 12:13 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Mark Brown, pascal paillet, gregkh, lgirdwood, linux-kernel,
	Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz, rafael.j.wysocki

+ Rafael

2018-07-09 13:17 GMT+02:00 Marek Szyprowski <m.szyprowski@samsung.com>:
> Dear All,
>
> On 2018-07-05 19:55, Mark Brown wrote:
>> The patch
>>
>>     regulator: core: Link consumer with regulator driver
>>
>> has been applied to the regulator tree at
>>
>>     https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git
>>
>> All being well this means that it will be integrated into the linux-next
>> tree (usually sometime in the next 24 hours) and sent to Linus during
>> the next merge window (or sooner if it is a bug fix), however if
>> problems are discovered then the patch may be dropped or reverted.
>>
>> You may get further e-mails resulting from automated or manual testing
>> and review of the tree, please engage with people reporting problems and
>> send followup patches addressing any issues that are reported if needed.
>>
>> If any updates are required or you are submitting further changes they
>> should be sent as incremental updates against current git, existing
>> patches will not be replaced.
>>
>> Please add any relevant lists and maintainers to the CCs when replying
>> to this mail.
>>
>> Thanks,
>> Mark
>>
>> >From ed1ae2dd9f242c7a36e8e39100f6a7f6bcdfdd89 Mon Sep 17 00:00:00 2001
>> From: pascal paillet <p.paillet@st.com>
>> Date: Thu, 5 Jul 2018 14:25:56 +0000
>> Subject: [PATCH] regulator: core: Link consumer with regulator driver
>>
>> Add a device link between the consumer and the driver so that
>> the consumer is not suspended before the driver. The goal is to avoid
>> implementing suspend_late ops in regulator drivers.
>>
>> Signed-off-by: pascal paillet <p.paillet@st.com>
>> Signed-off-by: Mark Brown <broonie@kernel.org>
>
> This patch triggers the following warning on several Exynos SoC based
> boards:
>
> ------------[ cut here ]------------
> WARNING: CPU: 1 PID: 1 at drivers/base/core.c:108
> device_is_dependent+0xa4/0xb4
> Modules linked in:
> CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.18.0-rc3-next-20180706 #112
> Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
> [<c0113200>] (unwind_backtrace) from [<c010edd0>] (show_stack+0x10/0x14)
> [<c010edd0>] (show_stack) from [<c0a4b6e8>] (dump_stack+0x98/0xc4)
> [<c0a4b6e8>] (dump_stack) from [<c0127b90>] (__warn+0x10c/0x124)
> [<c0127b90>] (__warn) from [<c0127cbc>] (warn_slowpath_null+0x40/0x48)
> [<c0127cbc>] (warn_slowpath_null) from [<c0580464>]
> (device_is_dependent+0xa4/0xb4)
> [<c0580464>] (device_is_dependent) from [<c058037c>]
> (device_for_each_child+0x50/0x94)
> [<c058037c>] (device_for_each_child) from [<c05803e0>]
> (device_is_dependent+0x20/0xb4)
> [<c05803e0>] (device_is_dependent) from [<c0581bcc>]
> (device_link_add+0x70/0x2a8)
> [<c0581bcc>] (device_link_add) from [<c04e4134>] (_regulator_get+0xbc/0x270)
> [<c04e4134>] (_regulator_get) from [<c04e4350>]
> (regulator_bulk_get+0x60/0xcc)
> [<c04e4350>] (regulator_bulk_get) from [<c05b4e40>]
> (wm8994_i2c_probe+0x334/0x8ec)
> [<c05b4e40>] (wm8994_i2c_probe) from [<c06d8d98>]
> (i2c_device_probe+0x240/0x2b8)
> [<c06d8d98>] (i2c_device_probe) from [<c05857d8>]
> (driver_probe_device+0x2dc/0x4ac)
> [<c05857d8>] (driver_probe_device) from [<c0585ad0>]
> (__driver_attach+0x128/0x144)
> [<c0585ad0>] (__driver_attach) from [<c0583668>]
> (bus_for_each_dev+0x68/0xb4)
> [<c0583668>] (bus_for_each_dev) from [<c0584968>]
> (bus_add_driver+0x1a8/0x268)
> [<c0584968>] (bus_add_driver) from [<c0586c48>] (driver_register+0x78/0x10c)
> [<c0586c48>] (driver_register) from [<c06d9ca4>]
> (i2c_register_driver+0x3c/0xa8)
> [<c06d9ca4>] (i2c_register_driver) from [<c0103188>]
> (do_one_initcall+0x8c/0x4b0)
> [<c0103188>] (do_one_initcall) from [<c0f01268>]
> (kernel_init_freeable+0x3e4/0x570)
> [<c0f01268>] (kernel_init_freeable) from [<c0a6503c>]
> (kernel_init+0x8/0x10c)
> [<c0a6503c>] (kernel_init) from [<c01010b4>] (ret_from_fork+0x14/0x20)
> Exception stack(0xee8c9fb0 to 0xee8c9ff8)
> ...
> ---[ end trace 4ed89cca1d70ea82 ]---
>
> The above stack comes from Exynos5250 Arndale board
> (arch/arm/boot/dts/exynos5250-arndale.dts), where wm8994 codec tries to get
> regulator, which is provided by its parent mfd device. Similar issue can be
> observed on Exynos4412-based Trats2 and Exynos5433 TM2(e) boards.
>
> It looks that some more checks have to be done before adding a link between
> regulator consumer and regulator driver, because it is not that uncommon
> that
> regulator consumer shares the parent device with regulator provider.
>

Each time device_is_dependent() will return 1 we have a warn_on.
It is strange since returning 1 is well documented on function description.
I don't know if we can safely remove the warn_on or if their is a good
reason to keep it.
Rafael what do you think about that ?

>> ---
>>   drivers/regulator/core.c | 18 ++++++++++++++++--
>>   1 file changed, 16 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
>> index da9b0fed8330..bb1324f93143 100644
>> --- a/drivers/regulator/core.c
>> +++ b/drivers/regulator/core.c
>> @@ -1740,6 +1740,8 @@ struct regulator *_regulator_get(struct device *dev, const char *id,
>>                       rdev->use_count = 0;
>>       }
>>
>> +     device_link_add(dev, &rdev->dev, DL_FLAG_STATELESS);
>> +
>>       return regulator;
>>   }
>>
>> @@ -1829,9 +1831,21 @@ static void _regulator_put(struct regulator *regulator)
>>
>>       debugfs_remove_recursive(regulator->debugfs);
>>
>> -     /* remove any sysfs entries */
>> -     if (regulator->dev)
>> +     if (regulator->dev) {
>> +             int count = 0;
>> +             struct regulator *r;
>> +
>> +             list_for_each_entry(r, &rdev->consumer_list, list)
>> +                     if (r->dev == regulator->dev)
>> +                             count++;
>> +
>> +             if (count == 1)
>> +                     device_link_remove(regulator->dev, &rdev->dev);
>> +
>> +             /* remove any sysfs entries */
>>               sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
>> +     }
>> +
>>       regulator_lock(rdev);
>>       list_del(&regulator->list);
>>
>
> Best regards
> --
> Marek Szyprowski, PhD
> Samsung R&D Institute Poland
>



-- 
Benjamin Gaignard

Graphic Study Group

Linaro.org │ Open source software for ARM SoCs

Follow Linaro: Facebook | Twitter | Blog

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

* Re: Applied "regulator: core: Link consumer with regulator driver" to the regulator tree
  2018-07-09 12:13         ` Benjamin Gaignard
@ 2018-07-09 12:26           ` Mark Brown
  0 siblings, 0 replies; 13+ messages in thread
From: Mark Brown @ 2018-07-09 12:26 UTC (permalink / raw)
  To: Benjamin Gaignard
  Cc: Marek Szyprowski, pascal paillet, gregkh, lgirdwood,
	linux-kernel, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	rafael.j.wysocki

[-- Attachment #1: Type: text/plain, Size: 1205 bytes --]

On Mon, Jul 09, 2018 at 02:13:35PM +0200, Benjamin Gaignard wrote:
> 2018-07-09 13:17 GMT+02:00 Marek Szyprowski <m.szyprowski@samsung.com>:

> > ------------[ cut here ]------------
> > WARNING: CPU: 1 PID: 1 at drivers/base/core.c:108
> > device_is_dependent+0xa4/0xb4
> > Modules linked in:
> > CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.18.0-rc3-next-20180706 #112

> > It looks that some more checks have to be done before adding a link between
> > regulator consumer and regulator driver, because it is not that uncommon
> > that
> > regulator consumer shares the parent device with regulator provider.

> Each time device_is_dependent() will return 1 we have a warn_on.
> It is strange since returning 1 is well documented on function description.
> I don't know if we can safely remove the warn_on or if their is a good
> reason to keep it.
> Rafael what do you think about that ?

It's trying to tell you that there's probably a higher level bug if
you're adding a link from a device to itself.  That's not super
unreasonable, though it is going to mean that every bit of generic code
like this adding links is going to have to add checks (or we have to
downgrade or make optional the WARN_ON).

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

end of thread, other threads:[~2018-07-09 12:26 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-05 14:25 [PATCH 0/3] link regulator consumer with driver Pascal PAILLET-LME
2018-07-05 14:25 ` [PATCH 1/3] driver core: Add device_link_remove function Pascal PAILLET-LME
2018-07-05 16:54   ` Mark Brown
2018-07-05 17:55   ` Applied "driver core: Add device_link_remove function" to the regulator tree Mark Brown
2018-07-05 14:25 ` [PATCH 2/3] regulator: core: Link consumer with regulator driver Pascal PAILLET-LME
2018-07-05 16:53   ` Mark Brown
2018-07-05 17:53     ` gregkh
2018-07-05 17:55   ` Applied "regulator: core: Link consumer with regulator driver" to the regulator tree Mark Brown
     [not found]     ` <CGME20180709111753eucas1p1f32e66fb2f7ea3216097cd72a132355d@eucas1p1.samsung.com>
2018-07-09 11:17       ` Marek Szyprowski
2018-07-09 12:13         ` Benjamin Gaignard
2018-07-09 12:26           ` Mark Brown
2018-07-05 14:25 ` [PATCH 3/3] regulator: core: Change suspend_late to suspend Pascal PAILLET-LME
2018-07-05 17:08   ` Applied "regulator: core: Change suspend_late to suspend" to the regulator tree Mark Brown

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.