summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/composite.c
diff options
context:
space:
mode:
authorElson Roy Serrao <quic_eserrao@quicinc.com>2023-03-25 00:47:57 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-03-29 11:27:00 +0300
commitb93c2a68f3d9dc98ec30dcb342ae47c1c8d09d18 (patch)
tree0ab2f0fef04383c702f06f478ba36e0ce964fc18 /drivers/usb/gadget/composite.c
parent79e94aa19736ec8f38ec02880eeec37cc5900bd8 (diff)
downloadlinux-b93c2a68f3d9dc98ec30dcb342ae47c1c8d09d18.tar.xz
usb: gadget: Properly configure the device for remote wakeup
The wakeup bit in the bmAttributes field indicates whether the device is configured for remote wakeup. But this field should be allowed to set only if the UDC supports such wakeup mechanism. So configure this field based on UDC capability. Also inform the UDC whether the device is configured for remote wakeup by implementing a gadget op. Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Signed-off-by: Elson Roy Serrao <quic_eserrao@quicinc.com> Link: https://lore.kernel.org/r/1679694482-16430-2-git-send-email-quic_eserrao@quicinc.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/gadget/composite.c')
-rw-r--r--drivers/usb/gadget/composite.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index f1ecd12b62c3..00c89571de2a 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -513,6 +513,19 @@ static u8 encode_bMaxPower(enum usb_device_speed speed,
return min(val, 900U) / 8;
}
+void check_remote_wakeup_config(struct usb_gadget *g,
+ struct usb_configuration *c)
+{
+ if (USB_CONFIG_ATT_WAKEUP & c->bmAttributes) {
+ /* Reset the rw bit if gadget is not capable of it */
+ if (!g->wakeup_capable && g->ops->set_remote_wakeup) {
+ WARN(c->cdev, "Clearing wakeup bit for config c.%d\n",
+ c->bConfigurationValue);
+ c->bmAttributes &= ~USB_CONFIG_ATT_WAKEUP;
+ }
+ }
+}
+
static int config_buf(struct usb_configuration *config,
enum usb_device_speed speed, void *buf, u8 type)
{
@@ -994,6 +1007,11 @@ static int set_config(struct usb_composite_dev *cdev,
power = min(power, 500U);
else
power = min(power, 900U);
+
+ if (USB_CONFIG_ATT_WAKEUP & c->bmAttributes)
+ usb_gadget_set_remote_wakeup(gadget, 1);
+ else
+ usb_gadget_set_remote_wakeup(gadget, 0);
done:
if (power <= USB_SELF_POWER_VBUS_MAX_DRAW)
usb_gadget_set_selfpowered(gadget);