mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v9 0/4] lan966x pci device: Add support for SFPs, simple-bus part
@ 2026-11-09 14:08 Herve Codina
  2026-11-09 14:08 ` [PATCH v9 1/4] bus: simple-pm-bus: Avoid inconsistencies between probe() and remove() Herve Codina
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Herve Codina @ 2026-11-09 14:08 UTC (permalink / raw)
  To: Andrew Lunn, Rob Herring, Saravana Kannan, Geert Uytterhoeven,
	Kalle Niemi, Matti Vaittinen, Greg Kroah-Hartman,
	Rafael J. Wysocki, Danilo Krummrich, Johan Hovold
  Cc: driver-core, devicetree, linux-kernel, Allan Nielsen,
	Horatiu Vultur, Daniel Machon, Steen Hegelund, Luca Ceresoli,
	Thomas Petazzoni, Herve Codina

Hi,

Previously, I sent a big picture series adding support for SFP ports
available on the LAN966x PCI device [0].

In this series patches touch several parts and sub-system in the kernel.
Reviews have be done and it makes sense to split the series and send
parts separately.

This current series is the extraction of patches related to the
simple-bus driver. It has to be seen as a continuation of the big
picture series but related to this specific simple-bus part.

Patch 1 fixes an already existing issue reported by Sashiko.
Patch 2 removes the no more useful remove() function.

Patch 3 depopulates devices populated at probe() when the driver is
unbound.

Patch 4 makes the simple-bus driver compatible with fw_devlink
expectation consisting in creating its child devices at probe.

[0] https://lore.kernel.org/all/20260325143555.451852-1-herve.codina@bootlin.com/

Best regards,
Hervé

Changes:

v8 -> v9
  v8: https://lore.kernel.org/all/20260630102717.413501-1-herve.codina@bootlin.com/

  Rebase on top of v7.4-rc1

  - Patch 1 (new patch in v9)
    Fix an issue reported by Sashiko related to possible inconsistencies
    between operations done at probe() and the ones done at remove().

  - Patch 2 (new patch in v9)
    Fully remove the remove() function.

  - Patch 3
    Changed the way depopulate is performed and use devres feature.
    Took into account a pm_runtime possible issue (reported by Sashiko)
    related to async pm_request_idle() triggered when all child devices
    are removed from the bus.

  - Patch 4
    Use devres feature.

v7 -> v8
  v7: https://lore.kernel.org/all/20260511155902.34534-1-herve.codina@bootlin.com/

  Rebase on top of v7.2-rc1
  No nother changes

v6 -> v7

  Rebase on top of v7.1-rc1

  - Patch 1
    No changes

  - Patch 2
    Fix conflict due to device_has_driver_override() introduction.

Older iterations:
  Patches 4 and 5 in the big picture series
  https://lore.kernel.org/all/20260325143555.451852-1-herve.codina@bootlin.com/

Herve Codina (4):
  bus: simple-pm-bus: Avoid inconsistencies between probe() and remove()
  bus: simple-pm-bus: Remove the remove() function
  bus: simple-pm-bus: Remove child devices when the bus is unbound
  bus: simple-pm-bus: Populate child nodes at probe

 drivers/bus/simple-pm-bus.c | 90 +++++++++++++++++++++++++++----------
 1 file changed, 67 insertions(+), 23 deletions(-)

-- 
2.56.0


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

* [PATCH v9 1/4] bus: simple-pm-bus: Avoid inconsistencies between probe() and remove()
  2026-11-09 14:08 [PATCH v9 0/4] lan966x pci device: Add support for SFPs, simple-bus part Herve Codina
@ 2026-11-09 14:08 ` Herve Codina
  2026-11-09 14:08 ` [PATCH v9 2/4] bus: simple-pm-bus: Remove the remove() function Herve Codina
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Herve Codina @ 2026-11-09 14:08 UTC (permalink / raw)
  To: Andrew Lunn, Rob Herring, Saravana Kannan, Geert Uytterhoeven,
	Kalle Niemi, Matti Vaittinen, Greg Kroah-Hartman,
	Rafael J. Wysocki, Danilo Krummrich, Johan Hovold
  Cc: driver-core, devicetree, linux-kernel, Allan Nielsen,
	Horatiu Vultur, Daniel Machon, Steen Hegelund, Luca Ceresoli,
	Thomas Petazzoni, Herve Codina, Sashiko, stable

At probe(), operations done depends on device_has_driver_override().

At remove() a call to device_has_driver_override() is also present to
identify operations that need to be done in order to revert operations
previously done at probe().

Nothing prevents device_has_driver_override() to return a different
value when called at probe() and when called at remove(). Indeed, a user
can set driver_override (or clear it) after the probe() call and before
the remove() call.

In that case, inconsistencies are present between pm_runtime_enable()
called at probe() and pm_runtime_disable() called at remove().

In order to ensure that pm_runtime_disable() is called only if
pm_runtime_enable() has been called at probe(), use the devres version
of pm_runtime_enable().

Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://lore.kernel.org/all/20260630105701.7D0471F00A3A@smtp.kernel.org/
Fixes: 98e96cf80045 ("drivers: bus: simple-pm-bus: Add support for probing simple bus only devices")
Cc: stable@vger.kernel.org
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
 drivers/bus/simple-pm-bus.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/bus/simple-pm-bus.c b/drivers/bus/simple-pm-bus.c
index c920bd6fbaaf..4322a778e801 100644
--- a/drivers/bus/simple-pm-bus.c
+++ b/drivers/bus/simple-pm-bus.c
@@ -29,6 +29,7 @@ static int simple_pm_bus_probe(struct platform_device *pdev)
 	struct device_node *np = dev->of_node;
 	const struct of_device_id *match;
 	struct simple_pm_bus *bus;
+	int ret;
 
 	/*
 	 * Allow user to use driver_override to bind this driver to a
@@ -66,7 +67,9 @@ static int simple_pm_bus_probe(struct platform_device *pdev)
 
 	dev_dbg(&pdev->dev, "%s\n", __func__);
 
-	pm_runtime_enable(&pdev->dev);
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "failed enable pm_runtime\n");
 
 	if (np)
 		of_platform_populate(np, NULL, lookup, &pdev->dev);
@@ -76,14 +79,7 @@ static int simple_pm_bus_probe(struct platform_device *pdev)
 
 static void simple_pm_bus_remove(struct platform_device *pdev)
 {
-	const void *data = of_device_get_match_data(&pdev->dev);
-
-	if (device_has_driver_override(&pdev->dev) || data)
-		return;
-
 	dev_dbg(&pdev->dev, "%s\n", __func__);
-
-	pm_runtime_disable(&pdev->dev);
 }
 
 static int simple_pm_bus_runtime_suspend(struct device *dev)
-- 
2.56.0


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

* [PATCH v9 2/4] bus: simple-pm-bus: Remove the remove() function
  2026-11-09 14:08 [PATCH v9 0/4] lan966x pci device: Add support for SFPs, simple-bus part Herve Codina
  2026-11-09 14:08 ` [PATCH v9 1/4] bus: simple-pm-bus: Avoid inconsistencies between probe() and remove() Herve Codina
