Commit 1a0808cb authored by John Keeping's avatar John Keeping Committed by Felipe Balbi
Browse files

usb: dwc2: Implement set_selfpowered()



dwc2 always reports as self-powered in response to a device status
request.  Implement the set_selfpowered() operations so that the gadget
can report as bus-powered when appropriate.

This is modelled on the dwc3 implementation.

Acked-by: default avatarMinas Harutyunyan <hminas@synopsys.com>
Signed-off-by: default avatarJohn Keeping <john@metanate.com>
Signed-off-by: default avatarFelipe Balbi <balbi@kernel.org>
parent 201c26c0
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -1646,7 +1646,8 @@ static int dwc2_hsotg_process_req_status(struct dwc2_hsotg *hsotg,

	switch (ctrl->bRequestType & USB_RECIP_MASK) {
	case USB_RECIP_DEVICE:
		status = 1 << USB_DEVICE_SELF_POWERED;
		status = hsotg->gadget.is_selfpowered <<
			 USB_DEVICE_SELF_POWERED;
		status |= hsotg->remote_wakeup_allowed <<
			  USB_DEVICE_REMOTE_WAKEUP;
		reply = cpu_to_le16(status);
@@ -4527,6 +4528,26 @@ static int dwc2_hsotg_gadget_getframe(struct usb_gadget *gadget)
	return dwc2_hsotg_read_frameno(to_hsotg(gadget));
}

/**
 * dwc2_hsotg_set_selfpowered - set if device is self/bus powered
 * @gadget: The usb gadget state
 * @is_selfpowered: Whether the device is self-powered
 *
 * Set if the device is self or bus powered.
 */
static int dwc2_hsotg_set_selfpowered(struct usb_gadget *gadget,
				      int is_selfpowered)
{
	struct dwc2_hsotg *hsotg = to_hsotg(gadget);
	unsigned long flags;

	spin_lock_irqsave(&hsotg->lock, flags);
	gadget->is_selfpowered = !!is_selfpowered;
	spin_unlock_irqrestore(&hsotg->lock, flags);

	return 0;
}

/**
 * dwc2_hsotg_pullup - connect/disconnect the USB PHY
 * @gadget: The usb gadget state
@@ -4618,6 +4639,7 @@ static int dwc2_hsotg_vbus_draw(struct usb_gadget *gadget, unsigned int mA)

static const struct usb_gadget_ops dwc2_hsotg_gadget_ops = {
	.get_frame	= dwc2_hsotg_gadget_getframe,
	.set_selfpowered	= dwc2_hsotg_set_selfpowered,
	.udc_start		= dwc2_hsotg_udc_start,
	.udc_stop		= dwc2_hsotg_udc_stop,
	.pullup                 = dwc2_hsotg_pullup,