All of lore.kernel.org
 help / color / mirror / Atom feed
From: Maxim Devaev <mdevaev@gmail.com>
To: linux-usb@vger.kernel.org, hminas@synopsys.com,
	gregkh@linuxfoundation.org
Subject: dwc2: remote wakeup implementation
Date: Thu, 5 Aug 2021 05:40:06 +0300	[thread overview]
Message-ID: <20210805054006.665e475e@reki> (raw)

Hello.

The dwc3 driver in gadget mode has the ability to send
a remote wakeup signal to the host by writing 1 to the srp file:

echo 1 > /sys/class/udc/XXX/srp

I am trying to implement the same feature for dwc2, but I ran
into a problem. My naive and clumsy implementation is able
to wake up the host, but after that dwc2 stops processing
any interrupts and the gadget stops working.

At the same time, if I send the host to suspend, and then
it is awakened independently (for example, using the hardware
keyboard), then I see that dwc2 handles interrupts
and starts working again. I used the protocol analyzer
and made sure that the gadget with dwc2 is really correctly
suspended and wakes up.

I suppose remote wakeup signaling causes the controller
to switch to some incomprehensible (for me) state, and I need
to do something so that everything works again and dwc2
can receive a wake-up event from the host after signaling.

I don't have any DesignWare documentation, so I hope someone
can help me. Thanks.

diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index c581ee41a..14dfb678a 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -4660,6 +4660,21 @@ static int dwc2_hsotg_vbus_draw(struct usb_gadget *gadget, unsigned int mA)
 	return usb_phy_set_power(hsotg->uphy, mA);
 }
 
+static int dwc2_hsotg_wakeup(struct usb_gadget *gadget)
+{
+	struct dwc2_hsotg *hsotg = to_hsotg(gadget);
+	unsigned long flags;
+
+	spin_lock_irqsave(&hsotg->lock, flags);
+
+	dwc2_set_bit(hsotg, DCTL, DCTL_RMTWKUPSIG);
+	mdelay(10);
+	dwc2_clear_bit(hsotg, DCTL, DCTL_RMTWKUPSIG);
+
+	spin_unlock_irqrestore(&hsotg->lock, flags);
+	return 0;
+}
+
 static const struct usb_gadget_ops dwc2_hsotg_gadget_ops = {
 	.get_frame	= dwc2_hsotg_gadget_getframe,
 	.set_selfpowered	= dwc2_hsotg_set_selfpowered,
@@ -4668,6 +4683,7 @@ static const struct usb_gadget_ops dwc2_hsotg_gadget_ops = {
 	.pullup                 = dwc2_hsotg_pullup,
 	.vbus_session		= dwc2_hsotg_vbus_session,
 	.vbus_draw		= dwc2_hsotg_vbus_draw,
+	.wakeup			= dwc2_hsotg_wakeup,
 };
 
 /**

                 reply	other threads:[~2021-08-05  2:40 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20210805054006.665e475e@reki \
    --to=mdevaev@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=hminas@synopsys.com \
    --cc=linux-usb@vger.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 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.