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: Rohith Kollalsi <rkollals@codeaurora.org>
This commit is contained in:
Rohith Kollalsi 2020-08-07 15:25:46 +05:30 committed by Gerrit - the friendly Code Review server
parent 117a496b54
commit de4b3858f6
2 changed files with 39 additions and 2 deletions

View File

@ -1858,9 +1858,41 @@ 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;
ret = usb_func_ep_queue(&gsi->function, gsi->c_port.notify,
gsi->c_port.notify_req, GFP_ATOMIC);
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
&& func->func_is_suspended)
ret = usb_func_wakeup(func);
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;
@ -2493,6 +2525,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 */
@ -2593,6 +2626,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);
@ -2624,6 +2658,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);

View File

@ -209,6 +209,7 @@ struct gsi_ctrl_port {
atomic_t ctrl_online;
bool is_open;
bool is_suspended;
wait_queue_head_t read_wq;