aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/chipidea/udc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/chipidea/udc.c')
-rw-r--r--drivers/usb/chipidea/udc.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 4fe18ce3bd5a..ff451048c1ac 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -819,8 +819,8 @@ __acquires(hwep->lock)
}
if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
- /* Assume that device is bus powered for now. */
- *(u16 *)req->buf = ci->remote_wakeup << 1;
+ *(u16 *)req->buf = (ci->remote_wakeup << 1) |
+ ci->gadget.is_selfpowered;
} else if ((setup->bRequestType & USB_RECIP_MASK) \
== USB_RECIP_ENDPOINT) {
dir = (le16_to_cpu(setup->wIndex) & USB_ENDPOINT_DIR_MASK) ?
@@ -1520,6 +1520,19 @@ static int ci_udc_vbus_draw(struct usb_gadget *_gadget, unsigned ma)
return -ENOTSUPP;
}
+static int ci_udc_selfpowered(struct usb_gadget *_gadget, int is_on)
+{
+ struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget);
+ struct ci_hw_ep *hwep = ci->ep0in;
+ unsigned long flags;
+
+ spin_lock_irqsave(hwep->lock, flags);
+ _gadget->is_selfpowered = (is_on != 0);
+ spin_unlock_irqrestore(hwep->lock, flags);
+
+ return 0;
+}
+
/* Change Data+ pullup status
* this func is used by usb_gadget_connect/disconnet
*/
@@ -1549,6 +1562,7 @@ static int ci_udc_stop(struct usb_gadget *gadget);
static const struct usb_gadget_ops usb_gadget_ops = {
.vbus_session = ci_udc_vbus_session,
.wakeup = ci_udc_wakeup,
+ .set_selfpowered = ci_udc_selfpowered,
.pullup = ci_udc_pullup,
.vbus_draw = ci_udc_vbus_draw,
.udc_start = ci_udc_start,