From 17b10ed288ef1a1363378c60e853902cfd4bdfac Mon Sep 17 00:00:00 2001 From: Bar Weiner <bweiner@codeaurora.org> Date: Thu, 13 Mar 2014 18:07:11 +0200 Subject: [PATCH] usb: bam: suspend/resume handshake with the IPA When going to suspend, there is the need to perform a handshake with the IPA. Furthermore, due to a hardware bug in the DBM, there is also a need to reset the DBM ep and corresponding BAM pipe. This patch exposes the need (or lack thereof) to perform the DBM and BAM reset, as well as incorporates this reset into the overall flow of handshaking with the IPA Change-Id: I4c7159bd292799122785ab019a844822efe46d5c Signed-off-by: Dov Levenglick <dovl@codeaurora.org> Signed-off-by: Bar Weiner <bweiner@codeaurora.org> --- drivers/platform/msm/usb_bam.c | 106 +++++++++++++++++---- drivers/usb/gadget/u_bam.c | 163 +++++++++++++++++++++++--------- drivers/usb/gadget/u_bam_data.c | 82 +++++++++++++--- include/linux/usb/msm_hsusb.h | 13 +++ include/linux/usb_bam.h | 2 + 5 files changed, 290 insertions(+), 76 deletions(-) diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c index a44fca5beac2..215381554e6a 100644 --- a/drivers/platform/msm/usb_bam.c +++ b/drivers/platform/msm/usb_bam.c @@ -35,6 +35,8 @@ #define USB_BAM_NR_PORTS 4 +#define ARRAY_INDEX_FROM_ADDR(base, addr) ((addr) - (base)) + enum usb_bam_sm { USB_BAM_SM_INIT = 0, USB_BAM_SM_PLUG_NOTIFIED, @@ -296,8 +298,7 @@ static void usb_bam_set_inactivity_timer(enum usb_bam bam) */ for (i = 0; i < ctx.max_connections; i++) { pipe_connect = &usb_bam_connections[i]; - if (pipe_connect->bam_type == bam && - pipe_connect->enabled) { + if (pipe_connect->bam_type == bam && pipe_connect->enabled) { pipe = ctx.usb_bam_sps.sps_pipes[i]; break; } @@ -583,6 +584,7 @@ static int connect_pipe_bam2bam_ipa(u8 idx, pipe_connect->activity_notify = ipa_params->activity_notify; pipe_connect->inactivity_notify = ipa_params->inactivity_notify; pipe_connect->priv = ipa_params->priv; + pipe_connect->reset_pipe_after_lpm = ipa_params->reset_pipe_after_lpm; /* IPA input parameters */ ipa_in_params.client_bam_hdl = usb_handle; @@ -749,7 +751,7 @@ static int disconnect_pipe(u8 idx) static bool _usb_bam_resume_core(void) { - pr_debug("%s: Resuming usb peripheral/host device", __func__); + pr_debug("Resuming usb peripheral/host device\n"); if (usb_device) pm_runtime_resume(usb_device); @@ -1081,6 +1083,57 @@ int usb_bam_connect(int idx, u32 *bam_pipe_idx) return 0; } +/* This function is in expectation that the SPS team expose similar + * functionality. As a result, it is written so that when the + * function does become available, it'll have the same (expected) API. + */ +static int __sps_reset_pipe(struct sps_pipe *pipe, u32 idx) +{ + int ret; + struct sps_connect *sps_connection = + &ctx.usb_bam_sps.sps_connections[idx]; + + ret = sps_disconnect(pipe); + if (ret) { + pr_err("%s: sps_disconnect() failed %d\n", __func__, ret); + return ret; + } + + ret = sps_connect(pipe, sps_connection); + if (ret < 0) { + pr_err("%s: sps_connect() failed %d\n", __func__, ret); + return ret; + } + + return 0; +} + +static void reset_pipe_for_resume(struct usb_bam_pipe_connect *pipe_connect) +{ + int ret; + u32 idx = ARRAY_INDEX_FROM_ADDR(usb_bam_connections, pipe_connect); + struct sps_pipe *pipe = ctx.usb_bam_sps.sps_pipes[idx]; + + if (!pipe_connect->reset_pipe_after_lpm || + pipe_connect->pipe_type != USB_BAM_PIPE_BAM2BAM) { + pr_debug("No need to reset pipe %d\n", idx); + return; + } + + ret = __sps_reset_pipe(pipe, idx); + if (ret) { + pr_err("%s failed to reset the USB sps pipe\n", __func__); + return; + } + + ret = ipa_reset_endpoint(pipe_connect->ipa_clnt_hdl); + if (ret) { + pr_err("%s failed to reset the IPA pipe\n", __func__); + return; + } + +} + /* Stop PROD transfers in case they were started */ static void stop_prod_transfers(struct usb_bam_pipe_connect *pipe_connect) { @@ -1109,7 +1162,7 @@ static void start_cons_transfers(struct usb_bam_pipe_connect *pipe_connect) if (pipe_connect->start && pipe_connect->cons_stopped) { pr_debug("%s: Enqueue CONS transfer", __func__); pipe_connect->start(pipe_connect->start_stop_param, - PEER_PERIPHERAL_TO_USB); + PEER_PERIPHERAL_TO_USB); pipe_connect->cons_stopped = 0; } } @@ -1190,14 +1243,14 @@ static void usb_bam_finish_suspend(enum usb_bam cur_bam) cons_pipe = ctx.usb_bam_sps.sps_pipes[dst_idx]; pr_debug("pipes_suspended=%d pipes_to_suspend=%d", - info[cur_bam].pipes_suspended, - info[cur_bam].pipes_to_suspend); + info[cur_bam].pipes_suspended, + info[cur_bam].pipes_to_suspend); spin_unlock(&usb_bam_ipa_handshake_info_lock); ret = sps_is_pipe_empty(cons_pipe, &cons_empty); if (ret) { pr_err("%s: sps_is_pipe_empty failed with %d\n", - __func__, ret); + __func__, ret); goto no_lpm; } @@ -1215,9 +1268,9 @@ static void usb_bam_finish_suspend(enum usb_bam cur_bam) pr_debug("%s: Suspending pipe\n", __func__); /* ACK on the last pipe */ if ((info[cur_bam].pipes_suspended + 1) * 2 == - ctx.pipes_enabled_per_bam[cur_bam] && - info[cur_bam].cur_cons_state == - IPA_RM_RESOURCE_RELEASED) { + ctx.pipes_enabled_per_bam[cur_bam] && + info[cur_bam].cur_cons_state == + IPA_RM_RESOURCE_RELEASED) { ipa_rm_notify_completion( IPA_RM_RESOURCE_RELEASED, ipa_rm_resource_cons[cur_bam]); @@ -1578,7 +1631,7 @@ static void wait_for_prod_release(enum usb_bam cur_bam) pr_err("%s: ipa_rm_request_resource ret =%d", __func__, ret); } -static int check_pipes_empty(u8 src_idx, u8 dst_idx) +static bool check_pipes_empty(u8 src_idx, u8 dst_idx) { struct sps_pipe *prod_pipe, *cons_pipe; struct usb_bam_pipe_connect *prod_pipe_connect, *cons_pipe_connect; @@ -1596,18 +1649,32 @@ static int check_pipes_empty(u8 src_idx, u8 dst_idx) cons_pipe = ctx.usb_bam_sps.sps_pipes[dst_idx]; pr_debug("prod_pipe=%p, cons_pipe=%p", prod_pipe, cons_pipe); - if (!prod_pipe || sps_is_pipe_empty(prod_pipe, &prod_empty) || - !cons_pipe || sps_is_pipe_empty(cons_pipe, &cons_empty)) { - pr_err("%s: sps_is_pipe_empty failed with\n", __func__); - return 1; + if (!cons_pipe || (!prod_pipe && + prod_pipe_connect->pipe_type == USB_BAM_PIPE_BAM2BAM)) { + pr_err("Missing a pipe!\n"); + return false; + } + + if (prod_pipe && sps_is_pipe_empty(prod_pipe, &prod_empty)) { + pr_err("sps_is_pipe_empty(prod) failed\n"); + return false; + } else { + prod_empty = true; } + + if (sps_is_pipe_empty(cons_pipe, &cons_empty)) { + pr_err("sps_is_pipe_empty(cons) failed\n"); + return false; + } + if (!prod_empty || !cons_empty) { - pr_err("%s: pipes not empty prod=%d cond=%d", __func__, + pr_err("pipes not empty prod=%d cond=%d", prod_empty, cons_empty); - return 0; + return false; } - return 1; + return true; + } void usb_bam_suspend(struct usb_bam_connect_ipa_params *ipa_params) @@ -1763,6 +1830,9 @@ static void usb_bam_finish_resume(struct work_struct *w) idx = suspended - 1; dst_idx = info[cur_bam].resume_dst_idx[idx]; pipe_connect = &usb_bam_connections[dst_idx]; + spin_unlock(&usb_bam_ipa_handshake_info_lock); + reset_pipe_for_resume(pipe_connect); + spin_lock(&usb_bam_ipa_handshake_info_lock); if (pipe_connect->cons_stopped) { pr_debug("%s: Starting CONS on %d", __func__, dst_idx); start_cons_transfers(pipe_connect); diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c index b4f4363e5fc0..6097adb11ef7 100644 --- a/drivers/usb/gadget/u_bam.c +++ b/drivers/usb/gadget/u_bam.c @@ -118,10 +118,13 @@ struct bam_ch_info { struct usb_request *rx_req; struct usb_request *tx_req; - u32 src_pipe_idx; - u32 dst_pipe_idx; - u8 src_connection_idx; - u8 dst_connection_idx; + u32 src_pipe_idx; + u32 dst_pipe_idx; + u8 src_connection_idx; + u8 dst_connection_idx; + int src_bam_idx; + int dst_bam_idx; + enum transport_type trans; struct usb_bam_connect_ipa_params ipa_params; @@ -777,9 +780,53 @@ static void gbam_stop_endless_tx(struct gbam_port *port) spin_unlock(&port->port_lock_dl); } + +/* + * This function configured data fifo based on index passed to get bam2bam + * configuration. + */ +static void configure_data_fifo(u8 idx, struct usb_ep *ep, + enum usb_bam_pipe_type pipe_type) +{ + struct u_bam_data_connect_info bam_info; + struct sps_mem_buffer data_fifo = {0}; + + if (pipe_type == USB_BAM_PIPE_BAM2BAM) { + get_bam2bam_connection_info(idx, + &bam_info.usb_bam_handle, + &bam_info.usb_bam_pipe_idx, + &bam_info.peer_pipe_idx, + NULL, &data_fifo); + + msm_data_fifo_config(ep, + data_fifo.phys_base, + data_fifo.size, + bam_info.usb_bam_pipe_idx); + } +} + + static void gbam_start(void *param, enum usb_bam_pipe_dir dir) { struct gbam_port *port = param; + struct f_rmnet *dev = NULL; + struct usb_gadget *gadget = NULL; + struct bam_ch_info *d; + + if (port) { + dev = port_to_rmnet(port->gr); + d = &port->data_ch; + } else { + pr_err("%s: port is NULL\n", __func__); + return; + } + + if (dev && dev->cdev) + gadget = dev->cdev->gadget; + else { + pr_err("%s: dev or dev->cdev are NULL\n", __func__); + return; + } if (dir == USB_TO_PEER_PERIPHERAL) { if (port->data_ch.src_pipe_type == USB_BAM_PIPE_BAM2BAM) @@ -787,6 +834,22 @@ static void gbam_start(void *param, enum usb_bam_pipe_dir dir) else gbam_start_rx(port); } else { + if (gadget_is_dwc3(gadget) && + msm_dwc3_reset_ep_after_lpm(gadget)) { + u8 idx; + + idx = usb_bam_get_connection_idx(gadget->name, + IPA_P_BAM, PEER_PERIPHERAL_TO_USB, + USB_BAM_DEVICE, 0); + if (idx < 0) { + pr_err("%s: get_connection_idx failed\n", + __func__); + return; + } + configure_data_fifo(idx, + port->port_usb->in, + d->dst_pipe_type); + } gbam_start_endless_tx(port); } } @@ -998,30 +1061,6 @@ static void gbam_connect_work(struct work_struct *w) pr_debug("%s: done\n", __func__); } -/* - * This function configured data fifo based on index passed to get bam2bam - * configuration. - */ -static void configure_data_fifo(u8 idx, struct usb_ep *ep, - enum usb_bam_pipe_type pipe_type) -{ - struct u_bam_data_connect_info bam_info; - struct sps_mem_buffer data_fifo = {0}; - - if (pipe_type == USB_BAM_PIPE_BAM2BAM) { - get_bam2bam_connection_info(idx, - &bam_info.usb_bam_handle, - &bam_info.usb_bam_pipe_idx, - &bam_info.peer_pipe_idx, - NULL, &data_fifo); - - msm_data_fifo_config(ep, - data_fifo.phys_base, - data_fifo.size, - bam_info.usb_bam_pipe_idx); - } -} - static void gbam2bam_connect_work(struct work_struct *w) { struct gbam_port *port = container_of(w, struct gbam_port, connect_w); @@ -1089,6 +1128,9 @@ static void gbam2bam_connect_work(struct work_struct *w) teth_bridge_params.usb_notify_cb; d->ipa_params.priv = teth_bridge_params.private_data; + d->ipa_params.reset_pipe_after_lpm = + (gadget_is_dwc3(gadget) && + msm_dwc3_reset_ep_after_lpm(gadget)); } d->ipa_params.ipa_ep_cfg.mode.mode = IPA_BASIC; d->ipa_params.skip_ep_cfg = teth_bridge_params.skip_ep_cfg; @@ -1101,18 +1143,16 @@ static void gbam2bam_connect_work(struct work_struct *w) } if (gadget && gadget_is_dwc3(gadget)) { - u8 idx; - - idx = usb_bam_get_connection_idx(gadget->name, - IPA_P_BAM, USB_TO_PEER_PERIPHERAL, + d->src_bam_idx = usb_bam_get_connection_idx( + gadget->name, IPA_P_BAM, USB_TO_PEER_PERIPHERAL, USB_BAM_DEVICE, 0); - if (idx < 0) { + if (d->src_bam_idx < 0) { pr_err("%s: get_connection_idx failed\n", __func__); return; } - configure_data_fifo(idx, port->port_usb->out, + configure_data_fifo(d->src_bam_idx, port->port_usb->out, d->src_pipe_type); } @@ -1120,6 +1160,9 @@ static void gbam2bam_connect_work(struct work_struct *w) if (d->src_pipe_type == USB_BAM_PIPE_SYS2BAM) { d->ipa_params.notify = d->ul_params.teth_cb; d->ipa_params.priv = d->ul_params.teth_priv; + d->ipa_params.reset_pipe_after_lpm = + (gadget_is_dwc3(gadget) && + msm_dwc3_reset_ep_after_lpm(gadget)); } d->ipa_params.dir = PEER_PERIPHERAL_TO_USB; ret = usb_bam_connect_ipa(&d->ipa_params); @@ -1130,18 +1173,16 @@ static void gbam2bam_connect_work(struct work_struct *w) } if (gadget && gadget_is_dwc3(gadget)) { - u8 idx; - - idx = usb_bam_get_connection_idx(gadget->name, - IPA_P_BAM, PEER_PERIPHERAL_TO_USB, + d->dst_bam_idx = usb_bam_get_connection_idx( + gadget->name, IPA_P_BAM, PEER_PERIPHERAL_TO_USB, USB_BAM_DEVICE, 0); - if (idx < 0) { + if (d->dst_bam_idx < 0) { pr_err("%s: get_connection_idx failed\n", __func__); return; } - configure_data_fifo(idx, port->port_usb->in, + configure_data_fifo(d->dst_bam_idx, port->port_usb->in, d->dst_pipe_type); } @@ -1264,10 +1305,18 @@ static void gbam2bam_suspend_work(struct work_struct *w) { struct gbam_port *port = container_of(w, struct gbam_port, suspend_w); struct bam_ch_info *d = &port->data_ch; + int ret; pr_debug("%s: suspend work started\n", __func__); - usb_bam_register_wake_cb(d->dst_connection_idx, gbam_wake_cb, port); + ret = usb_bam_register_wake_cb(d->dst_connection_idx, + gbam_wake_cb, port); + if (ret) { + pr_err("%s(): Failed to register BAM wake callback.\n", + __func__); + return; + } + if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) { usb_bam_register_start_stop_cbs(d->dst_connection_idx, gbam_start, gbam_stop, port); @@ -1279,12 +1328,40 @@ static void gbam2bam_resume_work(struct work_struct *w) { struct gbam_port *port = container_of(w, struct gbam_port, resume_w); struct bam_ch_info *d = &port->data_ch; + struct f_rmnet *dev = NULL; + struct usb_gadget *gadget = NULL; + int ret; pr_debug("%s: resume work started\n", __func__); + if (port) + dev = port_to_rmnet(port->gr); + if (dev && dev->cdev) { + gadget = dev->cdev->gadget; + } else { + pr_err("Unable to retrieve gadget handle\n"); + return; + } - usb_bam_register_wake_cb(d->dst_connection_idx, NULL, NULL); - if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) + ret = usb_bam_register_wake_cb(d->dst_connection_idx, NULL, NULL); + if (ret) { + pr_err("%s(): Failed to register BAM wake callback.\n", + __func__); + return; + } + + if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) { + if (gadget_is_dwc3(gadget) && + msm_dwc3_reset_ep_after_lpm(gadget)) { + configure_data_fifo(d->src_bam_idx, + port->port_usb->out, + d->src_pipe_type); + configure_data_fifo(d->dst_bam_idx, + port->port_usb->in, + d->dst_pipe_type); + msm_dwc3_reset_dbm_ep(port->port_usb->in); + } usb_bam_resume(&d->ipa_params); + } } static int gbam_peer_reset_cb(void *param) diff --git a/drivers/usb/gadget/u_bam_data.c b/drivers/usb/gadget/u_bam_data.c index a0d8b245ae6d..0ae7826072fd 100644 --- a/drivers/usb/gadget/u_bam_data.c +++ b/drivers/usb/gadget/u_bam_data.c @@ -81,6 +81,8 @@ struct bam_data_ch_info { u32 dst_pipe_idx; u8 src_connection_idx; u8 dst_connection_idx; + int src_bam_idx; + int dst_bam_idx; enum function_type func_type; enum transport_type trans; @@ -653,6 +655,10 @@ static void bam2bam_data_connect_work(struct work_struct *w) bam_data_ipa_sys2bam_notify_cb; d->ul_params.teth_priv = d->ipa_params.priv; d->ipa_params.priv = &d->ul_params; + } else { + d->ipa_params.reset_pipe_after_lpm = + (gadget_is_dwc3(gadget) && + msm_dwc3_reset_ep_after_lpm(gadget)); } ret = usb_bam_connect_ipa(&d->ipa_params); @@ -665,18 +671,18 @@ static void bam2bam_data_connect_work(struct work_struct *w) d_port->ipa_consumer_ep = d->ipa_params.ipa_cons_ep_idx; if (gadget_is_dwc3(gadget)) { - u8 idx; - - idx = usb_bam_get_connection_idx(gadget->name, - IPA_P_BAM, USB_TO_PEER_PERIPHERAL, - USB_BAM_DEVICE, 0); - if (idx < 0) { + d->src_bam_idx = usb_bam_get_connection_idx( + gadget->name, + IPA_P_BAM, USB_TO_PEER_PERIPHERAL, + USB_BAM_DEVICE, 0); + if (d->src_bam_idx < 0) { pr_err("%s: get_connection_idx failed\n", __func__); return; } - configure_usb_data_fifo(idx, port->port_usb->out, + configure_usb_data_fifo(d->src_bam_idx, + port->port_usb->out, d->src_pipe_type); } @@ -699,6 +705,13 @@ static void bam2bam_data_connect_work(struct work_struct *w) d->ipa_params.skip_ep_cfg = rndis_qc_get_skip_ep_config(); } + + if (d->src_pipe_type == USB_BAM_PIPE_BAM2BAM) { + d->ipa_params.reset_pipe_after_lpm = + (gadget_is_dwc3(gadget) && + msm_dwc3_reset_ep_after_lpm(gadget)); + } + ret = usb_bam_connect_ipa(&d->ipa_params); if (ret) { pr_err("%s: usb_bam_connect_ipa failed: err:%d\n", @@ -712,18 +725,18 @@ static void bam2bam_data_connect_work(struct work_struct *w) d_port->ipa_consumer_ep); if (gadget_is_dwc3(gadget)) { - u8 idx; - - idx = usb_bam_get_connection_idx(gadget->name, - IPA_P_BAM, PEER_PERIPHERAL_TO_USB, - USB_BAM_DEVICE, 0); - if (idx < 0) { + d->dst_bam_idx = usb_bam_get_connection_idx( + gadget->name, + IPA_P_BAM, PEER_PERIPHERAL_TO_USB, + USB_BAM_DEVICE, 0); + if (d->dst_bam_idx < 0) { pr_err("%s: get_connection_idx failed\n", __func__); return; } - configure_usb_data_fifo(idx, port->port_usb->in, + configure_usb_data_fifo(d->dst_bam_idx, + port->port_usb->in, d->dst_pipe_type); } @@ -1204,6 +1217,16 @@ static int bam_data_wake_cb(void *param) static void bam_data_start(void *param, enum usb_bam_pipe_dir dir) { struct bam_data_port *port = param; + struct data_port *d_port = port->port_usb; + struct bam_data_ch_info *d = &port->data_ch; + struct usb_gadget *gadget; + + if (!d_port || !d_port->cdev || !d_port->cdev->gadget) { + pr_err("%s:d_port,cdev or gadget is NULL\n", __func__); + return; + } + + gadget = d_port->cdev->gadget; if (dir == USB_TO_PEER_PERIPHERAL) { if (port->data_ch.src_pipe_type == USB_BAM_PIPE_BAM2BAM) @@ -1211,6 +1234,22 @@ static void bam_data_start(void *param, enum usb_bam_pipe_dir dir) else bam_data_start_rx(port); } else { + if (gadget_is_dwc3(gadget) && + msm_dwc3_reset_ep_after_lpm(gadget)) { + u8 idx; + + idx = usb_bam_get_connection_idx(gadget->name, + IPA_P_BAM, PEER_PERIPHERAL_TO_USB, + USB_BAM_DEVICE, 0); + if (idx < 0) { + pr_err("%s: get_connection_idx failed\n", + __func__); + return; + } + configure_data_fifo(idx, + port->port_usb->in, + d->dst_pipe_type); + } bam_data_start_endless_tx(port); } @@ -1293,6 +1332,8 @@ static void bam2bam_data_resume_work(struct work_struct *w) struct bam_data_port *port = container_of(w, struct bam_data_port, resume_w); struct bam_data_ch_info *d = &port->data_ch; + struct data_port *d_port = port->port_usb; + struct usb_gadget *gadget = d_port->cdev->gadget; int ret; pr_debug("%s: resume work started\n", __func__); @@ -1309,8 +1350,19 @@ static void bam2bam_data_resume_work(struct work_struct *w) return; } - if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) + if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) { + if (gadget_is_dwc3(gadget) && + msm_dwc3_reset_ep_after_lpm(gadget)) { + configure_usb_data_fifo(d->src_bam_idx, + port->port_usb->out, + d->src_pipe_type); + configure_usb_data_fifo(d->dst_bam_idx, + port->port_usb->in, + d->dst_pipe_type); + msm_dwc3_reset_dbm_ep(port->port_usb->in); + } usb_bam_resume(&d->ipa_params); + } } void u_bam_data_set_max_xfer_size(u32 max_transfer_size) diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h index 079e62777335..51d5ce2bdd6e 100644 --- a/include/linux/usb/msm_hsusb.h +++ b/include/linux/usb/msm_hsusb.h @@ -615,6 +615,8 @@ int msm_ep_unconfig(struct usb_ep *ep); void dwc3_tx_fifo_resize_request(struct usb_ep *ep, bool qdss_enable); int msm_data_fifo_config(struct usb_ep *ep, phys_addr_t addr, u32 size, u8 dst_pipe_idx); +bool msm_dwc3_reset_ep_after_lpm(struct usb_gadget *gadget); +int msm_dwc3_reset_dbm_ep(struct usb_ep *ep); void msm_dwc3_restart_usb_session(struct usb_gadget *gadget); @@ -652,5 +654,16 @@ static inline int msm_register_usb_ext_notification( { return -ENODEV; } + +static inline bool msm_dwc3_reset_ep_after_lpm(struct usb_gadget *gadget) +{ + return false; +} + +static inline int msm_dwc3_reset_dbm_ep(struct usb_ep *ep) +{ + return -ENODEV; +} + #endif #endif diff --git a/include/linux/usb_bam.h b/include/linux/usb_bam.h index 20e50e0f878e..a94ebcf69923 100644 --- a/include/linux/usb_bam.h +++ b/include/linux/usb_bam.h @@ -83,6 +83,7 @@ struct usb_bam_connect_ipa_params { int (*activity_notify)(void *priv); int (*inactivity_notify)(void *priv); bool skip_ep_cfg; + bool reset_pipe_after_lpm; }; /** @@ -162,6 +163,7 @@ struct usb_bam_pipe_connect { void (*start)(void *, enum usb_bam_pipe_dir); void (*stop)(void *, enum usb_bam_pipe_dir); void *start_stop_param; + bool reset_pipe_after_lpm; }; /** -- GitLab