diff mbox series

usb: ehci: Fix db410c usb reset not working

Message ID OSQPR04MB77401D18913B397B768EC042908C2@OSQPR04MB7740.apcprd04.prod.outlook.com
State Changes Requested
Delegated to: Marek Vasut
Headers show
Series usb: ehci: Fix db410c usb reset not working | expand

Commit Message

JianfengA.Zhu@sony.com Aug. 19, 2024, 2:05 a.m. UTC
usb reset not working error log
====================================================================
dragonboard410c => usb reset
resetting USB...
Bus usb@78d9000: Port not available.
dragonboard410c =>
====================================================================

After commit ed8fbd2889fc ("dts: msm8916: replace with upstream DTS")
msm8916_usbphy will be defined as a child device of usb@78d9000. usb reset
will first call usb_stop, and msm8916_usbphy as child dev will be unbind
in usb_stop, and there is no bind operation in do_usb_start afterwards, so
the msm8916_usbphy uclass cannot be found. This causes ehci_msm probe to
fail.

Detailed calling process
====================================================================
usb reset:
|-> usb_stop (drivers/usb/host/usb-uclass.c)
.|-> device_find_first_child
. |-> device_unbind(rh); <== (unbind msm8916_usbphy)
|-> do_usb_start
 |-> usb_init (drivers/usb/host/usb-uclass.c)
  |-> device_probe(bus);
   |-> ehci_usb_probe
    |-> generic_setup_phy <== err couldn't find msm8916_usbphy
====================================================================

Fix: rebind the msm8916_usbphy driver during ehci_usb_probe if the
msm8916_usbphy uclass has been removed.

Signed-off-by: Jianfeng Zhu <JianfengA.Zhu@sony.com>
Reviewed-by: Jacky Cao <Jacky.Cao@sony.com>
Reviewed-by: Toyama, Yoshihiro <Yoshihiro.Toyama@sony.com>
---
 drivers/usb/host/ehci-msm.c | 7 +++++++
 1 file changed, 7 insertions(+)

Comments

JianfengA.Zhu@sony.com Aug. 20, 2024, 2:45 a.m. UTC | #1
> Jianfeng: could you run the usb reset command with log level 8 and paste 
> a log? That might reveal where the FDT lookup goes wrong.

Please confirm below log with level 8 

dragonboard410c => usb reset
resetting USB...
Sending event 5/(unknown) to spy 'efi_disk add'
Bus usb@78d9000: ofnode_read_prop: assigned-clock-rates: <not found>
Sending event 5/(unknown) to spy 'efi_disk add'
ofnode_read_prop: assigned-clock-rates: <not found>
Sending event 5/(unknown) to spy 'efi_disk add'
ofnode_read_prop: assigned-clock-rates: ofnode_read_u32_array: assigned-clock-rates: Looking for clock-controller@1800000
Looking for clock-controller@1800000
      - checking qcom_clk
   - result for clock-controller@1800000: qcom_clk (ret=0)
   - result for clock-controller@1800000: qcom_clk (ret=0)
Looking for clock-controller@1800000
Looking for clock-controller@1800000
      - checking qcom_clk
   - result for clock-controller@1800000: qcom_clk (ret=0)
   - result for clock-controller@1800000: qcom_clk (ret=0)
Looking for clock-controller@1800000
Looking for clock-controller@1800000
      - checking qcom_clk
   - result for clock-controller@1800000: qcom_clk (ret=0)
   - result for clock-controller@1800000: qcom_clk (ret=0)
Looking for phy
Looking for phy
   - result for phy: (none) (ret=-19)
   - result for phy: (none) (ret=-19)
Looking for ulpi
Looking for ulpi
   - result for ulpi: (none) (ret=-19)
   - result for ulpi: (none) (ret=-19)
Port not available.
dragonboard410c => 

Best Regards
jianfeng zhu
diff mbox series

Patch

diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
index ff336082e3..7cb3ae0849 100644
--- a/drivers/usb/host/ehci-msm.c
+++ b/drivers/usb/host/ehci-msm.c
@@ -47,6 +47,8 @@  static const struct ehci_ops msm_ehci_ops = {
 	.init_after_reset = msm_init_after_reset
 };
 
+static int ehci_usb_of_bind(struct udevice *dev);
+
 static int ehci_usb_probe(struct udevice *dev)
 {
 	struct msm_ehci_priv *p = dev_get_priv(dev);
@@ -54,6 +56,7 @@  static int ehci_usb_probe(struct udevice *dev)
 	struct usb_plat *plat = dev_get_plat(dev);
 	struct ehci_hccr *hccr;
 	struct ehci_hcor *hcor;
+	struct udevice *phydev;
 	int ret;
 
 	ret = clk_get_by_name(dev, "core", &p->core_clk);
@@ -80,6 +83,10 @@  static int ehci_usb_probe(struct udevice *dev)
 	hcor = (struct ehci_hcor *)((phys_addr_t)hccr +
 			HC_LENGTH(ehci_readl(&(hccr)->cr_capbase)));
 
+	ret = uclass_get_device_by_name(UCLASS_PHY, "msm8916_usbphy", &phydev);
+	if (ret)
+		ehci_usb_of_bind(dev);
+
 	ret = generic_setup_phy(dev, &p->phy, 0);
 	if (ret)
 		goto cleanup_iface;