[PATCH v13 2/5] phy: core: Add devm_phy_get_by_of_node()
From: Bryan O'Donoghue
Date: Tue Jul 28 2026 - 05:47:54 EST
Add a devm variant of phy_get_by_of_node() to allow for the familiar
pattern of having devres automatically release resources on the driver's
exit path.
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@xxxxxxxxxx>
---
drivers/phy/phy-core.c | 34 ++++++++++++++++++++++++++++++++++
include/linux/phy/phy.h | 7 +++++++
2 files changed, 41 insertions(+)
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index ebfad5325072e..7af24f2f4120f 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -1029,6 +1029,40 @@ struct phy *phy_get_by_of_node(struct device_node *np)
}
EXPORT_SYMBOL_GPL(phy_get_by_of_node);
+/**
+ * devm_phy_get_by_of_node() - devm managed lookup and obtain phy reference by device node
+ * @dev: device requesting the PHY
+ * @np: device_node of the PHY provider
+ *
+ * Returns phy associated with the device_node or ERR_PTR. devres manages
+ * releasing resources.
+ */
+struct phy *devm_phy_get_by_of_node(struct device *dev, struct device_node *np)
+{
+ struct phy **ptr, *phy;
+ struct device_link *link;
+
+ ptr = devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return ERR_PTR(-ENOMEM);
+
+ phy = phy_get_by_of_node(np);
+ if (IS_ERR(phy)) {
+ devres_free(ptr);
+ return phy;
+ }
+
+ *ptr = phy;
+ devres_add(dev, ptr);
+ link = device_link_add(dev, &phy->dev, DL_FLAG_STATELESS);
+ if (!link)
+ dev_dbg(dev, "failed to create device link to %s\n",
+ dev_name(phy->dev.parent));
+
+ return phy;
+}
+EXPORT_SYMBOL_GPL(devm_phy_get_by_of_node);
+
/**
* phy_create() - create a new phy
* @dev: device that is creating the new phy
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 71c2e16397130..14b924a88411f 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -285,6 +285,7 @@ struct phy *devm_of_phy_optional_get(struct device *dev, struct device_node *np,
struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np,
int index);
struct phy *phy_get_by_of_node(struct device_node *np);
+struct phy *devm_phy_get_by_of_node(struct device *dev, struct device_node *np);
void of_phy_put(struct phy *phy);
void phy_put(struct device *dev, struct phy *phy);
void devm_phy_put(struct device *dev, struct phy *phy);
@@ -499,6 +500,12 @@ static inline struct phy *phy_get_by_of_node(struct device_node *np)
return ERR_PTR(-ENOSYS);
}
+static inline struct phy *devm_phy_get_by_of_node(struct device *dev,
+ struct device_node *np)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
static inline void of_phy_put(struct phy *phy)
{
}
--
2.54.0