Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit abe7752f authored by Shimrit Malichi's avatar Shimrit Malichi Committed by Tarun Gupta
Browse files

usb: gadget: Add link power management support



Link Power Management (a.k.a. L1) is similar to the existing usb bus
suspend/resume/remote-wakeup, but has transitional latencies of tens
of microseconds between power states (instead of three to greater than
20 millisecond latencies of the USB 2.0 suspend/resume).

Change-Id: I8ae493534702e658c24f384a6b705b08e9ea9d05
Signed-off-by: default avatarShimrit Malichi <smalichi@codeaurora.org>
Signed-off-by: default avatarTarun Gupta <tarung@codeaurora.org>
parent f0331928
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -599,6 +599,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
	ci->imx28_write_fix = !!(ci->platdata->flags &
		CI_HDRC_IMX28_WRITE_FIX);

	ci->gadget.l1_supported = ci->platdata->l1_supported;

	ret = hw_device_init(ci, base);
	if (ret < 0) {
		dev_err(dev, "can't initialize hardware\n");
+37 −28
Original line number Diff line number Diff line
@@ -643,7 +643,8 @@ static int bos_desc(struct usb_composite_dev *cdev)

	/*
	 * A SuperSpeed device shall include the USB2.0 extension descriptor
	 * and shall support LPM when operating in USB2.0 HS mode.
	 * and shall support LPM when operating in USB2.0 HS mode, as well as
	 * a HS device when operating in USB2.1 HS mode.
	 */
	usb_ext = cdev->req->buf + le16_to_cpu(bos->wTotalLength);
	bos->bNumDeviceCaps++;
@@ -653,9 +654,10 @@ static int bos_desc(struct usb_composite_dev *cdev)
	usb_ext->bDevCapabilityType = USB_CAP_TYPE_EXT;
	usb_ext->bmAttributes = cpu_to_le32(USB_LPM_SUPPORT | USB_BESL_SUPPORT);

	if (gadget_is_superspeed(cdev->gadget)) {
		/*
	 * The Superspeed USB Capability descriptor shall be implemented by all
	 * SuperSpeed devices.
		 * The Superspeed USB Capability descriptor shall be
		 * implemented by all SuperSpeed devices.
		 */
		ss_cap = cdev->req->buf + le16_to_cpu(bos->wTotalLength);
		bos->bNumDeviceCaps++;
@@ -672,14 +674,17 @@ static int bos_desc(struct usb_composite_dev *cdev)

		/* Get Controller configuration */
		if (cdev->gadget->ops->get_config_params)
		cdev->gadget->ops->get_config_params(&dcd_config_params);
			cdev->gadget->ops->get_config_params
				(&dcd_config_params);
		else {
		dcd_config_params.bU1devExitLat = USB_DEFAULT_U1_DEV_EXIT_LAT;
			dcd_config_params.bU1devExitLat =
				USB_DEFAULT_U1_DEV_EXIT_LAT;
			dcd_config_params.bU2DevExitLat =
				cpu_to_le16(USB_DEFAULT_U2_DEV_EXIT_LAT);
		}
		ss_cap->bU1devExitLat = dcd_config_params.bU1devExitLat;
		ss_cap->bU2DevExitLat = dcd_config_params.bU2DevExitLat;
	}

	return le16_to_cpu(bos->wTotalLength);
}
@@ -1619,6 +1624,9 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
				} else {
					cdev->desc.bcdUSB = cpu_to_le16(0x0210);
				}
			} else if (gadget->l1_supported) {
				cdev->desc.bcdUSB = cpu_to_le16(0x0210);
				DBG(cdev, "Config HS device with LPM(L1)\n");
			}

			value = min(w_length, (u16) sizeof cdev->desc);
@@ -1649,7 +1657,8 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
				value = min(w_length, (u16) value);
			break;
		case USB_DT_BOS:
			if (gadget_is_superspeed(gadget)) {
			if (gadget_is_superspeed(gadget) ||
				gadget->l1_supported) {
				value = bos_desc(cdev);
				value = min(w_length, (u16) value);
			}
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ struct ci_hdrc_platform_data {
	void	(*notify_event) (struct ci_hdrc *ci, unsigned event);
	struct regulator	*reg_vbus;
	bool			tpl_support;
	bool			l1_supported;
};

/* Default offset of capability registers */
+1 −0
Original line number Diff line number Diff line
@@ -585,6 +585,7 @@ struct usb_gadget {
	u32				xfer_isr_count;
	u8				usb_core_id;
	bool				streaming_enabled;
	bool				l1_supported;
};
#define work_to_gadget(w)	(container_of((w), struct usb_gadget, work))