@ 2026-11-09 14:08 ` Herve Codina
  2026-11-09 14:08 ` [PATCH v9 3/4] bus: simple-pm-bus: Remove child devices when the bus is unbound Herve Codina
  2026-11-09 14:08 ` [PATCH v9 4/4] bus: simple-pm-bus: Populate child nodes at probe Herve Codina
  3 siblings, 0 replies; 5+ messages in thread
From: Herve Codina @ 2026-11-09 14:08 UTC (permalink / raw)
  To: Andrew Lunn, Rob Herring, Saravana Kannan, Geert Uytterhoeven,
	Kalle Niemi, Matti Vaittinen, Greg Kroah-Hartman,
	Rafael J. Wysocki, Danilo Krummrich, Johan Hovold
  Cc: driver-core, devicetree, linux-kernel, Allan Nielsen,
	Horatiu Vultur, Daniel Machon, Steen Hegelund, Luca Ceresoli,
	Thomas Petazzoni, Herve Codina

Due to recent modification, the driver remove() function is almost
empty. It only performs a dev_dbg() call.

Having this remove() function is no more needed. Remove it.

Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
 drivers/bus/simple-pm-bus.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/drivers/bus/simple-pm-bus.c b/drivers/bus/simple-pm-bus.c
index 4322a778e801..e45700156732 100644
--- a/drivers/bus/simple-pm-bus.c
+++ b/drivers/bus/simple-pm-bus.c
@@ -77,11 +77,6 @@ static int simple_pm_bus_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static void simple_pm_bus_remove(struct platform_device *pdev)
-{
-	dev_dbg(&pdev->dev, "%s\n", __func__);
-}
-
 static int simple_pm_bus_runtime_suspend(struct device *dev)
 {
 	struct simple_pm_bus *bus = dev_get_drvdata(dev);
@@ -150,7 +145,6 @@ MODULE_DEVICE_TABLE(of, simple_pm_bus_of_match);
 
 static struct platform_driver simple_pm_bus_driver = {
 	.probe = simple_pm_bus_probe,
-	.remove = simple_pm_bus_remove,
 	.driver = {
 		.name = "simple-pm-bus",
 		.of_match_table = simple_pm_bus_of_match,
-- 
2.56.0


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

* [PATCH v9 3/4] bus: simple-pm-bus: Remove child devices when the bus is unbound
  2026-11-09 14:08 [PATCH v9 0/4] lan966x pci device: Add support for SFPs, simple-bus part Herve Codina
  2026-11-09 14:08 ` [PATCH v9 1/4] bus: simple-pm-bus: Avoid inconsistencies between probe() and remove() Herve Codina
  2026-11-09 14:08 ` [PATCH v9 2/4] bus: simple-pm-bus: Remove the remove() function Herve Codina
@ 2026-11-09 14:08 ` Herve Codina
  2026-11-09 14:08 ` [PATCH v9 4/4] bus: simple-pm-bus: Populate child nodes at probe Herve Codina
  3 siblings, 0 replies; 5+ messages in thread
From: Herve Codina @ 2026-11-09 14:08 UTC (permalink / raw)
  To: Andrew Lunn, Rob Herring, Saravana Kannan, Geert Uytterhoeven,
	Kalle Niemi, Matti Vaittinen, Greg Kroah-Hartman,
	Rafael J. Wysocki, Danilo Krummrich, Johan Hovold
  Cc: driver-core, devicetree, linux-kernel, Allan Nielsen,
	Horatiu Vultur, Daniel Machon, Steen Hegelund, Luca Ceresoli,
	Thomas Petazzoni, Herve Codina

During its probe, the simple-pm-bus driver (simple-pm-bus compatible
variant) populates its child devices but it doesn't touch them during
its removal.

This leads to bus child devices present and bound to drivers whereas the
bus itself is unbound.

Be consistent and remove child devices when the bus itself is unbound.

Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
 drivers/bus/simple-pm-bus.c | 45 +++++++++++++++++++++++++++++++++++--
 1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/drivers/bus/simple-pm-bus.c b/drivers/bus/simple-pm-bus.c
index e45700156732..23ac18551fd9 100644
--- a/drivers/bus/simple-pm-bus.c
+++ b/drivers/bus/simple-pm-bus.c
@@ -22,6 +22,46 @@ struct simple_pm_bus {
 	int num_clks;
 };
 
+static void simple_pm_bus_depopulate(void *data)
+{
+	struct device *dev = data;
+
+	/*
+	 * Bus stays on for children
+	 * This ensure that the bus will not be put in idle asynchronously when
+	 * all its children are removed.
+	 */
+	pm_runtime_get_sync(dev);
+
+	/* Let remove children */
+	of_platform_depopulate(dev);
+
+	/*
+	 * Lets runtime_suspend() calls simple_pm_bus_runtime_suspend() in a
+	 * synchronous way before disabling runtime pm.
+	 *
+	 * This guarantee that clocks are disabled and unprepared before the
+	 * bus is removed in all cases.
+	 */
+	pm_runtime_put_sync(dev);
+}
+
+static int simple_pm_bus_populate(struct device *dev,
+				  const struct of_dev_auxdata *lookup)
+{
+	struct device_node *np = dev->of_node;
+	int ret;
+
+	if (!np)
+		return 0;
+
+	ret = of_platform_populate(np, NULL, lookup, dev);
+	if (ret)
+		return ret;
+
+	return devm_add_action_or_reset(dev, simple_pm_bus_depopulate, dev);
+}
+
 static int simple_pm_bus_probe(struct platform_device *pdev)
 {
 	const struct device *dev = &pdev->dev;
@@ -71,8 +111,9 @@ static int simple_pm_bus_probe(struct platform_device *pdev)
 	if (ret)
 		return dev_err_probe(&pdev->dev, ret, "failed enable pm_runtime\n");
 
-	if (np)
-		of_platform_populate(np, NULL, lookup, &pdev->dev);
+	ret = simple_pm_bus_populate(&pdev->dev, lookup);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "failed to populate\n");
 
 	return 0;
 }
-- 
2.56.0


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

* [PATCH v9 4/4] bus: simple-pm-bus: Populate child nodes at probe
  2026-11-09 14:08 [PATCH v9 0/4] lan966x pci device: Add support for SFPs, simple-bus part Herve Codina
                   ` (2 preceding siblings ...)
  2026-11-09 14:08 ` [PATCH v9 3/4] bus: simple-pm-bus: Remove child devices when the bus is unbound Herve Codina
@ 2026-11-09 14:08 ` Herve Codina
  3 siblings, 0 replies; 5+ messages in thread
