From: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
To: Fabrice Gasnier <fabrice.gasnier@foss.st.com>,
"gregkh@linuxfoundation.org" <gregkh@linuxfoundation.org>,
"robh+dt@kernel.org" <robh+dt@kernel.org>
Cc: "linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"linux-stm32@st-md-mailman.stormreply.com"
<linux-stm32@st-md-mailman.stormreply.com>,
"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>,
"amelie.delaunay@foss.st.com" <amelie.delaunay@foss.st.com>,
"alexandre.torgue@foss.st.com" <alexandre.torgue@foss.st.com>
Subject: Re: [PATCH 3/3] usb: dwc2: drd: restore role and overrides upon resume
Date: Thu, 16 Dec 2021 10:26:34 +0000 [thread overview]
Message-ID: <6f7adaf0-4894-4e7b-6c2b-757e25a1f39b@synopsys.com> (raw)
In-Reply-To: <1638806203-6624-4-git-send-email-fabrice.gasnier@foss.st.com>
On 12/6/2021 7:56 PM, Fabrice Gasnier wrote:
> Override enable bits may not be restored when going to low power mode
> (e.g. when in DWC2_POWER_DOWN_PARAM_NONE).
> These bits are set when probing/initializing drd (role switch). Restore
> them upon resume from low power mode (in case these have been lost).
>
> To achieve this, the last known role is restored upon resume. And the
> override enable bits are always set when configuring aval, bval and vbval.
>
> When resuming, forcing the role should be done only once, or this can cause
> port changes in HOST mode for instance.
> So, only restore FORCEDEVMODE/FORCEHOSTMODE when role_sw is unused
>
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
> ---
> drivers/usb/dwc2/drd.c | 38 ++++++++++++++++++++++++++++++++++++--
> drivers/usb/dwc2/platform.c | 10 ++++++----
> 2 files changed, 42 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/usb/dwc2/drd.c b/drivers/usb/dwc2/drd.c
> index 4f453ec..1b39c47 100644
> --- a/drivers/usb/dwc2/drd.c
> +++ b/drivers/usb/dwc2/drd.c
> @@ -13,6 +13,10 @@
> #include <linux/usb/role.h>
> #include "core.h"
>
> +#define dwc2_ovr_gotgctl(gotgctl) \
> + ((gotgctl) |= GOTGCTL_BVALOEN | GOTGCTL_AVALOEN | GOTGCTL_VBVALOEN | \
> + GOTGCTL_DBNCE_FLTR_BYPASS)
> +
> static void dwc2_ovr_init(struct dwc2_hsotg *hsotg)
> {
> unsigned long flags;
> @@ -21,8 +25,7 @@ static void dwc2_ovr_init(struct dwc2_hsotg *hsotg)
> spin_lock_irqsave(&hsotg->lock, flags);
>
> gotgctl = dwc2_readl(hsotg, GOTGCTL);
> - gotgctl |= GOTGCTL_BVALOEN | GOTGCTL_AVALOEN | GOTGCTL_VBVALOEN;
> - gotgctl |= GOTGCTL_DBNCE_FLTR_BYPASS;
> + dwc2_ovr_gotgctl(gotgctl);
> gotgctl &= ~(GOTGCTL_BVALOVAL | GOTGCTL_AVALOVAL | GOTGCTL_VBVALOVAL);
> if (hsotg->role_sw_default_mode == USB_DR_MODE_HOST)
> gotgctl |= GOTGCTL_AVALOVAL | GOTGCTL_VBVALOVAL;
> @@ -44,6 +47,9 @@ static int dwc2_ovr_avalid(struct dwc2_hsotg *hsotg, bool valid)
> (!valid && !(gotgctl & GOTGCTL_ASESVLD)))
> return -EALREADY;
>
> + /* Always enable overrides to handle the resume case */
> + dwc2_ovr_gotgctl(gotgctl);
> +
> gotgctl &= ~GOTGCTL_BVALOVAL;
> if (valid)
> gotgctl |= GOTGCTL_AVALOVAL | GOTGCTL_VBVALOVAL;
> @@ -63,6 +69,9 @@ static int dwc2_ovr_bvalid(struct dwc2_hsotg *hsotg, bool valid)
> (!valid && !(gotgctl & GOTGCTL_BSESVLD)))
> return -EALREADY;
>
> + /* Always enable overrides to handle the resume case */
> + dwc2_ovr_gotgctl(gotgctl);
> +
> gotgctl &= ~GOTGCTL_AVALOVAL;
> if (valid)
> gotgctl |= GOTGCTL_BVALOVAL | GOTGCTL_VBVALOVAL;
> @@ -196,6 +205,31 @@ void dwc2_drd_suspend(struct dwc2_hsotg *hsotg)
> void dwc2_drd_resume(struct dwc2_hsotg *hsotg)
> {
> u32 gintsts, gintmsk;
> + enum usb_role role;
> +
> + if (hsotg->role_sw) {
> + /* get last known role (as the get ops isn't implemented by this driver) */
> + role = usb_role_switch_get_role(hsotg->role_sw);
> +
> + if (role == USB_ROLE_NONE) {
> + if (hsotg->role_sw_default_mode == USB_DR_MODE_HOST)
> + role = USB_ROLE_HOST;
> + else if (hsotg->role_sw_default_mode == USB_DR_MODE_PERIPHERAL)
> + role = USB_ROLE_DEVICE;
> + }
> +
> + /* restore last role that may have been lost */
> + if (role == USB_ROLE_HOST)
> + dwc2_ovr_avalid(hsotg, true);
> + else if (role == USB_ROLE_DEVICE)
> + dwc2_ovr_bvalid(hsotg, true);
> +
> + dwc2_force_mode(hsotg, role == USB_ROLE_HOST);
> +
> + dev_dbg(hsotg->dev, "resuming %s-session valid\n",
> + role == USB_ROLE_NONE ? "No" :
> + role == USB_ROLE_HOST ? "A" : "B");
> + }
>
> if (hsotg->role_sw && !hsotg->params.external_id_pin_ctl) {
> gintsts = dwc2_readl(hsotg, GINTSTS);
> diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
> index c8f18f3..e6a7fc0 100644
> --- a/drivers/usb/dwc2/platform.c
> +++ b/drivers/usb/dwc2/platform.c
> @@ -748,10 +748,12 @@ static int __maybe_unused dwc2_resume(struct device *dev)
> spin_unlock_irqrestore(&dwc2->lock, flags);
> }
>
> - /* Need to restore FORCEDEVMODE/FORCEHOSTMODE */
> - dwc2_force_dr_mode(dwc2);
> -
> - dwc2_drd_resume(dwc2);
> + if (!dwc2->role_sw) {
> + /* Need to restore FORCEDEVMODE/FORCEHOSTMODE */
> + dwc2_force_dr_mode(dwc2);
> + } else {
> + dwc2_drd_resume(dwc2);
> + }
>
> if (dwc2_is_device_mode(dwc2))
> ret = dwc2_hsotg_resume(dwc2);
prev parent reply other threads:[~2021-12-16 10:26 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-06 15:56 [PATCH 0/3] usb: dwc2: drd: add support for role-switch-default-mode Fabrice Gasnier
2021-12-06 15:56 ` [PATCH 1/3] dt-bindings: usb: document role-switch-default-mode property in dwc2 Fabrice Gasnier
2021-12-13 22:16 ` Rob Herring
2021-12-06 15:56 ` [PATCH 2/3] usb: dwc2: drd: add role-switch-default-node support Fabrice Gasnier
2021-12-16 10:26 ` Minas Harutyunyan
2021-12-06 15:56 ` [PATCH 3/3] usb: dwc2: drd: restore role and overrides upon resume Fabrice Gasnier
2021-12-16 10:26 ` Minas Harutyunyan [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=6f7adaf0-4894-4e7b-6c2b-757e25a1f39b@synopsys.com \
--to=minas.harutyunyan@synopsys.com \
--cc=alexandre.torgue@foss.st.com \
--cc=amelie.delaunay@foss.st.com \
--cc=devicetree@vger.kernel.org \
--cc=fabrice.gasnier@foss.st.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-stm32@st-md-mailman.stormreply.com \
--cc=linux-usb@vger.kernel.org \
--cc=robh+dt@kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®