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

Commit 15525bb9 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: gsi: Retry USB function wakeup if USB is into low power mode"

parents 8c903957 718f2b7a
Loading
Loading
Loading
Loading
+49 −11
Original line number Diff line number Diff line
@@ -163,6 +163,8 @@ static int gsi_wakeup_host(struct f_gsi *gsi)
	if ((gadget->speed >= USB_SPEED_SUPER) && (gsi->func_is_suspended)) {
		log_event_dbg("%s: Calling usb_func_wakeup", __func__);
		ret = usb_func_wakeup(func);
		if (ret == -EAGAIN)
			gsi->func_wakeup_pending = true;
	} else {
		log_event_dbg("%s: Calling usb_gadget_wakeup", __func__);
		ret = usb_gadget_wakeup(gadget);
@@ -1880,18 +1882,44 @@ static int queue_notification_request(struct f_gsi *gsi)
{
	int ret;
	unsigned long flags;
	struct usb_function *func = &gsi->function;
	struct usb_request *req = gsi->c_port.notify_req;
	struct usb_ep *ep = gsi->c_port.notify;
	struct usb_gadget *gadget = func->config->cdev->gadget;

	if (!gsi->func_is_suspended) {
		ret = usb_ep_queue(gsi->c_port.notify,
				   gsi->c_port.notify_req, GFP_ATOMIC);
	} else {
		if (gsi->func_wakeup_allowed)
			ret = usb_func_wakeup(&gsi->function);
		else
			ret = -EOPNOTSUPP;
	if (gsi->c_port.is_suspended) {
		/*For remote wakeup, queue the req from gsi_resume*/
		spin_lock_irqsave(&gsi->c_port.lock, flags);
		gsi->c_port.notify_req_queued = false;
		spin_unlock_irqrestore(&gsi->c_port.lock, flags);

		if (gsi->rwake_inprogress) {
			log_event_dbg("%s remote-wakeup in progress\n",
							__func__);
			return -EBUSY;
		}

		if (!usb_gsi_remote_wakeup_allowed(func)) {
			log_event_dbg("%s remote-wakeup not capable\n",
							__func__);
			return -EOPNOTSUPP;
		}

	if (ret < 0 || gsi->func_is_suspended) {
		log_event_dbg("%s wakeup host\n", __func__);
		if (gadget->speed >= USB_SPEED_SUPER
		    && gsi->func_is_suspended) {
			ret = usb_func_wakeup(func);
			if (ret == -EAGAIN)
				gsi->func_wakeup_pending = true;
		} else
			ret = usb_gadget_wakeup(gadget);

		gsi->rwake_inprogress = true;
		return ret;
	}

	ret = usb_ep_queue(ep, req, GFP_ATOMIC);
	if (ret < 0) {
		spin_lock_irqsave(&gsi->c_port.lock, flags);
		gsi->c_port.notify_req_queued = false;
		spin_unlock_irqrestore(&gsi->c_port.lock, flags);
@@ -2523,6 +2551,8 @@ static int gsi_set_alt(struct usb_function *f, unsigned int intf,
				gsi->data_id, gsi->data_interface_up);
	}

	gsi->c_port.is_suspended = false;
	gsi->func_wakeup_pending = false;
	atomic_set(&gsi->connected, 1);

	/* send 0 len pkt to qti to notify state change */
@@ -2606,6 +2636,7 @@ static void gsi_suspend(struct usb_function *f)
		return;
	}

	gsi->c_port.is_suspended = true;
	block_db = true;
	usb_gsi_ep_op(gsi->d_port.in_ep, (void *)&block_db,
			GSI_EP_OP_SET_CLR_BLOCK_DBL);
@@ -2636,8 +2667,13 @@ static void gsi_resume(struct usb_function *f)
	 * canceled. In this case resume is done by a Function Resume request.
	 */
	if ((cdev->gadget->speed >= USB_SPEED_SUPER) &&
		gsi->func_is_suspended)
		gsi->func_is_suspended) {
		if (gsi->func_wakeup_pending) {
			usb_func_wakeup(&gsi->function);
			gsi->func_wakeup_pending = false;
		}
		return;
	}

	/* Keep timer enabled if user enabled using debugfs */
	if (!gsi->debugfs_rw_timer_enable)
@@ -2646,6 +2682,8 @@ static void gsi_resume(struct usb_function *f)
	if (gsi->c_port.notify && !gsi->c_port.notify->desc)
		config_ep_by_speed(cdev->gadget, f, gsi->c_port.notify);

	gsi->c_port.is_suspended = false;

	/* Check any pending cpkt, and queue immediately on resume */
	gsi_ctrl_send_notification(gsi);

@@ -3304,7 +3342,7 @@ static void gsi_unbind(struct usb_configuration *c, struct usb_function *f)
	rmnet_gsi_string_defs[0].id = 0;
	mbim_gsi_string_defs[0].id  = 0;
	qdss_gsi_string_defs[0].id  = 0;

	gsi->func_wakeup_pending = false;
	if (gsi->prot_id == IPA_USB_RNDIS) {
		gsi->d_port.sm_state = STATE_UNINITIALIZED;
		rndis_deregister(gsi->params);
+2 −0
Original line number Diff line number Diff line
@@ -202,6 +202,7 @@ struct gsi_ctrl_port {
	atomic_t ctrl_online;

	bool is_open;
	bool is_suspended;

	wait_queue_head_t read_wq;

@@ -274,6 +275,7 @@ struct f_gsi {
	/* function suspend status */
	bool func_is_suspended;
	bool func_wakeup_allowed;
	bool func_wakeup_pending;

	const struct usb_endpoint_descriptor *in_ep_desc_backup;
	const struct usb_endpoint_descriptor *out_ep_desc_backup;