All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Glass <sjg@chromium.org>
To: Icenowy Zheng <icenowy@aosc.io>
Cc: Siva Mahadevan <me@svmhdvn.name>, u-boot@lists.denx.de
Subject: Re: [PATCH] phy: rockchip: inno-usb2: fix hang when multiple controllers exit
Date: Fri, 12 Nov 2021 15:40:21 -0700	[thread overview]
Message-ID: <CAPnjgZ1wfaS4gESHhEwDyr2LeWmwMDKuOimbEmg72PM22R8dKw@mail.gmail.com> (raw)
In-Reply-To: <c4513cb98e517afce27e6110fe4169ed2f1ddeec.camel@aosc.io>

Hi,

On Sat, 23 Oct 2021 at 12:19, Icenowy Zheng <icenowy@aosc.io> wrote:
>
> 在 2021-10-23星期六的 13:23 -0400,Siva Mahadevan写道:
> > Icenowy Zheng wrote:
> > > The OHCI and EHCI controllers are both bound to the same PHY. They
> > > will
> > > both do init and power_on operations when the controller is brought
> > > up
> > > and both do power_off and exit when the controller is stopped.
> > > However,
> > > the PHY uclass of U-Boot is not as sane as we thought -- they won't
> > > maintain a status mark for PHYs, and thus the functions of the PHYs
> > > could be called for multiple times. Calling init/power_on for
> > > multiple
> > > times have no severe problems, however calling power_off/exit for
> > > multiple times have a problem -- the first exit call will stop the
> > > PHY
> > > clock, and power_off/exit calls after it still trying to write to
> > > PHY
> > > registers. The write operation to PHY registers will fail because
> > > clock
> > > is already stopped.
> > >
> > > Adapt the count mechanism from phy-sun4i-usb to both init/exit and
> > > power_on/power_off functions to phy-rockchip-inno-usb2 to fix this
> > > problem. With this stopping USB controllers (manually or before
> > > booting
> > > a kernel) will work.
> > >
> > > Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> > > Fixes: ac97a9ece14e ("phy: rockchip: Add Rockchip USB2PHY driver")
> > > ---
> > >  drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 21
> > > +++++++++++++++++++
> > >  1 file changed, 21 insertions(+)
> > >
> > > diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> > > b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> > > index 62b8ba3a4a..be9cc99d90 100644
> > > --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> > > +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> > > @@ -62,6 +62,8 @@ struct rockchip_usb2phy {
> > >         void *reg_base;
> > >         struct clk phyclk;
> > >         const struct rockchip_usb2phy_cfg *phy_cfg;
> > > +       int init_count;
> > > +       int power_on_count;
> > >  };
> > >
> > >  static inline int property_enable(void *reg_base,
> > > @@ -92,6 +94,10 @@ static int rockchip_usb2phy_power_on(struct phy
> > > *phy)
> > >         struct rockchip_usb2phy *priv = dev_get_priv(parent);
> > >         const struct rockchip_usb2phy_port_cfg *port_cfg =
> > > us2phy_get_port(phy);
> > >
> > > +       priv->power_on_count++;
> > > +       if (priv->power_on_count != 1)
> > > +               return 0;
> > > +
> > >         property_enable(priv->reg_base, &port_cfg->phy_sus, false);
> > >
> > >         /* waiting for the utmi_clk to become stable */
> > > @@ -106,6 +112,10 @@ static int rockchip_usb2phy_power_off(struct
> > > phy *phy)
> > >         struct rockchip_usb2phy *priv = dev_get_priv(parent);
> > >         const struct rockchip_usb2phy_port_cfg *port_cfg =
> > > us2phy_get_port(phy);
> > >
> > > +       priv->power_on_count--;
> > > +       if (priv->power_on_count != 0)
> > > +               return 0;
> > > +
> > >         property_enable(priv->reg_base, &port_cfg->phy_sus, true);
> > >
> > >         return 0;
> > > @@ -118,6 +128,10 @@ static int rockchip_usb2phy_init(struct phy
> > > *phy)
> > >         const struct rockchip_usb2phy_port_cfg *port_cfg =
> > > us2phy_get_port(phy);
> > >         int ret;
> > >
> > > +       priv->init_count++;
> > > +       if (priv->init_count != 1)
> > > +               return 0;
> > > +
> > >         ret = clk_enable(&priv->phyclk);
> > >         if (ret) {
> > >                 dev_err(phy->dev, "failed to enable phyclk
> > > (ret=%d)\n", ret);
> > > @@ -140,6 +154,10 @@ static int rockchip_usb2phy_exit(struct phy
> > > *phy)
> > >         struct udevice *parent = dev_get_parent(phy->dev);
> > >         struct rockchip_usb2phy *priv = dev_get_priv(parent);
> > >
> > > +       priv->init_count--;
> > > +       if (priv->init_count != 0)
> > > +               return 0;
> > > +
> > >         clk_disable(&priv->phyclk);
> > >
> > >         return 0;
> > > @@ -212,6 +230,9 @@ static int rockchip_usb2phy_probe(struct
> > > udevice *dev)
> > >                 return ret;
> > >         }
> > >
> > > +       priv->power_on_count = 0;
> > > +       priv->init_count = 0;
> > > +
> > >         return 0;
> > >  }
> > >
> > > --
> > > 2.30.2
> >
> > Are there any plans of submitting this patch to u-boot mainline? I
> > recently got a pinebook pro and got u-boot mainline working as-is
> > plus
> > this patch. I can confirm that this fixes the issue for me.
>
> The current maintainer wants a fix in PHY framework instead of the
> specific driver, but I am recently not interested in fixing it (because
> PBP is my daily driver now, and I don't dare to do dangerous BL
> development that will lead to regression on it).
>

From what I can tell the maintainer is correct - the PHY uclass should
be updated as clk was. There is a sandbox driver for the PHY uclass so
you can add a test for it the new behaviour. I don't think there is
too much risk of a regression, but in any case it seems like the
correct fix to me.

Regards,
Simon

      reply	other threads:[~2021-11-12 22:40 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-06 15:10 [PATCH] phy: rockchip: inno-usb2: fix hang when multiple controllers exit Icenowy Zheng
2021-04-06 23:11 ` Peter Robinson
2021-04-07  6:42 ` Frank Wang
2021-04-07  6:43   ` Icenowy Zheng
2021-04-07  7:28     ` Frank Wang
2021-04-07  7:31       ` Icenowy Zheng
2021-07-02 12:55         ` Grant Likely
2021-10-23 17:23 ` Siva Mahadevan
2021-10-23 18:19   ` Icenowy Zheng
2021-11-12 22:40     ` Simon Glass [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAPnjgZ1wfaS4gESHhEwDyr2LeWmwMDKuOimbEmg72PM22R8dKw@mail.gmail.com \
    --to=sjg@chromium.org \
    --cc=icenowy@aosc.io \
    --cc=me@svmhdvn.name \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.