Netdev List
 help / color / mirror / Atom feed
From: Carlo Szelinsky <github@szelinsky.de>
To: Oleksij Rempel <o.rempel@pengutronix.de>,
	Kory Maincent <kory.maincent@bootlin.com>,
	Andrew Lunn <andrew+netdev@lunn.ch>,
	"David S . Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@kernel.org>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>
Cc: Mark Brown <broonie@kernel.org>,
	Liam Girdwood <lgirdwood@gmail.com>,
	Corey Leavitt <corey@leavitt.info>,
	Kyle Swenson <kyle.swenson@est.tech>,
	Simon Horman <horms@kernel.org>,
	netdev-bot+sashiko@kernel.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Carlo Szelinsky <github@szelinsky.de>
Subject: [PATCH net-next 4/4] net: pse-pd: check the PI vpwr supply before registering the controller
Date: Sun, 18 Oct 2026 10:18:53 +0200	[thread overview]
Message-ID: <20261018081853.47484-5-github@szelinsky.de> (raw)
In-Reply-To: <20261018081853.47484-1-github@szelinsky.de>

A regulator registers even when its supply is not there yet. So a PSE
controller registers while its vpwr supply is missing, and every PI
lookup returns -EPROBE_DEFER until the supply appears. Today the MDIO
bus owner keeps deferring until then, but a consumer that only looks a
PI up when a controller registers, as phylib will with the PSE
notifier, would never get it.

Check every PI's vpwr supply before the PI regulators are registered,
and defer the PSE driver's probe if one is missing. The check runs
after setup_pi_matrix(), because pd692x0 registers the supply
regulators there.

The check is simpler than the regulator core's: a supply that is
registered, but whose device is not bound yet, still passes, and that
PI then gets no power domain. On the other hand, a PI whose supply
appears late now gets a power domain; before, pse_register_pw_ds()
skipped it.

Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
---
 drivers/net/pse-pd/pse_core.c | 81 +++++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 05b02d736931..44986749600e 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -11,6 +11,7 @@
 #include <linux/of.h>
 #include <linux/phy.h>
 #include <linux/pse-pd/pse.h>
+#include <linux/regulator/consumer.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/rtnetlink.h>
@@ -826,6 +827,65 @@ static const struct regulator_ops pse_pi_ops = {
 	.set_current_limit = pse_pi_set_current_limit,
 };
 
+/* Look up PI @id's vpwr supply on its own node, as the regulator core
+ * will. Only if the PI node has a vpwr-supply phandle: otherwise the
+ * lookup falls back to of_get_child_regulator() on the controller node,
+ * which can return a sibling PI's supply.
+ *
+ * Return: 0 if this PI needs nothing more, 1 if the controller node has
+ *	   to answer for it, or a negative error such as -EPROBE_DEFER.
+ */
+static int pse_pi_check_supply(struct pse_controller_dev *pcdev, int id)
+{
+	struct device_node *np;
+	struct regulator *supply;
+	int ret;
+
+	/* The PIs the registration loop skips. */
+	if (!pcdev->no_of_pse_pi && !pcdev->pi[id].np)
+		return 0;
+
+	np = pcdev->pi[id].np ?
+	     of_parse_phandle(pcdev->pi[id].np, "vpwr-supply", 0) : NULL;
+	if (!np)
+		return 1;
+
+	of_node_put(np);
+	supply = of_regulator_get_optional(pcdev->dev, pcdev->pi[id].np,
+					   "vpwr");
+	if (!IS_ERR(supply)) {
+		regulator_put(supply);
+		return 0;
+	}
+
+	ret = PTR_ERR(supply);
+	if (ret == -ENODEV)
+		return 1;
+
+	return dev_err_probe(pcdev->dev, ret,
+			     "PI %d: failed to get vpwr supply\n", id);
+}
+
+/* The core's fallback: a vpwr-supply on the controller node. */
+static int pse_controller_check_supply(struct pse_controller_dev *pcdev)
+{
+	struct regulator *supply;
+	int ret;
+
+	supply = regulator_get_optional(pcdev->dev, "vpwr");
+	if (!IS_ERR(supply)) {
+		regulator_put(supply);
+		return 0;
+	}
+
+	ret = PTR_ERR(supply);
+	if (ret == -ENODEV)
+		return 0;
+
+	return dev_err_probe(pcdev->dev, ret,
+			     "failed to get vpwr supply\n");
+}
+
 static int
 devm_pse_pi_regulator_register(struct pse_controller_dev *pcdev,
 			       char *name, int id)
@@ -1068,6 +1128,7 @@ static void pse_send_ntf_worker(struct work_struct *work)
  */
 int pse_controller_register(struct pse_controller_dev *pcdev)
 {
+	bool ctrl_supply_ok = false;
 	size_t reg_name_len;
 	int ret, i;
 
@@ -1102,6 +1163,26 @@ int pse_controller_register(struct pse_controller_dev *pcdev)
 			goto release_pis;
 	}
 
+	/* Check vpwr supplies while pcdev->pi can still be freed. Not before
+	 * setup_pi_matrix(): pd692x0 registers the regulators its PIs name
+	 * there.
+	 */
+	for (i = 0; i < pcdev->nr_lines; i++) {
+		ret = pse_pi_check_supply(pcdev, i);
+		if (ret < 0)
+			goto release_pis;
+
+		/* Same answer for every PI: ask once. */
+		if (!ret || ctrl_supply_ok)
+			continue;
+
+		ret = pse_controller_check_supply(pcdev);
+		if (ret)
+			goto release_pis;
+
+		ctrl_supply_ok = true;
+	}
+
 	/* Each regulator name len is pcdev dev name + 7 char +
 	 * int max digit number (10) + 1
 	 */
-- 
2.43.0


  parent reply	other threads:[~2026-10-18  8:19 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-18  8:18 [PATCH net-next 0/4] net: pse-pd: core fixes ahead of the controller notifier Carlo Szelinsky
2026-10-18  8:18 ` [PATCH net-next 1/4] net: pse-pd: unlink the controller before freeing its PI data Carlo Szelinsky
2026-10-18  8:18 ` [PATCH net-next 2/4] net: pse-pd: unwind allocations when controller registration fails Carlo Szelinsky
2026-10-18  8:18 ` [PATCH net-next 3/4] net: pse-pd: si3474: use dev_err_probe() for controller registration Carlo Szelinsky
2026-10-18  8:18 ` Carlo Szelinsky [this message]
2026-10-18  8:23 ` [PATCH net-next 0/4] net: pse-pd: core fixes ahead of the controller notifier netdev-bot+sinfo

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=20261018081853.47484-5-github@szelinsky.de \
    --to=github@szelinsky.de \
    --cc=andrew+netdev@lunn.ch \
    --cc=broonie@kernel.org \
    --cc=corey@leavitt.info \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=horms@kernel.org \
    --cc=kory.maincent@bootlin.com \
    --cc=kuba@kernel.org \
    --cc=kyle.swenson@est.tech \
    --cc=lgirdwood@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev-bot+sashiko@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=o.rempel@pengutronix.de \
    --cc=pabeni@redhat.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox