summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/phy/phy-mxs-usb.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c
index 305a3134bfa9..56602e905dc0 100644
--- a/drivers/usb/phy/phy-mxs-usb.c
+++ b/drivers/usb/phy/phy-mxs-usb.c
@@ -40,6 +40,7 @@
#define BM_USBPHY_CTRL_SFTRST BIT(31)
#define BM_USBPHY_CTRL_CLKGATE BIT(30)
+#define BM_USBPHY_CTRL_OTG_ID_VALUE BIT(27)
#define BM_USBPHY_CTRL_ENAUTOSET_USBCLKS BIT(26)
#define BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE BIT(25)
#define BM_USBPHY_CTRL_ENVBUSCHG_WKUP BIT(23)
@@ -129,7 +130,8 @@ static const struct mxs_phy_data imx6sl_phy_data = {
};
static const struct mxs_phy_data imx6sx_phy_data = {
- .flags = MXS_PHY_HAS_ANATOP,
+ .flags = MXS_PHY_HAS_ANATOP |
+ MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS,
};
static const struct of_device_id mxs_phy_dt_ids[] = {
@@ -221,11 +223,6 @@ static bool mxs_phy_get_vbus_status(struct mxs_phy *mxs_phy)
return false;
}
-#ifdef CONFIG_USB_OTG_FSM
-static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
-{
-}
-#else
static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect)
{
void __iomem *base = mxs_phy->phy.io_priv;
@@ -258,6 +255,18 @@ static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect)
usleep_range(500, 1000);
}
+static bool mxs_phy_is_otg_host(struct mxs_phy *mxs_phy)
+{
+ void __iomem *base = mxs_phy->phy.io_priv;
+ u32 phyctrl = readl(base + HW_USBPHY_CTRL);
+
+ if (IS_ENABLED(CONFIG_USB_OTG) &&
+ !(phyctrl & BM_USBPHY_CTRL_OTG_ID_VALUE))
+ return true;
+
+ return false;
+}
+
static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
{
bool vbus_is_on = false;
@@ -272,13 +281,12 @@ static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
vbus_is_on = mxs_phy_get_vbus_status(mxs_phy);
- if (on && !vbus_is_on)
+ if (on && !vbus_is_on && !mxs_phy_is_otg_host(mxs_phy))
__mxs_phy_disconnect_line(mxs_phy, true);
else
__mxs_phy_disconnect_line(mxs_phy, false);
}
-#endif
static void mxs_phy_enable_ldo_in_suspend(struct mxs_phy *mxs_phy, bool on)
{