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

Commit 2fe2bf7d authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: gadget: f_mbim: Issue wakeup if notification already queued"

parents 3e982c0a 34e3eb55
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -132,7 +132,9 @@ struct f_mbim {

	atomic_t		error;
	unsigned int		cpkt_drop_cnt;

	bool			remote_wakeup_enabled;
	struct delayed_work	rwake_work;
};

struct mbim_ntb_input_size {
@@ -667,6 +669,29 @@ static void mbim_clear_queues(struct f_mbim *mbim)
	spin_unlock(&mbim->lock);
}

static void mbim_remote_wakeup_work(struct work_struct *w)
{
	struct f_mbim	*mbim = container_of(w, struct f_mbim, rwake_work.work);
	int		ret = 0;

	if ((mbim->cdev->gadget->speed == USB_SPEED_SUPER) &&
			!mbim->function.func_is_suspended){
		pr_debug("%s: resume in progress\n", __func__);
		return;
	}

	if ((mbim->cdev->gadget->speed == USB_SPEED_SUPER) &&
			mbim->function.func_is_suspended)
		ret = usb_func_wakeup(&mbim->function);
	else
		ret = usb_gadget_wakeup(mbim->cdev->gadget);

	if (ret == -EBUSY || ret == -EAGAIN)
		pr_debug("%s:RW delayed due to LPM exit %d\n",  __func__, ret);
	else
		pr_info("%s: remote wake-up failed: %d\n", __func__, ret);
}

/*
 * Context: mbim->lock held
 */
@@ -1285,6 +1310,8 @@ static void mbim_disable(struct usb_function *f)
	struct usb_composite_dev *cdev = mbim->cdev;

	pr_info("SET DEVICE OFFLINE\n");

	cancel_delayed_work(&mbim->rwake_work);
	atomic_set(&mbim->online, 0);
	mbim->remote_wakeup_enabled = 0;

@@ -1362,6 +1389,13 @@ static void mbim_suspend(struct usb_function *f)

	bam_data_suspend(&mbim->bam_port, mbim->port_num, USB_FUNC_MBIM,
			 mbim->remote_wakeup_enabled);

	if (mbim->remote_wakeup_enabled &&
			atomic_read(&mbim->not_port.notify_count) > 0) {
		pr_info("%s: pending notification, wakeup host\n", __func__);
		schedule_delayed_work(&mbim->rwake_work,
				      msecs_to_jiffies(2000));
	}
}

static void mbim_resume(struct usb_function *f)
@@ -1381,6 +1415,8 @@ static void mbim_resume(struct usb_function *f)
		f->func_is_suspended)
		return;

	cancel_delayed_work(&mbim->rwake_work);

	/* resume control path by queuing notify req */
	spin_lock(&mbim->lock);
	mbim_do_notify(mbim);
@@ -1748,6 +1784,7 @@ int mbim_bind_config(struct usb_configuration *c, unsigned portno,

	INIT_LIST_HEAD(&mbim->cpkt_req_q);
	INIT_LIST_HEAD(&mbim->cpkt_resp_q);
	INIT_DELAYED_WORK(&mbim->rwake_work, mbim_remote_wakeup_work);

	status = usb_add_function(c, &mbim->function);