To prevent VBUS contention, the am335x MUSB phy senses VBUS first before transitioning to host mode. However, for host-only mode, VBUS could be directly tied to 5V power rail which could prevent MUSB transitions to host mode. This change receives dr_mode of the controller then ignores the first VBUS sensing for host-only mode, so that MUSB can work in host mode event if VBUS is tied to 5V. Signed-off-by: Bin Liu <b-liu@xxxxxx> --- drivers/usb/phy/phy-am335x-control.c | 14 +++++++++++--- drivers/usb/phy/phy-am335x-control.h | 8 +++++--- drivers/usb/phy/phy-am335x.c | 10 +++++----- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/usb/phy/phy-am335x-control.c b/drivers/usb/phy/phy-am335x-control.c index 23fca51..42a1afe 100644 --- a/drivers/usb/phy/phy-am335x-control.c +++ b/drivers/usb/phy/phy-am335x-control.c @@ -4,6 +4,7 @@ #include <linux/of.h> #include <linux/io.h> #include <linux/delay.h> +#include <linux/usb/otg.h> #include "phy-am335x-control.h" struct am335x_control_usb { @@ -58,7 +59,8 @@ static void am335x_phy_wkup(struct phy_control *phy_ctrl, u32 id, bool on) spin_unlock(&usb_ctrl->lock); } -static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on) +static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, + enum usb_dr_mode dr_mode, bool on) { struct am335x_control_usb *usb_ctrl; u32 val; @@ -80,8 +82,14 @@ static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on) val = readl(usb_ctrl->phy_reg + reg); if (on) { - val &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN); - val |= USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN; + if (dr_mode == USB_DR_MODE_HOST) { + val &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN | + USBPHY_OTGVDET_EN); + val |= USBPHY_OTGSESSEND_EN; + } else { + val &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN); + val |= USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN; + } } else { val |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN; } diff --git a/drivers/usb/phy/phy-am335x-control.h b/drivers/usb/phy/phy-am335x-control.h index b96594d..e86b316 100644 --- a/drivers/usb/phy/phy-am335x-control.h +++ b/drivers/usb/phy/phy-am335x-control.h @@ -2,13 +2,15 @@ #define _AM335x_PHY_CONTROL_H_ struct phy_control { - void (*phy_power)(struct phy_control *phy_ctrl, u32 id, bool on); + void (*phy_power)(struct phy_control *phy_ctrl, u32 id, + enum usb_dr_mode dr_mode, bool on); void (*phy_wkup)(struct phy_control *phy_ctrl, u32 id, bool on); }; -static inline void phy_ctrl_power(struct phy_control *phy_ctrl, u32 id, bool on) +static inline void phy_ctrl_power(struct phy_control *phy_ctrl, u32 id, + enum usb_dr_mode dr_mode, bool on) { - phy_ctrl->phy_power(phy_ctrl, id, on); + phy_ctrl->phy_power(phy_ctrl, id, dr_mode, on); } static inline void phy_ctrl_wkup(struct phy_control *phy_ctrl, u32 id, bool on) diff --git a/drivers/usb/phy/phy-am335x.c b/drivers/usb/phy/phy-am335x.c index ee7e265..39b424f 100644 --- a/drivers/usb/phy/phy-am335x.c +++ b/drivers/usb/phy/phy-am335x.c @@ -24,7 +24,7 @@ static int am335x_init(struct usb_phy *phy) { struct am335x_phy *am_phy = dev_get_drvdata(phy->dev); - phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, true); + phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, am_phy->dr_mode, true); return 0; } @@ -32,7 +32,7 @@ static void am335x_shutdown(struct usb_phy *phy) { struct am335x_phy *am_phy = dev_get_drvdata(phy->dev); - phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, false); + phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, am_phy->dr_mode, false); } static int am335x_phy_probe(struct platform_device *pdev) @@ -80,7 +80,7 @@ static int am335x_phy_probe(struct platform_device *pdev) */ device_set_wakeup_enable(dev, false); - phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, false); + phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, am_phy->dr_mode, false); return 0; } @@ -110,7 +110,7 @@ static int am335x_phy_suspend(struct device *dev) if (device_may_wakeup(dev)) phy_ctrl_wkup(am_phy->phy_ctrl, am_phy->id, true); - phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, false); + phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, am_phy->dr_mode, false); return 0; } @@ -120,7 +120,7 @@ static int am335x_phy_resume(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct am335x_phy *am_phy = platform_get_drvdata(pdev); - phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, true); + phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, am_phy->dr_mode, true); if (device_may_wakeup(dev)) phy_ctrl_wkup(am_phy->phy_ctrl, am_phy->id, false); -- 1.8.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html