diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index a44fca5beac225f8e863fee784cf81dfed18aef9..215381554e6ad8ab3244c1fa195b73bb44bfcab9 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 b4f4363e5fc04f736d22e37e598d23f0f79eeb61..6097adb11ef7afa8336f17a75af5edd65dcaf914 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 a0d8b245ae6da205526fb8554bb4d764b5177021..0ae7826072fdc0b660a31477225679fc5130d508 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 079e6277733528298e0b2adf5fb25385ef8ed785..51d5ce2bdd6e33ed86bf2427ea5d1ff294f2d606 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 20e50e0f878e8e4e926f47cfe2c5ecd5b9d7b040..a94ebcf699235e80b3006f6149e04d1c3a4ce144 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;
 };
 
 /**