From: Herve Codina @ 2026-11-09 14:08 UTC (permalink / raw)
  To: Andrew Lunn, Rob Herring, Saravana Kannan, Geert Uytterhoeven,
	Kalle Niemi, Matti Vaittinen, Greg Kroah-Hartman,
	Rafael J. Wysocki, Danilo Krummrich, Johan Hovold
  Cc: driver-core, devicetree, linux-kernel, Allan Nielsen,
	Horatiu Vultur, Daniel Machon, Steen Hegelund, Luca Ceresoli,
	Thomas Petazzoni, Herve Codina

The simple-pm-bus driver handles several simple busses. When it is used
with busses other than a compatible "simple-pm-bus", it doesn't populate
its child devices during its probe.

This confuses fw_devlink and results in wrong or missing devlinks.

Once a driver is bound to a device and the probe() has been called,
device_links_driver_bound() is called.

This function performs operation based on the following assumption:
    If a child firmware node of the bound device is not added as a
    device, it will never be added.

Among operations done on fw_devlinks of those "never be added" devices,
device_links_driver_bound() changes their supplier.

With devices attached to a simple-bus compatible device, this change
leads to wrong devlinks where supplier of devices points to the device
parent (i.e. simple-bus compatible device) instead of the device itself
(i.e. simple-bus child).

