While commit bfb530e06ca6 ("usb: cdns3: use VBUS Valid to determine role
for dr_mode OTG") enhances the driver, it causes boot failure for non-USB
boot mode when the 'dr_mode' is 'otg'. The reason for it is that the
cdns3_get_otg_mode() function reads the USB Controller registers to
determine the appropriate role. If the boot mode happens to be USB, then
the USB Controller will be powered ON and the registers are accessible.
For non-USB boot modes, the USB Controller is not necessarily powered ON
as a result of which the register accesses cause boot failure.
Another issue is that the error code from cdns3_get_otg_mode() is returned
as-is by cdns3_bind(). The cdns3_bind() function already has a comment
near the 'fail' label stating that an error code should __not__ be returned
as it will cause the board to hang.
Fix the aforementioned issues in the following manner:
1. Probe the parent device before calling cdns3_get_otg_mode() to ensure
that the USB Controller is powered ON and its registers are accessible.
2. If cdns3_get_otg_mode() returns an error code, instead of returning
the error code, jump to the 'fail' label and return '0'.
Fixes: bfb530e06ca6 ("usb: cdns3: use VBUS Valid to determine role for dr_mode
OTG")
Signed-off-by: Siddharth Vadapalli <[email protected]>
---
Hello,
This patch is based on commit
7995bf8dea2 Merge branch 'master' of
https://source.denx.de/u-boot/custodians/u-boot-samsung
of the master branch of U-Boot.
This patch is critical since it fixes non-USB boot modes on J784S4-EVM.
The commit being Fixed introduced boot failure for non-USB boot modes due
to the register accesses being performed by cdns3_get_otg_mode() without
ensuring that the USB Controller is powered ON.
Test Logs with the patch on J784S4 EVM for:
1. SD Boot Mode (non-USB Boot Mode):
https://gist.github.com/Siddharth-Vadapalli-at-TI/d3fbf2a7ddfa9bee1d65c09254ca3ef3
2. USB DFU Boot Mode (USB Boot Mode):
https://gist.github.com/Siddharth-Vadapalli-at-TI/bb7487efeb37b72039a9cb7d7aa563e0
Regards,
Siddharth.
drivers/usb/cdns3/core.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c
index 10bc4cabed4..a775567b3bc 100644
--- a/drivers/usb/cdns3/core.c
+++ b/drivers/usb/cdns3/core.c
@@ -461,9 +461,18 @@ int cdns3_bind(struct udevice *parent)
/* Use VBUS Valid to determine role */
if (dr_mode == USB_DR_MODE_OTG) {
+ /*
+ * Since we perform register accesses in cdns3_get_otg_mode(),
+ * we need to ensure that the parent has been probed and that
+ * the USB Controller is powered ON.
+ */
+ ret = device_probe(parent);
+ if (ret)
+ goto fail;
+
ret = cdns3_get_otg_mode(parent, &dr_mode);
if (ret < 0)
- return ret;
+ goto fail;
}
switch (dr_mode) {
--
2.51.1