All of lore.kernel.org
 help / color / mirror / Atom feed
* dwc2: remote wakeup implementation
@ 2021-08-05  2:40 Maxim Devaev
  0 siblings, 0 replies; only message in thread
From: Maxim Devaev @ 2021-08-05  2:40 UTC (permalink / raw)
  To: linux-usb, hminas, gregkh

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,
 };
 
 /**

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2021-08-05  2:40 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-08-05  2:40 dwc2: remote wakeup implementation Maxim Devaev

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.