When the device attached to the simple-bus is removed, because devlinks
are not correct, its consumers are not removed first.

In order to have correct devlinks created, make the simple-pm-bus driver
compliant with the devlink assumption and create its child devices
during its probe.

Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
 drivers/bus/simple-pm-bus.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/bus/simple-pm-bus.c b/drivers/bus/simple-pm-bus.c
index 23ac18551fd9..569580788575 100644
--- a/drivers/bus/simple-pm-bus.c
+++ b/drivers/bus/simple-pm-bus.c
@@ -26,6 +26,12 @@ static void simple_pm_bus_depopulate(void *data)
 {
 	struct device *dev = data;
 
+	if (!pm_runtime_enabled(dev)) {
+		/* No PM runtime, we can directly depopulate */
+		of_platform_depopulate(dev);
+		return;
+	}
+
 	/*
 	 * Bus stays on for children
 	 * This ensure that the bus will not be put in idle asynchronously when
@@ -83,16 +89,23 @@ static int simple_pm_bus_probe(struct platform_device *pdev)
 	match = of_match_device(dev->driver->of_match_table, dev);
 	/*
 	 * These are transparent bus devices (not simple-pm-bus matches) that
-	 * have their child nodes populated automatically.  So, don't need to
-	 * do anything more. We only match with the device if this driver is
-	 * the most specific match because we don't want to incorrectly bind to
-	 * a device that has a more specific driver.
+	 * need to have their child nodes populated. So, don't need to do
+	 * anything more except populate child nodes during this probe(). We
+	 * only match with the device if this driver is the most specific match
+	 * because we don't want to incorrectly bind to a device that has a more
+	 * specific driver.
 	 */
 	if (match && match->data) {
-		if (of_property_match_string(np, "compatible", match->compatible) == 0)
-			return 0;
-		else
+		if (of_property_match_string(np, "compatible", match->compatible))
 			return -ENODEV;
+
+		dev_dbg(&pdev->dev, "%s: populate only\n", __func__);
+
+		ret = simple_pm_bus_populate(&pdev->dev, lookup);
+		if (ret)
+			return dev_err_probe(&pdev->dev, ret, "failed to populate\n");
+
+		return 0;
 	}
 
 	bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
-- 
2.56.0


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

end of thread, other threads:[~2026-11-09 14:09 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-09 14:08 [PATCH v9 0/4] lan966x pci device: Add support for SFPs, simple-bus part Herve Codina
2026-11-09 14:08 ` [PATCH v9 1/4] bus: simple-pm-bus: Avoid inconsistencies between probe() and remove() Herve Codina
2026-11-09 14:08 ` [PATCH v9 2/4] bus: simple-pm-bus: Remove the remove() function Herve Codina
2026-11-09 14:08 ` [PATCH v9 3/4] bus: simple-pm-bus: Remove child devices when the bus is unbound Herve Codina
2026-11-09 14:08 ` [PATCH v9 4/4] bus: simple-pm-bus: Populate child nodes at probe Herve Codina

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®