Loading drivers/usb/dwc3/core.h +1 −0 Original line number Diff line number Diff line Loading @@ -743,6 +743,7 @@ struct dwc3_scratchpad_array { #define DWC3_CONTROLLER_CONNDONE_EVENT 8 #define DWC3_CONTROLLER_NOTIFY_OTG_EVENT 9 #define DWC3_CONTROLLER_SET_CURRENT_DRAW_EVENT 10 #define DWC3_CONTROLLER_RESTART_USB_SESSION 11 #define MAX_INTR_STATS 10 /** Loading drivers/usb/dwc3/dwc3-msm.c +10 −2 Original line number Diff line number Diff line Loading @@ -1437,7 +1437,7 @@ static void dwc3_restart_usb_work(struct work_struct *w) dev_dbg(mdwc->dev, "%s\n", __func__); if (atomic_read(&dwc->in_lpm) || !dwc->is_drd) { dev_err(mdwc->dev, "%s failed!!!\n", __func__); dev_dbg(mdwc->dev, "%s failed!!!\n", __func__); return; } Loading @@ -1462,7 +1462,10 @@ static void dwc3_restart_usb_work(struct work_struct *w) msleep(20); if (!timeout) { dev_warn(mdwc->dev, "Not in LPM after disconnect, forcing suspend...\n"); dev_dbg(mdwc->dev, "Not in LPM after disconnect, forcing suspend...\n"); dbg_event(0xFF, "ReStart:RT SUSP", atomic_read(&mdwc->dev->power.usage_count)); pm_runtime_suspend(mdwc->dev); } Loading @@ -1474,6 +1477,7 @@ static void dwc3_restart_usb_work(struct work_struct *w) } dwc->err_evt_seen = false; flush_delayed_work(&mdwc->sm_work); } /** Loading Loading @@ -1743,6 +1747,10 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned event) dev_dbg(mdwc->dev, "DWC3_CONTROLLER_SET_CURRENT_DRAW_EVENT received\n"); dwc3_msm_gadget_vbus_draw(mdwc, dwc->vbus_draw); break; case DWC3_CONTROLLER_RESTART_USB_SESSION: dev_dbg(mdwc->dev, "DWC3_CONTROLLER_RESTART_USB_SESSION received\n"); dwc3_restart_usb_work(&mdwc->restart_usb_work); break; default: dev_dbg(mdwc->dev, "unknown dwc3 event\n"); break; Loading drivers/usb/dwc3/gadget.c +8 −0 Original line number Diff line number Diff line Loading @@ -2226,6 +2226,13 @@ static int dwc3_gadget_stop(struct usb_gadget *g, return 0; } static int dwc3_gadget_restart_usb_session(struct usb_gadget *g) { struct dwc3 *dwc = gadget_to_dwc(g); return dwc3_notify_event(dwc, DWC3_CONTROLLER_RESTART_USB_SESSION); } static const struct usb_gadget_ops dwc3_gadget_ops = { .get_frame = dwc3_gadget_get_frame, .wakeup = dwc3_gadget_wakeup, Loading @@ -2236,6 +2243,7 @@ static const struct usb_gadget_ops dwc3_gadget_ops = { .pullup = dwc3_gadget_pullup, .udc_start = dwc3_gadget_start, .udc_stop = dwc3_gadget_stop, .restart = dwc3_gadget_restart_usb_session, }; /* -------------------------------------------------------------------------- */ Loading drivers/usb/gadget/function/f_gsi.c +48 −2 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ MODULE_PARM_DESC(num_out_bufs, "Number of OUT buffers"); static struct workqueue_struct *ipa_usb_wq; static bool gadget_restarted; struct usb_gsi_debugfs { struct dentry *debugfs_root; Loading Loading @@ -626,8 +627,10 @@ static int ipa_suspend_work_handler(struct gsi_data_port *d_port) struct f_gsi *gsi = d_port_to_gsi(d_port); if (!usb_gsi_ep_op(gsi->d_port.in_ep, NULL, GSI_EP_OP_CHECK_FOR_SUSPEND)) GSI_EP_OP_CHECK_FOR_SUSPEND)) { ret = -EFAULT; goto done; } ret = ipa_usb_xdci_suspend(gsi->d_port.out_channel_handle, gsi->d_port.in_channel_handle, gsi->prot_id); Loading Loading @@ -676,6 +679,7 @@ static void ipa_work_handler(struct work_struct *w) struct gsi_data_port *d_port = container_of(w, struct gsi_data_port, usb_ipa_w); u8 event; int ret = 0; event = read_event(d_port); Loading Loading @@ -710,13 +714,17 @@ static void ipa_work_handler(struct work_struct *w) read_event(d_port); ipa_disconnect_work_handler(d_port); d_port->sm_state = STATE_INITIALIZED; usb_gadget_autopm_put_async(d_port->gadget); pr_debug("%s: STATE DISCONNECTED", __func__); break; } ipa_suspend_work_handler(d_port); ret = ipa_suspend_work_handler(d_port); if (!ret) usb_gadget_autopm_put_async(d_port->gadget); } else if (event == EVT_DISCONNECTED) { ipa_disconnect_work_handler(d_port); d_port->sm_state = STATE_INITIALIZED; usb_gadget_autopm_put_async(d_port->gadget); pr_debug("%s: STATE DISCONNECTED", __func__); } break; Loading @@ -724,15 +732,21 @@ static void ipa_work_handler(struct work_struct *w) if (event == EVT_DISCONNECTED) { ipa_disconnect_work_handler(d_port); d_port->sm_state = STATE_INITIALIZED; usb_gadget_autopm_put_async(d_port->gadget); pr_debug("%s: STATE DISCONNECTED", __func__); } else if (event == EVT_SUSPEND) { if (peek_event(d_port) == EVT_DISCONNECTED) { ipa_disconnect_work_handler(d_port); d_port->sm_state = STATE_INITIALIZED; usb_gadget_autopm_put_async(d_port->gadget); pr_debug("%s: STATE DISCONNECTED", __func__); break; } ipa_suspend_work_handler(d_port); if (!ret) usb_gadget_autopm_put_async(d_port->gadget); } else if (event == EVT_CONNECTED) { d_port->sm_state = STATE_CONNECTED; pr_debug("%s: DATA PATH CONNECTED", __func__); Loading @@ -751,13 +765,22 @@ static void ipa_work_handler(struct work_struct *w) case STATE_SUSPEND_IN_PROGRESS: if (event == EVT_IPA_SUSPEND) { d_port->sm_state = STATE_SUSPENDED; usb_gadget_autopm_put_async(d_port->gadget); } else if (event == EVT_RESUMED) { ipa_resume_work_handler(d_port); d_port->sm_state = STATE_CONNECTED; /* * Increment usage count here to disallow gadget * parent suspend. This counter will decrement * after IPA disconnect is done in disconnect work * (due to cable disconnect) or in suspended state. */ usb_gadget_autopm_get_noresume(d_port->gadget); pr_debug("%s: STATE CONNECTED", __func__); } else if (event == EVT_DISCONNECTED) { ipa_disconnect_work_handler(d_port); d_port->sm_state = STATE_INITIALIZED; usb_gadget_autopm_put_async(d_port->gadget); pr_debug("%s: STATE DISCONNECTED", __func__); } break; Loading @@ -766,6 +789,14 @@ static void ipa_work_handler(struct work_struct *w) if (event == EVT_RESUMED) { ipa_resume_work_handler(d_port); d_port->sm_state = STATE_CONNECTED; /* * Increment usage count here to disallow gadget * parent suspend. This counter will decrement * after IPA handshake is done in disconnect work * (due to cable disconnect) or in suspended state. */ usb_gadget_autopm_get_noresume(d_port->gadget); pr_debug("%s: STATE CONNECTED", __func__); } else if (event == EVT_DISCONNECTED) { ipa_disconnect_work_handler(d_port); Loading Loading @@ -1915,6 +1946,8 @@ static int gsi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) GSI_EP_OP_CONFIG); } gsi->d_port.gadget = cdev->gadget; if (gsi->prot_id == IPA_USB_RNDIS) { gsi_rndis_open(gsi); net = gsi_rndis_get_netdev("rndis0"); Loading @@ -1930,6 +1963,13 @@ static int gsi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (gsi->prot_id == IPA_USB_ECM) gsi->d_port.cdc_filter = DEFAULT_FILTER; /* * Increment usage count upon cable connect. Decrement * after IPA disconnect is done in disconnect work * (due to cable disconnect) or in suspend work. */ usb_gadget_autopm_get_noresume(gsi->d_port.gadget); post_event(&gsi->d_port, EVT_CONNECT_IN_PROGRESS); queue_work(gsi->d_port.ipa_usb_wq, &gsi->d_port.usb_ipa_w); Loading Loading @@ -2591,6 +2631,7 @@ static void gsi_unbind(struct usb_configuration *c, struct usb_function *f) */ flush_workqueue(gsi->d_port.ipa_usb_wq); ipa_usb_deinit_teth_prot(gsi->prot_id); gadget_restarted = false; if (gsi->prot_id == IPA_USB_RNDIS) { gsi->d_port.sm_state = STATE_UNINITIALIZED; Loading Loading @@ -2643,6 +2684,11 @@ int gsi_bind_config(struct usb_configuration *c, enum ipa_usb_teth_prot prot_id) return -EINVAL; } if (!gadget_restarted) { usb_gadget_restart(c->cdev->gadget); gadget_restarted = true; } switch (prot_id) { case IPA_USB_RNDIS: gsi->function.name = "rndis"; Loading include/linux/usb/f_gsi.h +1 −0 Original line number Diff line number Diff line Loading @@ -161,6 +161,7 @@ struct gsi_data_port { struct usb_ep *out_ep; struct usb_gsi_request in_request; struct usb_gsi_request out_request; struct usb_gadget *gadget; int (*ipa_usb_notify_cb)(enum ipa_usb_notify_event, void *driver_data); struct ipa_usb_teth_params ipa_init_params; int in_channel_handle; Loading Loading
drivers/usb/dwc3/core.h +1 −0 Original line number Diff line number Diff line Loading @@ -743,6 +743,7 @@ struct dwc3_scratchpad_array { #define DWC3_CONTROLLER_CONNDONE_EVENT 8 #define DWC3_CONTROLLER_NOTIFY_OTG_EVENT 9 #define DWC3_CONTROLLER_SET_CURRENT_DRAW_EVENT 10 #define DWC3_CONTROLLER_RESTART_USB_SESSION 11 #define MAX_INTR_STATS 10 /** Loading
drivers/usb/dwc3/dwc3-msm.c +10 −2 Original line number Diff line number Diff line Loading @@ -1437,7 +1437,7 @@ static void dwc3_restart_usb_work(struct work_struct *w) dev_dbg(mdwc->dev, "%s\n", __func__); if (atomic_read(&dwc->in_lpm) || !dwc->is_drd) { dev_err(mdwc->dev, "%s failed!!!\n", __func__); dev_dbg(mdwc->dev, "%s failed!!!\n", __func__); return; } Loading @@ -1462,7 +1462,10 @@ static void dwc3_restart_usb_work(struct work_struct *w) msleep(20); if (!timeout) { dev_warn(mdwc->dev, "Not in LPM after disconnect, forcing suspend...\n"); dev_dbg(mdwc->dev, "Not in LPM after disconnect, forcing suspend...\n"); dbg_event(0xFF, "ReStart:RT SUSP", atomic_read(&mdwc->dev->power.usage_count)); pm_runtime_suspend(mdwc->dev); } Loading @@ -1474,6 +1477,7 @@ static void dwc3_restart_usb_work(struct work_struct *w) } dwc->err_evt_seen = false; flush_delayed_work(&mdwc->sm_work); } /** Loading Loading @@ -1743,6 +1747,10 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned event) dev_dbg(mdwc->dev, "DWC3_CONTROLLER_SET_CURRENT_DRAW_EVENT received\n"); dwc3_msm_gadget_vbus_draw(mdwc, dwc->vbus_draw); break; case DWC3_CONTROLLER_RESTART_USB_SESSION: dev_dbg(mdwc->dev, "DWC3_CONTROLLER_RESTART_USB_SESSION received\n"); dwc3_restart_usb_work(&mdwc->restart_usb_work); break; default: dev_dbg(mdwc->dev, "unknown dwc3 event\n"); break; Loading
drivers/usb/dwc3/gadget.c +8 −0 Original line number Diff line number Diff line Loading @@ -2226,6 +2226,13 @@ static int dwc3_gadget_stop(struct usb_gadget *g, return 0; } static int dwc3_gadget_restart_usb_session(struct usb_gadget *g) { struct dwc3 *dwc = gadget_to_dwc(g); return dwc3_notify_event(dwc, DWC3_CONTROLLER_RESTART_USB_SESSION); } static const struct usb_gadget_ops dwc3_gadget_ops = { .get_frame = dwc3_gadget_get_frame, .wakeup = dwc3_gadget_wakeup, Loading @@ -2236,6 +2243,7 @@ static const struct usb_gadget_ops dwc3_gadget_ops = { .pullup = dwc3_gadget_pullup, .udc_start = dwc3_gadget_start, .udc_stop = dwc3_gadget_stop, .restart = dwc3_gadget_restart_usb_session, }; /* -------------------------------------------------------------------------- */ Loading
drivers/usb/gadget/function/f_gsi.c +48 −2 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ MODULE_PARM_DESC(num_out_bufs, "Number of OUT buffers"); static struct workqueue_struct *ipa_usb_wq; static bool gadget_restarted; struct usb_gsi_debugfs { struct dentry *debugfs_root; Loading Loading @@ -626,8 +627,10 @@ static int ipa_suspend_work_handler(struct gsi_data_port *d_port) struct f_gsi *gsi = d_port_to_gsi(d_port); if (!usb_gsi_ep_op(gsi->d_port.in_ep, NULL, GSI_EP_OP_CHECK_FOR_SUSPEND)) GSI_EP_OP_CHECK_FOR_SUSPEND)) { ret = -EFAULT; goto done; } ret = ipa_usb_xdci_suspend(gsi->d_port.out_channel_handle, gsi->d_port.in_channel_handle, gsi->prot_id); Loading Loading @@ -676,6 +679,7 @@ static void ipa_work_handler(struct work_struct *w) struct gsi_data_port *d_port = container_of(w, struct gsi_data_port, usb_ipa_w); u8 event; int ret = 0; event = read_event(d_port); Loading Loading @@ -710,13 +714,17 @@ static void ipa_work_handler(struct work_struct *w) read_event(d_port); ipa_disconnect_work_handler(d_port); d_port->sm_state = STATE_INITIALIZED; usb_gadget_autopm_put_async(d_port->gadget); pr_debug("%s: STATE DISCONNECTED", __func__); break; } ipa_suspend_work_handler(d_port); ret = ipa_suspend_work_handler(d_port); if (!ret) usb_gadget_autopm_put_async(d_port->gadget); } else if (event == EVT_DISCONNECTED) { ipa_disconnect_work_handler(d_port); d_port->sm_state = STATE_INITIALIZED; usb_gadget_autopm_put_async(d_port->gadget); pr_debug("%s: STATE DISCONNECTED", __func__); } break; Loading @@ -724,15 +732,21 @@ static void ipa_work_handler(struct work_struct *w) if (event == EVT_DISCONNECTED) { ipa_disconnect_work_handler(d_port); d_port->sm_state = STATE_INITIALIZED; usb_gadget_autopm_put_async(d_port->gadget); pr_debug("%s: STATE DISCONNECTED", __func__); } else if (event == EVT_SUSPEND) { if (peek_event(d_port) == EVT_DISCONNECTED) { ipa_disconnect_work_handler(d_port); d_port->sm_state = STATE_INITIALIZED; usb_gadget_autopm_put_async(d_port->gadget); pr_debug("%s: STATE DISCONNECTED", __func__); break; } ipa_suspend_work_handler(d_port); if (!ret) usb_gadget_autopm_put_async(d_port->gadget); } else if (event == EVT_CONNECTED) { d_port->sm_state = STATE_CONNECTED; pr_debug("%s: DATA PATH CONNECTED", __func__); Loading @@ -751,13 +765,22 @@ static void ipa_work_handler(struct work_struct *w) case STATE_SUSPEND_IN_PROGRESS: if (event == EVT_IPA_SUSPEND) { d_port->sm_state = STATE_SUSPENDED; usb_gadget_autopm_put_async(d_port->gadget); } else if (event == EVT_RESUMED) { ipa_resume_work_handler(d_port); d_port->sm_state = STATE_CONNECTED; /* * Increment usage count here to disallow gadget * parent suspend. This counter will decrement * after IPA disconnect is done in disconnect work * (due to cable disconnect) or in suspended state. */ usb_gadget_autopm_get_noresume(d_port->gadget); pr_debug("%s: STATE CONNECTED", __func__); } else if (event == EVT_DISCONNECTED) { ipa_disconnect_work_handler(d_port); d_port->sm_state = STATE_INITIALIZED; usb_gadget_autopm_put_async(d_port->gadget); pr_debug("%s: STATE DISCONNECTED", __func__); } break; Loading @@ -766,6 +789,14 @@ static void ipa_work_handler(struct work_struct *w) if (event == EVT_RESUMED) { ipa_resume_work_handler(d_port); d_port->sm_state = STATE_CONNECTED; /* * Increment usage count here to disallow gadget * parent suspend. This counter will decrement * after IPA handshake is done in disconnect work * (due to cable disconnect) or in suspended state. */ usb_gadget_autopm_get_noresume(d_port->gadget); pr_debug("%s: STATE CONNECTED", __func__); } else if (event == EVT_DISCONNECTED) { ipa_disconnect_work_handler(d_port); Loading Loading @@ -1915,6 +1946,8 @@ static int gsi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) GSI_EP_OP_CONFIG); } gsi->d_port.gadget = cdev->gadget; if (gsi->prot_id == IPA_USB_RNDIS) { gsi_rndis_open(gsi); net = gsi_rndis_get_netdev("rndis0"); Loading @@ -1930,6 +1963,13 @@ static int gsi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (gsi->prot_id == IPA_USB_ECM) gsi->d_port.cdc_filter = DEFAULT_FILTER; /* * Increment usage count upon cable connect. Decrement * after IPA disconnect is done in disconnect work * (due to cable disconnect) or in suspend work. */ usb_gadget_autopm_get_noresume(gsi->d_port.gadget); post_event(&gsi->d_port, EVT_CONNECT_IN_PROGRESS); queue_work(gsi->d_port.ipa_usb_wq, &gsi->d_port.usb_ipa_w); Loading Loading @@ -2591,6 +2631,7 @@ static void gsi_unbind(struct usb_configuration *c, struct usb_function *f) */ flush_workqueue(gsi->d_port.ipa_usb_wq); ipa_usb_deinit_teth_prot(gsi->prot_id); gadget_restarted = false; if (gsi->prot_id == IPA_USB_RNDIS) { gsi->d_port.sm_state = STATE_UNINITIALIZED; Loading Loading @@ -2643,6 +2684,11 @@ int gsi_bind_config(struct usb_configuration *c, enum ipa_usb_teth_prot prot_id) return -EINVAL; } if (!gadget_restarted) { usb_gadget_restart(c->cdev->gadget); gadget_restarted = true; } switch (prot_id) { case IPA_USB_RNDIS: gsi->function.name = "rndis"; Loading
include/linux/usb/f_gsi.h +1 −0 Original line number Diff line number Diff line Loading @@ -161,6 +161,7 @@ struct gsi_data_port { struct usb_ep *out_ep; struct usb_gsi_request in_request; struct usb_gsi_request out_request; struct usb_gadget *gadget; int (*ipa_usb_notify_cb)(enum ipa_usb_notify_event, void *driver_data); struct ipa_usb_teth_params ipa_init_params; int in_channel_handle; Loading