diff mbox series

[5/7] usb: onboard-hub: Bail out if peer hub is already probed

Message ID 20240605100221.3571-6-venkatesh.abbarapu@amd.com
State Changes Requested
Delegated to: Marek Vasut
Headers show
Series Add the USB5744 hub driver as per new DT binding | expand

Commit Message

Venkatesh Yadav Abbarapu June 5, 2024, 10:02 a.m. UTC
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.stach@pengutronix.de/

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

Comments

Marek Vasut Sept. 2, 2024, 6:58 p.m. UTC | #1
On 6/5/24 12:02 PM, Venkatesh Yadav Abbarapu wrote:
> Many physical hub chips include multiple logical hubs to handle both
> USB and 

Remove the 'and' here.

> 2 and 3

USB 2.0 and USB 3.0 .

>. 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.stach@pengutronix.de/
> 
> Signed-off-by: Venkatesh Yadav Abbarapu <venkatesh.abbarapu@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;

One field per line please.

>   	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;
> +		}
> +	}
> +

Implement .bind function of this driver, bind the correct "half" of the 
hub that you want the driver to bind to, and return -ENODEV for the 
other "half". See rpc_spi_bind() in drivers/spi/renesas_rpc_spi.c for 
example of this.
diff mbox series

Patch

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;
 }