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

Commit 978e7642 authored by Rohith Kollalsi's avatar Rohith Kollalsi Committed by Mayank Rana
Browse files

usb: f_gsi: Implement remote wakeup feature for gsi for bus suspend



Earlier remote wakeup feature for gsi was only available for
function suspend. This change adds remote wakeup feature even
for bus suspend. The entire implementation of remote wakeup
for gsi is now moved to gsi driver from func_ep_queue present
in composite.

Change-Id: I773ea038f1ee7c081c50388db3f3d397fa7e28ba
Signed-off-by: default avatarRohith Kollalsi <rkollals@codeaurora.org>
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent 7141e265
Loading
Loading
Loading
Loading
+36 −8
Original line number Diff line number Diff line
@@ -1880,18 +1880,42 @@ 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);
	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;
		}

		log_event_dbg("%s wakeup host\n", __func__);
		if (gadget->speed >= USB_SPEED_SUPER
		    && gsi->func_is_suspended)
			ret = usb_func_wakeup(func);
		else
			ret = -EOPNOTSUPP;
			ret = usb_gadget_wakeup(gadget);

		gsi->rwake_inprogress = true;
		return ret;
	}

	if (ret < 0 || gsi->func_is_suspended) {
	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 +2547,7 @@ 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;
	atomic_set(&gsi->connected, 1);

	/* send 0 len pkt to qti to notify state change */
@@ -2606,6 +2631,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);
@@ -2646,6 +2672,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);

+1 −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;