diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/phy/phy-mxs-usb.c | 24 |
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) { |