Many physical hub chips include multiple logical hubs to handle both
USB and 2 and 3. Both logical hubs will then match the onboard hub
driver, which means it will end up with two driver instances trying to
control the reset GPIO that is only present once on the physical chip.

The reference for this change is taken from
https://lore.barebox.org/barebox/20240327165554.894805-1-l.st...@pengutronix.de/

Signed-off-by: Venkatesh Yadav Abbarapu <venkatesh.abbar...@amd.com>
---
 common/usb_onboard_hub.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/common/usb_onboard_hub.c b/common/usb_onboard_hub.c
index 09ce452af1b..519bad337e1 100644
--- a/common/usb_onboard_hub.c
+++ b/common/usb_onboard_hub.c
@@ -11,6 +11,7 @@
 #include <common.h>
 #include <dm.h>
 #include <dm/device_compat.h>
+#include <dm/uclass-internal.h>
 #include <i2c.h>
 #include <linux/delay.h>
 #include <power/regulator.h>
@@ -21,7 +22,7 @@
 #define USB5744_CONFIG_REG_ACCESS_LSB 0x99
 
 struct onboard_hub {
-       struct udevice *vdd;
+       struct udevice *vdd, *dev;
        struct gpio_desc *reset_gpio;
 };
 
@@ -106,8 +107,18 @@ static int usb_onboard_hub_probe(struct udevice *dev)
        struct onboard_hub_data *data =
                (struct onboard_hub_data *)dev_get_driver_data(dev);
        struct onboard_hub *hub = dev_get_priv(dev);
+       struct ofnode_phandle_args phandle;
+       struct udevice *hub_dev;
        int ret;
 
+       if (!dev_read_phandle_with_args(dev, "peer-hub", NULL, 0, 0, &phandle)) 
{
+               if (ofnode_valid(phandle.node)) {
+                       ret = uclass_find_device_by_ofnode(UCLASS_USB_HUB, 
phandle.node, &hub_dev);
+                       if (hub_dev && hub_dev->priv_)
+                               return 0;
+               }
+       }
+
        if (CONFIG_IS_ENABLED(DM_REGULATOR)) {
                ret = device_get_supply_regulator(dev, "vdd-supply",
                                                  &hub->vdd);
@@ -148,6 +159,9 @@ static int usb_onboard_hub_probe(struct udevice *dev)
                        return ret;
                }
        }
+       hub->dev = dev;
+       dev->priv_ = hub;
+
        return 0;
 }
 
-- 
2.17.1

Reply via email to