mirror of
https://github.com/openwrt/openwrt.git
synced 2026-07-19 22:51:49 +04:00
d0784a69dd
Changelog: https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.12.75 Removed upstream: bcm27xx/patches-6.12/950-0225-media-i2c-ov5647-Correct-pixel-array-offset.patch[1] bcm27xx/patches-6.12/950-0226-media-i2c-ov5647-Correct-minimum-VBLANK-value.patch[2] bcm27xx/patches-6.12/950-0248-media-i2c-ov5647-Sensor-should-report-RAW-color-spac.patch[3] qualcommax/patches-6.12/0074-v6.20-clk-qcom-gcc-ipq5018-flag-sleep-clock-as-critical.patch[4] Manually rebased: bcm27xx/patches-6.12/950-0262-mfd-simple-mfd-i2c-Add-configuration-for-RPi-POE-HAT.patch bcm27xx/patches-6.12/950-0071-drivers-mfd-sensehat-Add-Raspberry-Pi-Sense-HAT-to-s.patch bcm27xx/patches-6.12/950-0516-media-i2c-ov5647-Add-V4L2_CID_LINK_FREQUENCY-control.patch lantiq/patches-6.12/101-find_active_root.patch All other patches automatically rebased. 1. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.75&id=58f1767ad5c9eda3dd0befddc1843259d46d64fa 2. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.75&id=ff65571ffae52b65577121e7696bf22156e1928a 3. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.75&id=fbf2a108ed5eb1c896d3f354bd05314c2e22e78f 4. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.75&id=b109dd4970a0fc89d54b1198b163f86125dd2977 Build system: x86/64 Build-tested: flogic/glinet_gl-mt6000 Run-tested: flogic/glinet_gl-mt6000 Co-authored-by: Shiji Yang <yangshiji66@outlook.com> Signed-off-by: John Audia <therealgraysky@proton.me> Link: https://github.com/openwrt/openwrt/pull/22276 Signed-off-by: Robert Marko <robimarko@gmail.com>
525 lines
16 KiB
Diff
525 lines
16 KiB
Diff
From 986ec7ee75f2f1f7f93eb0e05f61f297f6123fce Mon Sep 17 00:00:00 2001
|
|
From: Heiner Kallweit <hkallweit1@gmail.com>
|
|
Date: Mon, 3 Mar 2025 21:14:02 +0100
|
|
Subject: [PATCH] v6.15: net: phy: move PHY package code from phy_device.c to
|
|
own source file
|
|
|
|
This patch is the first step in moving the PHY package related code
|
|
to its own source file. No functional change intended.
|
|
|
|
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
|
Link: https://patch.msgid.link/57df5c19-fbcd-45a7-9afd-cd4f74d7fa76@gmail.com
|
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
---
|
|
drivers/net/phy/Makefile | 3 +-
|
|
drivers/net/phy/phy_device.c | 237 ---------------------------------
|
|
drivers/net/phy/phy_package.c | 244 ++++++++++++++++++++++++++++++++++
|
|
3 files changed, 246 insertions(+), 238 deletions(-)
|
|
create mode 100644 drivers/net/phy/phy_package.c
|
|
|
|
--- a/drivers/net/phy/Makefile
|
|
+++ b/drivers/net/phy/Makefile
|
|
@@ -2,7 +2,8 @@
|
|
# Makefile for Linux PHY drivers
|
|
|
|
libphy-y := phy.o phy-c45.o phy-core.o phy_device.o \
|
|
- linkmode.o phy_link_topology.o
|
|
+ linkmode.o phy_link_topology.o \
|
|
+ phy_package.o
|
|
mdio-bus-y += mdio_bus.o mdio_device.o
|
|
|
|
ifdef CONFIG_MDIO_DEVICE
|
|
--- a/drivers/net/phy/phy_device.c
|
|
+++ b/drivers/net/phy/phy_device.c
|
|
@@ -1781,243 +1781,6 @@ bool phy_driver_is_genphy_10g(struct phy
|
|
EXPORT_SYMBOL_GPL(phy_driver_is_genphy_10g);
|
|
|
|
/**
|
|
- * phy_package_join - join a common PHY group
|
|
- * @phydev: target phy_device struct
|
|
- * @base_addr: cookie and base PHY address of PHY package for offset
|
|
- * calculation of global register access
|
|
- * @priv_size: if non-zero allocate this amount of bytes for private data
|
|
- *
|
|
- * This joins a PHY group and provides a shared storage for all phydevs in
|
|
- * this group. This is intended to be used for packages which contain
|
|
- * more than one PHY, for example a quad PHY transceiver.
|
|
- *
|
|
- * The base_addr parameter serves as cookie which has to have the same values
|
|
- * for all members of one group and as the base PHY address of the PHY package
|
|
- * for offset calculation to access generic registers of a PHY package.
|
|
- * Usually, one of the PHY addresses of the different PHYs in the package
|
|
- * provides access to these global registers.
|
|
- * The address which is given here, will be used in the phy_package_read()
|
|
- * and phy_package_write() convenience functions as base and added to the
|
|
- * passed offset in those functions.
|
|
- *
|
|
- * This will set the shared pointer of the phydev to the shared storage.
|
|
- * If this is the first call for a this cookie the shared storage will be
|
|
- * allocated. If priv_size is non-zero, the given amount of bytes are
|
|
- * allocated for the priv member.
|
|
- *
|
|
- * Returns < 1 on error, 0 on success. Esp. calling phy_package_join()
|
|
- * with the same cookie but a different priv_size is an error.
|
|
- */
|
|
-int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size)
|
|
-{
|
|
- struct mii_bus *bus = phydev->mdio.bus;
|
|
- struct phy_package_shared *shared;
|
|
- int ret;
|
|
-
|
|
- if (base_addr < 0 || base_addr >= PHY_MAX_ADDR)
|
|
- return -EINVAL;
|
|
-
|
|
- mutex_lock(&bus->shared_lock);
|
|
- shared = bus->shared[base_addr];
|
|
- if (!shared) {
|
|
- ret = -ENOMEM;
|
|
- shared = kzalloc(sizeof(*shared), GFP_KERNEL);
|
|
- if (!shared)
|
|
- goto err_unlock;
|
|
- if (priv_size) {
|
|
- shared->priv = kzalloc(priv_size, GFP_KERNEL);
|
|
- if (!shared->priv)
|
|
- goto err_free;
|
|
- shared->priv_size = priv_size;
|
|
- }
|
|
- shared->base_addr = base_addr;
|
|
- shared->np = NULL;
|
|
- refcount_set(&shared->refcnt, 1);
|
|
- bus->shared[base_addr] = shared;
|
|
- } else {
|
|
- ret = -EINVAL;
|
|
- if (priv_size && priv_size != shared->priv_size)
|
|
- goto err_unlock;
|
|
- refcount_inc(&shared->refcnt);
|
|
- }
|
|
- mutex_unlock(&bus->shared_lock);
|
|
-
|
|
- phydev->shared = shared;
|
|
-
|
|
- return 0;
|
|
-
|
|
-err_free:
|
|
- kfree(shared);
|
|
-err_unlock:
|
|
- mutex_unlock(&bus->shared_lock);
|
|
- return ret;
|
|
-}
|
|
-EXPORT_SYMBOL_GPL(phy_package_join);
|
|
-
|
|
-/**
|
|
- * of_phy_package_join - join a common PHY group in PHY package
|
|
- * @phydev: target phy_device struct
|
|
- * @priv_size: if non-zero allocate this amount of bytes for private data
|
|
- *
|
|
- * This is a variant of phy_package_join for PHY package defined in DT.
|
|
- *
|
|
- * The parent node of the @phydev is checked as a valid PHY package node
|
|
- * structure (by matching the node name "ethernet-phy-package") and the
|
|
- * base_addr for the PHY package is passed to phy_package_join.
|
|
- *
|
|
- * With this configuration the shared struct will also have the np value
|
|
- * filled to use additional DT defined properties in PHY specific
|
|
- * probe_once and config_init_once PHY package OPs.
|
|
- *
|
|
- * Returns < 0 on error, 0 on success. Esp. calling phy_package_join()
|
|
- * with the same cookie but a different priv_size is an error. Or a parent
|
|
- * node is not detected or is not valid or doesn't match the expected node
|
|
- * name for PHY package.
|
|
- */
|
|
-int of_phy_package_join(struct phy_device *phydev, size_t priv_size)
|
|
-{
|
|
- struct device_node *node = phydev->mdio.dev.of_node;
|
|
- struct device_node *package_node;
|
|
- u32 base_addr;
|
|
- int ret;
|
|
-
|
|
- if (!node)
|
|
- return -EINVAL;
|
|
-
|
|
- package_node = of_get_parent(node);
|
|
- if (!package_node)
|
|
- return -EINVAL;
|
|
-
|
|
- if (!of_node_name_eq(package_node, "ethernet-phy-package")) {
|
|
- ret = -EINVAL;
|
|
- goto exit;
|
|
- }
|
|
-
|
|
- if (of_property_read_u32(package_node, "reg", &base_addr)) {
|
|
- ret = -EINVAL;
|
|
- goto exit;
|
|
- }
|
|
-
|
|
- ret = phy_package_join(phydev, base_addr, priv_size);
|
|
- if (ret)
|
|
- goto exit;
|
|
-
|
|
- phydev->shared->np = package_node;
|
|
-
|
|
- return 0;
|
|
-exit:
|
|
- of_node_put(package_node);
|
|
- return ret;
|
|
-}
|
|
-EXPORT_SYMBOL_GPL(of_phy_package_join);
|
|
-
|
|
-/**
|
|
- * phy_package_leave - leave a common PHY group
|
|
- * @phydev: target phy_device struct
|
|
- *
|
|
- * This leaves a PHY group created by phy_package_join(). If this phydev
|
|
- * was the last user of the shared data between the group, this data is
|
|
- * freed. Resets the phydev->shared pointer to NULL.
|
|
- */
|
|
-void phy_package_leave(struct phy_device *phydev)
|
|
-{
|
|
- struct phy_package_shared *shared = phydev->shared;
|
|
- struct mii_bus *bus = phydev->mdio.bus;
|
|
-
|
|
- if (!shared)
|
|
- return;
|
|
-
|
|
- /* Decrease the node refcount on leave if present */
|
|
- if (shared->np)
|
|
- of_node_put(shared->np);
|
|
-
|
|
- if (refcount_dec_and_mutex_lock(&shared->refcnt, &bus->shared_lock)) {
|
|
- bus->shared[shared->base_addr] = NULL;
|
|
- mutex_unlock(&bus->shared_lock);
|
|
- kfree(shared->priv);
|
|
- kfree(shared);
|
|
- }
|
|
-
|
|
- phydev->shared = NULL;
|
|
-}
|
|
-EXPORT_SYMBOL_GPL(phy_package_leave);
|
|
-
|
|
-static void devm_phy_package_leave(struct device *dev, void *res)
|
|
-{
|
|
- phy_package_leave(*(struct phy_device **)res);
|
|
-}
|
|
-
|
|
-/**
|
|
- * devm_phy_package_join - resource managed phy_package_join()
|
|
- * @dev: device that is registering this PHY package
|
|
- * @phydev: target phy_device struct
|
|
- * @base_addr: cookie and base PHY address of PHY package for offset
|
|
- * calculation of global register access
|
|
- * @priv_size: if non-zero allocate this amount of bytes for private data
|
|
- *
|
|
- * Managed phy_package_join(). Shared storage fetched by this function,
|
|
- * phy_package_leave() is automatically called on driver detach. See
|
|
- * phy_package_join() for more information.
|
|
- */
|
|
-int devm_phy_package_join(struct device *dev, struct phy_device *phydev,
|
|
- int base_addr, size_t priv_size)
|
|
-{
|
|
- struct phy_device **ptr;
|
|
- int ret;
|
|
-
|
|
- ptr = devres_alloc(devm_phy_package_leave, sizeof(*ptr),
|
|
- GFP_KERNEL);
|
|
- if (!ptr)
|
|
- return -ENOMEM;
|
|
-
|
|
- ret = phy_package_join(phydev, base_addr, priv_size);
|
|
-
|
|
- if (!ret) {
|
|
- *ptr = phydev;
|
|
- devres_add(dev, ptr);
|
|
- } else {
|
|
- devres_free(ptr);
|
|
- }
|
|
-
|
|
- return ret;
|
|
-}
|
|
-EXPORT_SYMBOL_GPL(devm_phy_package_join);
|
|
-
|
|
-/**
|
|
- * devm_of_phy_package_join - resource managed of_phy_package_join()
|
|
- * @dev: device that is registering this PHY package
|
|
- * @phydev: target phy_device struct
|
|
- * @priv_size: if non-zero allocate this amount of bytes for private data
|
|
- *
|
|
- * Managed of_phy_package_join(). Shared storage fetched by this function,
|
|
- * phy_package_leave() is automatically called on driver detach. See
|
|
- * of_phy_package_join() for more information.
|
|
- */
|
|
-int devm_of_phy_package_join(struct device *dev, struct phy_device *phydev,
|
|
- size_t priv_size)
|
|
-{
|
|
- struct phy_device **ptr;
|
|
- int ret;
|
|
-
|
|
- ptr = devres_alloc(devm_phy_package_leave, sizeof(*ptr),
|
|
- GFP_KERNEL);
|
|
- if (!ptr)
|
|
- return -ENOMEM;
|
|
-
|
|
- ret = of_phy_package_join(phydev, priv_size);
|
|
-
|
|
- if (!ret) {
|
|
- *ptr = phydev;
|
|
- devres_add(dev, ptr);
|
|
- } else {
|
|
- devres_free(ptr);
|
|
- }
|
|
-
|
|
- return ret;
|
|
-}
|
|
-EXPORT_SYMBOL_GPL(devm_of_phy_package_join);
|
|
-
|
|
-/**
|
|
* phy_detach - detach a PHY device from its network device
|
|
* @phydev: target phy_device struct
|
|
*
|
|
--- /dev/null
|
|
+++ b/drivers/net/phy/phy_package.c
|
|
@@ -0,0 +1,244 @@
|
|
+// SPDX-License-Identifier: GPL-2.0-or-later
|
|
+/*
|
|
+ * PHY package support
|
|
+ */
|
|
+
|
|
+#include <linux/of.h>
|
|
+#include <linux/phy.h>
|
|
+
|
|
+/**
|
|
+ * phy_package_join - join a common PHY group
|
|
+ * @phydev: target phy_device struct
|
|
+ * @base_addr: cookie and base PHY address of PHY package for offset
|
|
+ * calculation of global register access
|
|
+ * @priv_size: if non-zero allocate this amount of bytes for private data
|
|
+ *
|
|
+ * This joins a PHY group and provides a shared storage for all phydevs in
|
|
+ * this group. This is intended to be used for packages which contain
|
|
+ * more than one PHY, for example a quad PHY transceiver.
|
|
+ *
|
|
+ * The base_addr parameter serves as cookie which has to have the same values
|
|
+ * for all members of one group and as the base PHY address of the PHY package
|
|
+ * for offset calculation to access generic registers of a PHY package.
|
|
+ * Usually, one of the PHY addresses of the different PHYs in the package
|
|
+ * provides access to these global registers.
|
|
+ * The address which is given here, will be used in the phy_package_read()
|
|
+ * and phy_package_write() convenience functions as base and added to the
|
|
+ * passed offset in those functions.
|
|
+ *
|
|
+ * This will set the shared pointer of the phydev to the shared storage.
|
|
+ * If this is the first call for a this cookie the shared storage will be
|
|
+ * allocated. If priv_size is non-zero, the given amount of bytes are
|
|
+ * allocated for the priv member.
|
|
+ *
|
|
+ * Returns < 1 on error, 0 on success. Esp. calling phy_package_join()
|
|
+ * with the same cookie but a different priv_size is an error.
|
|
+ */
|
|
+int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size)
|
|
+{
|
|
+ struct mii_bus *bus = phydev->mdio.bus;
|
|
+ struct phy_package_shared *shared;
|
|
+ int ret;
|
|
+
|
|
+ if (base_addr < 0 || base_addr >= PHY_MAX_ADDR)
|
|
+ return -EINVAL;
|
|
+
|
|
+ mutex_lock(&bus->shared_lock);
|
|
+ shared = bus->shared[base_addr];
|
|
+ if (!shared) {
|
|
+ ret = -ENOMEM;
|
|
+ shared = kzalloc(sizeof(*shared), GFP_KERNEL);
|
|
+ if (!shared)
|
|
+ goto err_unlock;
|
|
+ if (priv_size) {
|
|
+ shared->priv = kzalloc(priv_size, GFP_KERNEL);
|
|
+ if (!shared->priv)
|
|
+ goto err_free;
|
|
+ shared->priv_size = priv_size;
|
|
+ }
|
|
+ shared->base_addr = base_addr;
|
|
+ shared->np = NULL;
|
|
+ refcount_set(&shared->refcnt, 1);
|
|
+ bus->shared[base_addr] = shared;
|
|
+ } else {
|
|
+ ret = -EINVAL;
|
|
+ if (priv_size && priv_size != shared->priv_size)
|
|
+ goto err_unlock;
|
|
+ refcount_inc(&shared->refcnt);
|
|
+ }
|
|
+ mutex_unlock(&bus->shared_lock);
|
|
+
|
|
+ phydev->shared = shared;
|
|
+
|
|
+ return 0;
|
|
+
|
|
+err_free:
|
|
+ kfree(shared);
|
|
+err_unlock:
|
|
+ mutex_unlock(&bus->shared_lock);
|
|
+ return ret;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(phy_package_join);
|
|
+
|
|
+/**
|
|
+ * of_phy_package_join - join a common PHY group in PHY package
|
|
+ * @phydev: target phy_device struct
|
|
+ * @priv_size: if non-zero allocate this amount of bytes for private data
|
|
+ *
|
|
+ * This is a variant of phy_package_join for PHY package defined in DT.
|
|
+ *
|
|
+ * The parent node of the @phydev is checked as a valid PHY package node
|
|
+ * structure (by matching the node name "ethernet-phy-package") and the
|
|
+ * base_addr for the PHY package is passed to phy_package_join.
|
|
+ *
|
|
+ * With this configuration the shared struct will also have the np value
|
|
+ * filled to use additional DT defined properties in PHY specific
|
|
+ * probe_once and config_init_once PHY package OPs.
|
|
+ *
|
|
+ * Returns < 0 on error, 0 on success. Esp. calling phy_package_join()
|
|
+ * with the same cookie but a different priv_size is an error. Or a parent
|
|
+ * node is not detected or is not valid or doesn't match the expected node
|
|
+ * name for PHY package.
|
|
+ */
|
|
+int of_phy_package_join(struct phy_device *phydev, size_t priv_size)
|
|
+{
|
|
+ struct device_node *node = phydev->mdio.dev.of_node;
|
|
+ struct device_node *package_node;
|
|
+ u32 base_addr;
|
|
+ int ret;
|
|
+
|
|
+ if (!node)
|
|
+ return -EINVAL;
|
|
+
|
|
+ package_node = of_get_parent(node);
|
|
+ if (!package_node)
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (!of_node_name_eq(package_node, "ethernet-phy-package")) {
|
|
+ ret = -EINVAL;
|
|
+ goto exit;
|
|
+ }
|
|
+
|
|
+ if (of_property_read_u32(package_node, "reg", &base_addr)) {
|
|
+ ret = -EINVAL;
|
|
+ goto exit;
|
|
+ }
|
|
+
|
|
+ ret = phy_package_join(phydev, base_addr, priv_size);
|
|
+ if (ret)
|
|
+ goto exit;
|
|
+
|
|
+ phydev->shared->np = package_node;
|
|
+
|
|
+ return 0;
|
|
+exit:
|
|
+ of_node_put(package_node);
|
|
+ return ret;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(of_phy_package_join);
|
|
+
|
|
+/**
|
|
+ * phy_package_leave - leave a common PHY group
|
|
+ * @phydev: target phy_device struct
|
|
+ *
|
|
+ * This leaves a PHY group created by phy_package_join(). If this phydev
|
|
+ * was the last user of the shared data between the group, this data is
|
|
+ * freed. Resets the phydev->shared pointer to NULL.
|
|
+ */
|
|
+void phy_package_leave(struct phy_device *phydev)
|
|
+{
|
|
+ struct phy_package_shared *shared = phydev->shared;
|
|
+ struct mii_bus *bus = phydev->mdio.bus;
|
|
+
|
|
+ if (!shared)
|
|
+ return;
|
|
+
|
|
+ /* Decrease the node refcount on leave if present */
|
|
+ if (shared->np)
|
|
+ of_node_put(shared->np);
|
|
+
|
|
+ if (refcount_dec_and_mutex_lock(&shared->refcnt, &bus->shared_lock)) {
|
|
+ bus->shared[shared->base_addr] = NULL;
|
|
+ mutex_unlock(&bus->shared_lock);
|
|
+ kfree(shared->priv);
|
|
+ kfree(shared);
|
|
+ }
|
|
+
|
|
+ phydev->shared = NULL;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(phy_package_leave);
|
|
+
|
|
+static void devm_phy_package_leave(struct device *dev, void *res)
|
|
+{
|
|
+ phy_package_leave(*(struct phy_device **)res);
|
|
+}
|
|
+
|
|
+/**
|
|
+ * devm_phy_package_join - resource managed phy_package_join()
|
|
+ * @dev: device that is registering this PHY package
|
|
+ * @phydev: target phy_device struct
|
|
+ * @base_addr: cookie and base PHY address of PHY package for offset
|
|
+ * calculation of global register access
|
|
+ * @priv_size: if non-zero allocate this amount of bytes for private data
|
|
+ *
|
|
+ * Managed phy_package_join(). Shared storage fetched by this function,
|
|
+ * phy_package_leave() is automatically called on driver detach. See
|
|
+ * phy_package_join() for more information.
|
|
+ */
|
|
+int devm_phy_package_join(struct device *dev, struct phy_device *phydev,
|
|
+ int base_addr, size_t priv_size)
|
|
+{
|
|
+ struct phy_device **ptr;
|
|
+ int ret;
|
|
+
|
|
+ ptr = devres_alloc(devm_phy_package_leave, sizeof(*ptr),
|
|
+ GFP_KERNEL);
|
|
+ if (!ptr)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ ret = phy_package_join(phydev, base_addr, priv_size);
|
|
+
|
|
+ if (!ret) {
|
|
+ *ptr = phydev;
|
|
+ devres_add(dev, ptr);
|
|
+ } else {
|
|
+ devres_free(ptr);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(devm_phy_package_join);
|
|
+
|
|
+/**
|
|
+ * devm_of_phy_package_join - resource managed of_phy_package_join()
|
|
+ * @dev: device that is registering this PHY package
|
|
+ * @phydev: target phy_device struct
|
|
+ * @priv_size: if non-zero allocate this amount of bytes for private data
|
|
+ *
|
|
+ * Managed of_phy_package_join(). Shared storage fetched by this function,
|
|
+ * phy_package_leave() is automatically called on driver detach. See
|
|
+ * of_phy_package_join() for more information.
|
|
+ */
|
|
+int devm_of_phy_package_join(struct device *dev, struct phy_device *phydev,
|
|
+ size_t priv_size)
|
|
+{
|
|
+ struct phy_device **ptr;
|
|
+ int ret;
|
|
+
|
|
+ ptr = devres_alloc(devm_phy_package_leave, sizeof(*ptr),
|
|
+ GFP_KERNEL);
|
|
+ if (!ptr)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ ret = of_phy_package_join(phydev, priv_size);
|
|
+
|
|
+ if (!ret) {
|
|
+ *ptr = phydev;
|
|
+ devres_add(dev, ptr);
|
|
+ } else {
|
|
+ devres_free(ptr);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(devm_of_phy_package_join);
|