diff mbox series

[2/3] usb: phy: mxs: fix getting wrong state with mxs_phy_is_otg_host()

Message ID 20230627110353.1879477-2-xu.yang_2@nxp.com
State New
Headers show
Series [1/3] usb: chipidea: add USB PHY event | expand

Commit Message

Xu Yang June 27, 2023, 11:03 a.m. UTC
The function mxs_phy_is_otg_host() will return true if OTG_ID_VALUE is
0 at USBPHY_CTRL register. However, OTG_ID_VALUE will not reflect the real
state if the ID pin is float, such as Host-only or Type-C cases. The value
of OTG_ID_VALUE is always 1 which means device mode.
This patch will fix the issue by judging the current mode based on
last_event. The controller will update last_event in time.

Fixes: 7b09e67639d6 ("usb: phy: mxs: refine mxs_phy_disconnect_line")
Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
---
 drivers/usb/phy/phy-mxs-usb.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

Comments

Francesco Dolcini July 26, 2023, 6:08 a.m. UTC | #1
On Tue, Jun 27, 2023 at 07:03:52PM +0800, Xu Yang wrote:
> The function mxs_phy_is_otg_host() will return true if OTG_ID_VALUE is
> 0 at USBPHY_CTRL register. However, OTG_ID_VALUE will not reflect the real
> state if the ID pin is float, such as Host-only or Type-C cases. The value
> of OTG_ID_VALUE is always 1 which means device mode.
> This patch will fix the issue by judging the current mode based on
> last_event. The controller will update last_event in time.
> 
> Fixes: 7b09e67639d6 ("usb: phy: mxs: refine mxs_phy_disconnect_line")
> Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
> ---
>  drivers/usb/phy/phy-mxs-usb.c | 10 ++--------
>  1 file changed, 2 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c
> index 036bb58a3a71..f484c79efa6c 100644
> --- a/drivers/usb/phy/phy-mxs-usb.c
> +++ b/drivers/usb/phy/phy-mxs-usb.c
> @@ -388,14 +388,8 @@ static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect)
>  
>  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;
> +	return IS_ENABLED(CONFIG_USB_OTG) &&
> +		mxs_phy->phy.last_event == USB_EVENT_ID;

The logic here is not working when CONFIG_USB_OTG, should we always
return true when !IS_ENABLED(CONFIG_USB_OTG) ?

so something like 

if (!IS_ENABLED(CONFIG_USB_OTG))
	return true;

return mxs_phy->phy.last_event == USB_EVENT_ID;


?
Xu Yang July 26, 2023, 6:40 a.m. UTC | #2
> On Tue, Jun 27, 2023 at 07:03:52PM +0800, Xu Yang wrote:
> > The function mxs_phy_is_otg_host() will return true if OTG_ID_VALUE is
> > 0 at USBPHY_CTRL register. However, OTG_ID_VALUE will not reflect the real
> > state if the ID pin is float, such as Host-only or Type-C cases. The value
> > of OTG_ID_VALUE is always 1 which means device mode.
> > This patch will fix the issue by judging the current mode based on
> > last_event. The controller will update last_event in time.
> >
> > Fixes: 7b09e67639d6 ("usb: phy: mxs: refine mxs_phy_disconnect_line")
> > Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
> > ---
> >  drivers/usb/phy/phy-mxs-usb.c | 10 ++--------
> >  1 file changed, 2 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c
> > index 036bb58a3a71..f484c79efa6c 100644
> > --- a/drivers/usb/phy/phy-mxs-usb.c
> > +++ b/drivers/usb/phy/phy-mxs-usb.c
> > @@ -388,14 +388,8 @@ static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect)
> >
> >  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;
> > +     return IS_ENABLED(CONFIG_USB_OTG) &&
> > +             mxs_phy->phy.last_event == USB_EVENT_ID;
> 
> The logic here is not working when CONFIG_USB_OTG, should we always
> return true when !IS_ENABLED(CONFIG_USB_OTG) ?

No. 

> 
> so something like
> 
> if (!IS_ENABLED(CONFIG_USB_OTG))
>         return true;
> 

Below code should be enough. We don't need to judge 
CONFIG_USB_OTG here since last_event always be updated
when starting new role.

> return mxs_phy->phy.last_event == USB_EVENT_ID;
> 
> 
> ?
diff mbox series

Patch

diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c
index 036bb58a3a71..f484c79efa6c 100644
--- a/drivers/usb/phy/phy-mxs-usb.c
+++ b/drivers/usb/phy/phy-mxs-usb.c
@@ -388,14 +388,8 @@  static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect)
 
 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;
+	return IS_ENABLED(CONFIG_USB_OTG) &&
+		mxs_phy->phy.last_event == USB_EVENT_ID;
 }
 
 static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)