The USB PHY mux switch depend on both USB2/USB3 PHY state and xHCI/xDCI
controller state. The role can't be switched if related states haven't
satisfied. That is why we need to poll the DUAL_ROLE_CFG1 to check if
the role switched successful or not.

So the SW_IDPIN and SW_VBUS_VALID bits can't determine the current
acting role.

This patch changes the logic for getting role logic.

Signed-off-by: Yu Wang <yu1.w...@intel.com>
---
 drivers/usb/roles/intel-xhci-usb-role-switch.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/roles/intel-xhci-usb-role-switch.c 
b/drivers/usb/roles/intel-xhci-usb-role-switch.c
index 1fb3dd0..c118c9a 100644
--- a/drivers/usb/roles/intel-xhci-usb-role-switch.c
+++ b/drivers/usb/roles/intel-xhci-usb-role-switch.c
@@ -110,14 +110,18 @@ static enum usb_role intel_xhci_usb_get_role(struct 
device *dev)
 
        pm_runtime_get_sync(dev);
        val = readl(data->base + DUAL_ROLE_CFG0);
-       pm_runtime_put(dev);
 
-       if (!(val & SW_IDPIN))
-               role = USB_ROLE_HOST;
-       else if (val & SW_VBUS_VALID)
-               role = USB_ROLE_DEVICE;
-       else
+       if ((val & SW_IDPIN) && !(val & SW_VBUS_VALID))
                role = USB_ROLE_NONE;
+       else {
+               val = readl(data->base + DUAL_ROLE_CFG1);
+               if (val & HOST_MODE)
+                       role = USB_ROLE_HOST;
+               else
+                       role = USB_ROLE_DEVICE;
+       }
+
+       pm_runtime_put(dev);
 
        return role;
 }
-- 
2.7.4

Reply via email to