Merge "extcon: qcom-spmi: Add support for VBUS detection"
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
index f2f74c3..8f59515 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
@@ -912,6 +912,21 @@
 		qcom,pet-time = <10000>;
 	};
 
+	qcom_rng: qrng@793000{
+		compatible = "qcom,msm-rng";
+		reg = <0x793000 0x1000>;
+		qcom,msm-rng-iface-clk;
+		qcom,no-qrng-config;
+		qcom,msm-bus,name = "msm-rng-noc";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+			<1 618 0 0>,    /* No vote */
+			<1 618 0 800>;  /* 100 KHz */
+		clocks = <&clock_gcc GCC_PRNG_AHB_CLK>;
+		clock-names = "iface_clk";
+	};
+
 	qcom_cedev: qcedev@1de0000 {
 		compatible = "qcom,qcedev";
 		reg = <0x1de0000 0x20000>,
diff --git a/arch/arm/configs/sdxpoorwills-perf_defconfig b/arch/arm/configs/sdxpoorwills-perf_defconfig
index 0c6fdf3..1f04446 100644
--- a/arch/arm/configs/sdxpoorwills-perf_defconfig
+++ b/arch/arm/configs/sdxpoorwills-perf_defconfig
@@ -213,6 +213,7 @@
 CONFIG_SERIAL_MSM_HS=y
 CONFIG_DIAG_CHAR=y
 CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MSM_LEGACY=y
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MSM_V2=y
@@ -390,4 +391,7 @@
 CONFIG_CORESIGHT_CTI=y
 CONFIG_CORESIGHT_EVENT=y
 CONFIG_CORESIGHT_HWEVENT=y
+CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
+CONFIG_CRYPTO_DEV_QCRYPTO=y
+CONFIG_CRYPTO_DEV_QCEDEV=y
 CONFIG_QMI_ENCDEC=y
diff --git a/arch/arm/configs/sdxpoorwills_defconfig b/arch/arm/configs/sdxpoorwills_defconfig
index 05a7afb..0b5a266 100644
--- a/arch/arm/configs/sdxpoorwills_defconfig
+++ b/arch/arm/configs/sdxpoorwills_defconfig
@@ -207,6 +207,7 @@
 CONFIG_SERIAL_MSM_HS=y
 CONFIG_DIAG_CHAR=y
 CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MSM_LEGACY=y
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MSM_V2=y
@@ -408,8 +409,10 @@
 CONFIG_CORESIGHT_TGU=y
 CONFIG_CORESIGHT_HWEVENT=y
 CONFIG_CORESIGHT_DUMMY=y
-CONFIG_CRYPTO_ECB=y
 CONFIG_CRYPTO_CMAC=y
 CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
+CONFIG_CRYPTO_DEV_QCRYPTO=y
+CONFIG_CRYPTO_DEV_QCEDEV=y
 CONFIG_XZ_DEC=y
 CONFIG_QMI_ENCDEC=y
diff --git a/arch/arm64/boot/dts/qcom/msm8953-thermal.dtsi b/arch/arm64/boot/dts/qcom/msm8953-thermal.dtsi
index d5a6f52..d6d4427 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-thermal.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-thermal.dtsi
@@ -1087,4 +1087,19 @@
 			};
 		};
 	};
+
+	pa-therm0 {
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm8953_adc_tm 0x36>;
+		thermal-governor = "user_space";
+
+		trips {
+			active-config0 {
+				temperature = <65000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+	};
 };
diff --git a/arch/arm64/boot/dts/qcom/pm8953.dtsi b/arch/arm64/boot/dts/qcom/pm8953.dtsi
index 6cce3b7..21fdfd3 100644
--- a/arch/arm64/boot/dts/qcom/pm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8953.dtsi
@@ -248,6 +248,7 @@
 			qcom,adc-bit-resolution = <15>;
 			qcom,adc-vdd-reference = <1800>;
 			qcom,adc_tm-vadc = <&pm8953_vadc>;
+			#thermal-sensor-cells = <1>;
 		};
 
 		pm8953_rtc: qcom,pm8953_rtc {
diff --git a/arch/arm64/boot/dts/qcom/sda845-svr.dtsi b/arch/arm64/boot/dts/qcom/sda845-svr.dtsi
index fa82be2..51dbe74 100644
--- a/arch/arm64/boot/dts/qcom/sda845-svr.dtsi
+++ b/arch/arm64/boot/dts/qcom/sda845-svr.dtsi
@@ -324,6 +324,10 @@
 	};
 };
 
+&adsp_mem {
+	size = <0 0xc800000>;
+};
+
 &qupv3_se9_2uart {
 	status = "ok";
 };
diff --git a/arch/arm64/boot/dts/qcom/sdm670-vidc.dtsi b/arch/arm64/boot/dts/qcom/sdm670-vidc.dtsi
index 01d4057..a0b4a22 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-vidc.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-vidc.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -42,7 +42,7 @@
 			"bus_clk", "core0_clk", "core0_bus_clk",
 			"core1_clk", "core1_bus_clk";
 		qcom,clock-configs = <0x1 0x0 0x0 0x1 0x0 0x1 0x0>;
-		qcom,allowed-clock-rates = <100000000 200000000 320000000
+		qcom,allowed-clock-rates = <100000000 200000000 330000000
 			380000000 444000000 533000000>;
 
 		/* Buses */
@@ -138,7 +138,7 @@
 		qcom,proxy-clock-names = "core_clk", "iface_clk",
 			"bus_clk", "core0_clk", "core0_bus_clk";
 		qcom,clock-configs = <0x1 0x0 0x0 0x1 0x0>;
-		qcom,allowed-clock-rates = <100000000 200000000 320000000
+		qcom,allowed-clock-rates = <100000000 200000000 330000000
 			364700000>;
 
 		/* Buses */
diff --git a/arch/arm64/configs/sdm670-perf_defconfig b/arch/arm64/configs/sdm670-perf_defconfig
index 83b0d66..560c510 100644
--- a/arch/arm64/configs/sdm670-perf_defconfig
+++ b/arch/arm64/configs/sdm670-perf_defconfig
@@ -378,6 +378,7 @@
 CONFIG_DRM=y
 CONFIG_DRM_SDE_EVTLOG_DEBUG=y
 CONFIG_DRM_SDE_RSC=y
+CONFIG_DRM_LT_LT9611=y
 CONFIG_FB_VIRTUAL=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index e2e0148..c5f8092 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -17,6 +17,7 @@
 #include <linux/list.h>
 #include <linux/of.h>
 #include <linux/of_graph.h>
+#include <linux/of_gpio.h>
 #include <linux/err.h>
 
 #include "msm_drv.h"
@@ -309,6 +310,90 @@
 	dsi_panel_release_panel_lock(display->panel);
 }
 
+static irqreturn_t dsi_display_panel_te_irq_handler(int irq, void *data)
+{
+	struct dsi_display *display = (struct dsi_display *)data;
+
+	/*
+	 * This irq handler is used for sole purpose of identifying
+	 * ESD attacks on panel and we can safely assume IRQ_HANDLED
+	 * in case of display not being initalized yet
+	 */
+	if (!display)
+		return IRQ_HANDLED;
+
+	atomic_set(&display->te_irq_triggered, 1);
+
+	return IRQ_HANDLED;
+}
+
+static void dsi_display_change_te_irq_status(struct dsi_display *display,
+					bool enable)
+{
+	if (!display) {
+		pr_err("Invalid params\n");
+		return;
+	}
+
+	/* Handle unbalanced irq enable/disbale calls */
+	if (enable && !display->is_te_irq_enabled) {
+		atomic_set(&display->te_irq_triggered, 1);
+		enable_irq(gpio_to_irq(display->disp_te_gpio));
+		display->is_te_irq_enabled = true;
+	} else if (!enable && display->is_te_irq_enabled) {
+		disable_irq(gpio_to_irq(display->disp_te_gpio));
+		atomic_set(&display->te_irq_triggered, 0);
+		display->is_te_irq_enabled = false;
+	}
+}
+
+static void dsi_display_register_te_irq(struct dsi_display *display)
+{
+	int rc;
+	struct platform_device *pdev;
+	struct device *dev;
+
+	pdev = display->pdev;
+	if (!pdev) {
+		pr_err("invalid platform device\n");
+		return;
+	}
+
+	dev = &pdev->dev;
+	if (!dev) {
+		pr_err("invalid device\n");
+		return;
+	}
+
+	rc = devm_request_irq(dev, gpio_to_irq(display->disp_te_gpio),
+			dsi_display_panel_te_irq_handler, IRQF_TRIGGER_FALLING,
+			"TE_GPIO", display);
+	if (rc) {
+		pr_err("TE request_irq failed for ESD rc:%d\n", rc);
+		return;
+	}
+
+	disable_irq(gpio_to_irq(display->disp_te_gpio));
+	display->is_te_irq_enabled = false;
+}
+
+static bool dsi_display_is_te_based_esd(struct dsi_display *display)
+{
+	u32 status_mode = 0;
+
+	if (!display->panel) {
+		pr_err("Invalid panel data\n");
+		return false;
+	}
+
+	status_mode = display->panel->esd_config.status_mode;
+
+	if (status_mode == ESD_MODE_PANEL_TE &&
+			gpio_is_valid(display->disp_te_gpio))
+		return true;
+	return false;
+}
+
 /* Allocate memory for cmd dma tx buffer */
 static int dsi_host_alloc_cmd_tx_buffer(struct dsi_display *display)
 {
@@ -421,6 +506,27 @@
 	return false;
 }
 
+static void dsi_display_parse_te_gpio(struct dsi_display *display)
+{
+	struct platform_device *pdev;
+	struct device *dev;
+
+	pdev = display->pdev;
+	if (!pdev) {
+		pr_err("Inavlid platform device\n");
+		return;
+	}
+
+	dev = &pdev->dev;
+	if (!dev) {
+		pr_err("Inavlid platform device\n");
+		return;
+	}
+
+	display->disp_te_gpio = of_get_named_gpio(dev->of_node,
+					"qcom,platform-te-gpio", 0);
+}
+
 static int dsi_display_read_status(struct dsi_display_ctrl *ctrl,
 		struct dsi_panel *panel)
 {
@@ -566,12 +672,16 @@
 
 static int dsi_display_status_check_te(struct dsi_display *display)
 {
-	int rc = 0;
+	int const esd_check_success = 1;
 
-	pr_debug(" ++\n");
-	/* TODO: wait for TE interrupt from panel */
+	if (atomic_read(&display->te_irq_triggered)) {
+		atomic_set(&display->te_irq_triggered, 0);
+	} else {
+		pr_err("ESD check failed\n");
+		return -EINVAL;
+	}
 
-	return rc;
+	return esd_check_success;
 }
 
 int dsi_display_check_status(void *display)
@@ -3094,6 +3204,9 @@
 		display->type = DSI_DISPLAY_SINGLE;
 	}
 
+	/* Parse TE gpio */
+	dsi_display_parse_te_gpio(display);
+
 error:
 	return rc;
 }
@@ -3950,6 +4063,9 @@
 		}
 	}
 
+	/* register te irq handler */
+	dsi_display_register_te_irq(display);
+
 	/* Initialize resources for continuous splash */
 	rc = dsi_display_splash_res_init(display);
 	if (rc)
@@ -5190,6 +5306,9 @@
 
 	mode = display->panel->cur_mode;
 
+	if (dsi_display_is_te_based_esd(display))
+		dsi_display_change_te_irq_status(display, true);
+
 	if (mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) {
 		if (display->is_cont_splash_enabled) {
 			pr_err("DMS is not supposed to be set on first frame\n");
@@ -5717,6 +5836,10 @@
 		pr_err("[%s] display wake up failed, rc=%d\n",
 		       display->name, rc);
 
+	/* Disable panel TE irq */
+	if (dsi_display_is_te_based_esd(display))
+		dsi_display_change_te_irq_status(display, false);
+
 	rc = dsi_panel_unprepare(display->panel);
 	if (rc)
 		pr_err("[%s] panel unprepare failed, rc=%d\n",
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
index 53004e4..e243a92 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
@@ -132,6 +132,9 @@
  * @is_active:        Is display active.
  * @is_cont_splash_enabled:  Is continuous splash enabled
  * @display_lock:     Mutex for dsi_display interface.
+ * @disp_te_gpio:     GPIO for panel TE interrupt.
+ * @is_te_irq_enabled:bool to specify whether TE interrupt is enabled.
+ * @te_irq_triggered: atomic state notifying panel TE interrupt.
  * @ctrl_count:       Number of DSI interfaces required by panel.
  * @ctrl:             Controller information for DSI display.
  * @panel:            Handle to DSI panel.
@@ -173,6 +176,9 @@
 	bool is_active;
 	bool is_cont_splash_enabled;
 	struct mutex display_lock;
+	int disp_te_gpio;
+	bool is_te_irq_enabled;
+	atomic_t te_irq_triggered;
 
 	u32 ctrl_count;
 	struct dsi_display_ctrl ctrl[MAX_DSI_CTRLS_PER_DISPLAY];
diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c
index a615dca..4775c3e 100644
--- a/drivers/gpu/msm/adreno_a5xx.c
+++ b/drivers/gpu/msm/adreno_a5xx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1353,31 +1353,27 @@
 
 	/* todo double check the reg writes */
 	while ((cur - opcode) < length) {
-		switch (cur[0]) {
-		/* Write a 32 bit value to a 64 bit reg */
-		case 1:
+		if (cur[0] == 1 && ((cur + 4) - opcode) <= length) {
+			/* Write a 32 bit value to a 64 bit reg */
 			reg = cur[2];
 			reg = (reg << 32) | cur[1];
 			kgsl_regwrite(KGSL_DEVICE(adreno_dev), reg, cur[3]);
 			cur += 4;
-			break;
-		/* Write a 64 bit value to a 64 bit reg */
-		case 2:
+		} else if (cur[0] == 2 && ((cur + 5) - opcode) <= length) {
+			/* Write a 64 bit value to a 64 bit reg */
 			reg = cur[2];
 			reg = (reg << 32) | cur[1];
 			val = cur[4];
 			val = (val << 32) | cur[3];
 			kgsl_regwrite(KGSL_DEVICE(adreno_dev), reg, val);
 			cur += 5;
-			break;
-		/* Delay for X usec */
-		case 3:
+		} else if (cur[0] == 3 && ((cur + 2) - opcode) <= length) {
+			/* Delay for X usec */
 			udelay(cur[1]);
 			cur += 2;
-			break;
-		default:
+		} else
 			return -EINVAL;
-	} }
+	}
 	return 0;
 }
 
diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
index 2fb36f0..5c13de5 100644
--- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
+++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
@@ -399,7 +399,7 @@
 
 static int msm_vb2_buf_done(struct vb2_v4l2_buffer *vb, int session_id,
 				unsigned int stream_id, uint32_t sequence,
-				struct timeval *ts, uint32_t reserved)
+				struct timeval *ts, uint32_t buf_type)
 {
 	unsigned long flags, rl_flags;
 	struct msm_vb2_buffer *msm_vb2;
@@ -441,6 +441,7 @@
 		/* put buf before buf done */
 		if (msm_vb2->in_freeq) {
 			vb2_v4l2_buf->sequence = sequence;
+			vb2_v4l2_buf->timecode.type = buf_type;
 			vb2_v4l2_buf->vb2_buf.timestamp =
 				(ts->tv_sec * 1000000 + ts->tv_usec) * 1000;
 			vb2_buffer_done(&vb2_v4l2_buf->vb2_buf,
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index dec698f..6314270 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -3313,7 +3313,7 @@
 	return ret;
 }
 
-bool usb_bam_get_prod_granted(enum usb_ctrl bam_type, u8 idx)
+bool usb_bam_get_prod_granted(enum usb_ctrl bam_type)
 {
 	return (info[bam_type].cur_prod_state == IPA_RM_RESOURCE_GRANTED);
 }
diff --git a/drivers/slimbus/slim-msm.c b/drivers/slimbus/slim-msm.c
index 01779f9..24a3ccf 100644
--- a/drivers/slimbus/slim-msm.c
+++ b/drivers/slimbus/slim-msm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -490,32 +490,26 @@
 	return SLIM_P_INPROGRESS;
 }
 
-static int msm_slim_iommu_map(struct msm_slim_ctrl *dev, phys_addr_t iobuf,
+static dma_addr_t msm_slim_iommu_map(struct msm_slim_ctrl *dev, void *buf_addr,
 			      u32 len)
 {
-	int ret;
+	dma_addr_t ret;
+	struct device *devp = dev->iommu_desc.cb_dev ? dev->iommu_desc.cb_dev :
+							dev->dev;
+	ret = dma_map_single(devp, buf_addr, len, DMA_BIDIRECTIONAL);
 
-	if (!dev->iommu_desc.cb_dev)
-		return 0;
+	if (dma_mapping_error(devp, ret))
+		return DMA_ERROR_CODE;
 
-	ret = iommu_map(dev->iommu_desc.iommu_map->domain,
-			rounddown(iobuf, PAGE_SIZE),
-			rounddown(iobuf, PAGE_SIZE),
-			roundup((len + (iobuf - rounddown(iobuf, PAGE_SIZE))),
-				PAGE_SIZE), IOMMU_READ | IOMMU_WRITE);
 	return ret;
 }
 
-static void msm_slim_iommu_unmap(struct msm_slim_ctrl *dev, phys_addr_t iobuf,
+static void msm_slim_iommu_unmap(struct msm_slim_ctrl *dev, dma_addr_t buf_addr,
 				u32 len)
 {
-	if (!dev->iommu_desc.cb_dev)
-		return;
-
-	iommu_unmap(dev->iommu_desc.iommu_map->domain,
-		    rounddown(iobuf, PAGE_SIZE),
-		    roundup((len + (iobuf - rounddown(iobuf, PAGE_SIZE))),
-			    PAGE_SIZE));
+	struct device *devp = dev->iommu_desc.cb_dev ? dev->iommu_desc.cb_dev :
+							dev->dev;
+	dma_unmap_single(devp, buf_addr, len, DMA_BIDIRECTIONAL);
 }
 
 static void msm_slim_port_cb(struct sps_event_notify *ev)
@@ -539,11 +533,12 @@
 		complete(comp);
 }
 
-int msm_slim_port_xfer(struct slim_controller *ctrl, u8 pn, phys_addr_t iobuf,
+int msm_slim_port_xfer(struct slim_controller *ctrl, u8 pn, void *buf,
 			u32 len, struct completion *comp)
 {
 	struct sps_register_event sreg;
 	int ret;
+	dma_addr_t dma_buf;
 	struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
 
 	if (pn >= dev->port_nums)
@@ -552,9 +547,11 @@
 	if (!dev->pipes[pn].connected)
 		return -ENOTCONN;
 
-	ret = msm_slim_iommu_map(dev, iobuf, len);
-	if (ret)
-		return ret;
+	dma_buf =  msm_slim_iommu_map(dev, buf, len);
+	if (dma_buf == DMA_ERROR_CODE) {
+		dev_err(dev->dev, "error DMA mapping buffers\n");
+		return -ENOMEM;
+	}
 
 	sreg.options = (SPS_EVENT_DESC_DONE|SPS_EVENT_ERROR);
 	sreg.mode = SPS_TRIGGER_WAIT;
@@ -564,10 +561,10 @@
 	ret = sps_register_event(dev->pipes[pn].sps, &sreg);
 	if (ret) {
 		dev_dbg(dev->dev, "sps register event error:%x\n", ret);
-		msm_slim_iommu_unmap(dev, iobuf, len);
+		msm_slim_iommu_unmap(dev, dma_buf, len);
 		return ret;
 	}
-	ret = sps_transfer_one(dev->pipes[pn].sps, iobuf, len, comp,
+	ret = sps_transfer_one(dev->pipes[pn].sps, dma_buf, len, comp,
 				SPS_IOVEC_FLAG_INT);
 	dev_dbg(dev->dev, "sps submit xfer error code:%x\n", ret);
 	if (!ret) {
@@ -581,7 +578,7 @@
 		/* Make sure that port registers are updated before returning */
 		mb();
 	} else {
-		msm_slim_iommu_unmap(dev, iobuf, len);
+		msm_slim_iommu_unmap(dev, dma_buf, len);
 	}
 
 	return ret;
diff --git a/drivers/slimbus/slim-msm.h b/drivers/slimbus/slim-msm.h
index 5859c5f..edebfd9 100644
--- a/drivers/slimbus/slim-msm.h
+++ b/drivers/slimbus/slim-msm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -423,7 +423,7 @@
 int msm_slim_connect_pipe_port(struct msm_slim_ctrl *dev, u8 pn);
 enum slim_port_err msm_slim_port_xfer_status(struct slim_controller *ctr,
 				u8 pn, phys_addr_t *done_buf, u32 *done_len);
-int msm_slim_port_xfer(struct slim_controller *ctrl, u8 pn, phys_addr_t iobuf,
+int msm_slim_port_xfer(struct slim_controller *ctrl, u8 pn, void *buf,
 			u32 len, struct completion *comp);
 int msm_send_msg_buf(struct msm_slim_ctrl *dev, u32 *buf, u8 len, u32 tx_reg);
 u32 *msm_get_msg_buf(struct msm_slim_ctrl *dev, int len,
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index f34467b..1140b33 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1600,14 +1600,14 @@
  * Client will call slim_port_get_xfer_status to get error and/or number of
  * bytes transferred if used asynchronously.
  */
-int slim_port_xfer(struct slim_device *sb, u32 ph, phys_addr_t iobuf, u32 len,
+int slim_port_xfer(struct slim_device *sb, u32 ph, void *buf, u32 len,
 				struct completion *comp)
 {
 	struct slim_controller *ctrl = sb->ctrl;
 	u8 pn = SLIM_HDL_TO_PORT(ph);
 
 	dev_dbg(&ctrl->dev, "port xfer: num:%d", pn);
-	return ctrl->port_xfer(ctrl, pn, iobuf, len, comp);
+	return ctrl->port_xfer(ctrl, pn, buf, len, comp);
 }
 EXPORT_SYMBOL(slim_port_xfer);
 
diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile
index 857c734..a9344a5 100644
--- a/drivers/usb/gadget/function/Makefile
+++ b/drivers/usb/gadget/function/Makefile
@@ -66,5 +66,5 @@
 obj-$(CONFIG_USB_F_QDSS)        += usb_f_qdss.o
 usb_f_qcrndis-y			:= f_qc_rndis.o u_data_ipa.o
 obj-$(CONFIG_USB_F_QCRNDIS)	+= usb_f_qcrndis.o
-usb_f_rmnet_bam-y		:= f_rmnet.o u_ctrl_qti.o
+usb_f_rmnet_bam-y		:= f_rmnet.o u_ctrl_qti.o u_bam_dmux.o
 obj-$(CONFIG_USB_F_RMNET_BAM)	+= usb_f_rmnet_bam.o
diff --git a/drivers/usb/gadget/function/f_qc_rndis.c b/drivers/usb/gadget/function/f_qc_rndis.c
index a8e7092..908805a 100644
--- a/drivers/usb/gadget/function/f_qc_rndis.c
+++ b/drivers/usb/gadget/function/f_qc_rndis.c
@@ -102,7 +102,7 @@
 	struct usb_ep			*notify;
 	struct usb_request		*notify_req;
 	atomic_t			notify_count;
-	struct gadget_ipa_port		bam_port;
+	struct data_port		bam_port;
 	struct cdev			cdev;
 	struct device			*dev;
 	u8				port_num;
diff --git a/drivers/usb/gadget/function/f_rmnet.c b/drivers/usb/gadget/function/f_rmnet.c
index d6d7e73..47b87b0a 100644
--- a/drivers/usb/gadget/function/f_rmnet.c
+++ b/drivers/usb/gadget/function/f_rmnet.c
@@ -19,7 +19,6 @@
 #include <linux/usb_bam.h>
 #include <linux/module.h>
 
-#include "u_rmnet.h"
 #include "u_data_ipa.h"
 #include "configfs.h"
 
@@ -31,13 +30,15 @@
 struct f_rmnet {
 	struct usb_function             func;
 	enum qti_port_type		qti_port_type;
-	enum ipa_func_type		func_type;
+	enum bam_dmux_func_type		bam_dmux_func_type;
+	enum data_xport_type		xport_type;
+	enum ipa_func_type		ipa_func_type;
 	struct grmnet			port;
 	int				ifc_id;
 	atomic_t			online;
 	atomic_t			ctrl_online;
 	struct usb_composite_dev	*cdev;
-	struct gadget_ipa_port		ipa_port;
+	struct data_port		bam_port;
 	spinlock_t			lock;
 
 	/* usb eps*/
@@ -308,11 +309,22 @@
 
 	if (!strncasecmp("rmnet", name, MAX_INST_NAME_LEN)) {
 		dev->qti_port_type = QTI_PORT_RMNET;
-		dev->func_type = USB_IPA_FUNC_RMNET;
+		dev->xport_type = BAM2BAM_IPA;
+		dev->ipa_func_type = USB_IPA_FUNC_RMNET;
 	} else if (!strncasecmp("dpl", name, MAX_INST_NAME_LEN)) {
 		dev->qti_port_type = QTI_PORT_DPL;
-		dev->func_type = USB_IPA_FUNC_DPL;
+		dev->xport_type = BAM2BAM_IPA;
+		dev->ipa_func_type = USB_IPA_FUNC_DPL;
+	} else if (!strncasecmp("rmnet_bam_dmux", name, MAX_INST_NAME_LEN)) {
+		dev->qti_port_type = QTI_PORT_RMNET;
+		dev->xport_type = BAM_DMUX;
+		dev->bam_dmux_func_type = BAM_DMUX_FUNC_RMNET;
+	} else if (!strncasecmp("dpl_bam_dmux", name, MAX_INST_NAME_LEN)) {
+		dev->qti_port_type = QTI_PORT_DPL;
+		dev->xport_type = BAM_DMUX;
+		dev->bam_dmux_func_type = BAM_DMUX_FUNC_DPL;
 	}
+
 	return 0;
 
 error:
@@ -380,7 +392,8 @@
 	enum usb_ctrl		usb_bam_type;
 	int bam_pipe_num = (dev->qti_port_type == QTI_PORT_DPL) ? 1 : 0;
 
-	ret = gqti_ctrl_connect(&dev->port, dev->qti_port_type, dev->ifc_id);
+	ret = gqti_ctrl_connect(&dev->port, dev->qti_port_type, dev->ifc_id,
+							dev->xport_type);
 	if (ret) {
 		pr_err("%s: gqti_ctrl_connect failed: err:%d\n",
 			__func__, ret);
@@ -388,31 +401,42 @@
 	}
 	if (dev->qti_port_type == QTI_PORT_DPL)
 		dev->port.send_encap_cmd(QTI_PORT_DPL, NULL, 0);
-	dev->ipa_port.cdev = dev->cdev;
-	ipa_data_port_select(dev->func_type);
-	usb_bam_type = usb_bam_get_bam_type(gadget->name);
+	dev->bam_port.cdev = dev->cdev;
+	if (dev->xport_type == BAM_DMUX) {
+		ret = gbam_connect(&dev->bam_port, dev->bam_dmux_func_type);
+		if (ret)
+			pr_err("%s: gbam_connect failed: err:%d\n",
+				__func__, ret);
+	} else {
+		ipa_data_port_select(dev->ipa_func_type);
+		usb_bam_type = usb_bam_get_bam_type(gadget->name);
 
-	if (dev->ipa_port.in) {
-		dst_connection_idx = usb_bam_get_connection_idx(usb_bam_type,
-			IPA_P_BAM, PEER_PERIPHERAL_TO_USB,
-			USB_BAM_DEVICE, bam_pipe_num);
+		if (dev->bam_port.in) {
+			dst_connection_idx = usb_bam_get_connection_idx(
+						usb_bam_type, IPA_P_BAM,
+						PEER_PERIPHERAL_TO_USB,
+						USB_BAM_DEVICE, bam_pipe_num);
+		}
+		if (dev->bam_port.out) {
+			src_connection_idx = usb_bam_get_connection_idx(
+						usb_bam_type, IPA_P_BAM,
+						USB_TO_PEER_PERIPHERAL,
+						USB_BAM_DEVICE, bam_pipe_num);
+		}
+		if (dst_connection_idx < 0 || src_connection_idx < 0) {
+			pr_err("%s: usb_bam_get_connection_idx failed\n",
+				__func__);
+			gqti_ctrl_disconnect(&dev->port, dev->qti_port_type);
+			return -EINVAL;
+		}
+		ret = ipa_data_connect(&dev->bam_port, dev->ipa_func_type,
+				src_connection_idx, dst_connection_idx);
+		if (ret)
+			pr_err("%s: ipa_data_connect failed: err:%d\n",
+				__func__, ret);
 	}
-	if (dev->ipa_port.out) {
-		src_connection_idx = usb_bam_get_connection_idx(usb_bam_type,
-			IPA_P_BAM, USB_TO_PEER_PERIPHERAL,
-			USB_BAM_DEVICE, bam_pipe_num);
-	}
-	if (dst_connection_idx < 0 || src_connection_idx < 0) {
-		pr_err("%s: usb_bam_get_connection_idx failed\n",
-			__func__);
-		gqti_ctrl_disconnect(&dev->port, dev->qti_port_type);
-		return -EINVAL;
-	}
-	ret = ipa_data_connect(&dev->ipa_port, dev->func_type,
-			src_connection_idx, dst_connection_idx);
+
 	if (ret) {
-		pr_err("%s: ipa_data_connect failed: err:%d\n",
-			__func__, ret);
 		gqti_ctrl_disconnect(&dev->port, dev->qti_port_type);
 		return ret;
 	}
@@ -422,7 +446,11 @@
 static int gport_rmnet_disconnect(struct f_rmnet *dev)
 {
 	gqti_ctrl_disconnect(&dev->port, dev->qti_port_type);
-	ipa_data_disconnect(&dev->ipa_port, dev->func_type);
+	if (dev->xport_type == BAM_DMUX)
+		gbam_disconnect(&dev->bam_port, dev->bam_dmux_func_type);
+	else
+		ipa_data_disconnect(&dev->bam_port, dev->ipa_func_type);
+
 	return 0;
 }
 
@@ -488,7 +516,10 @@
 		usb_ep_fifo_flush(dev->notify);
 		frmnet_purge_responses(dev);
 	}
-	ipa_data_suspend(&dev->ipa_port, dev->func_type, remote_wakeup_allowed);
+
+	if (dev->xport_type == BAM2BAM_IPA)
+		ipa_data_suspend(&dev->bam_port, dev->ipa_func_type,
+							remote_wakeup_allowed);
 }
 
 static void frmnet_resume(struct usb_function *f)
@@ -503,8 +534,9 @@
 
 	pr_debug("%s: dev: %pK remote_wakeup: %d\n", __func__, dev,
 			remote_wakeup_allowed);
-
-	ipa_data_resume(&dev->ipa_port, dev->func_type, remote_wakeup_allowed);
+	if (dev->xport_type == BAM2BAM_IPA)
+		ipa_data_resume(&dev->bam_port, dev->ipa_func_type,
+							remote_wakeup_allowed);
 }
 
 static void frmnet_disable(struct usb_function *f)
@@ -557,20 +589,20 @@
 		dev->notify->driver_data = dev;
 	}
 
-	if (dev->ipa_port.in && !dev->ipa_port.in->desc
-		&& config_ep_by_speed(cdev->gadget, f, dev->ipa_port.in)) {
+	if (dev->bam_port.in && !dev->bam_port.in->desc
+		&& config_ep_by_speed(cdev->gadget, f, dev->bam_port.in)) {
 		pr_err("%s(): config_ep_by_speed failed.\n",
 				__func__);
-		dev->ipa_port.in->desc = NULL;
+		dev->bam_port.in->desc = NULL;
 		ret = -EINVAL;
 		goto err_disable_ep;
 	}
 
-	if (dev->ipa_port.out && !dev->ipa_port.out->desc
-		&& config_ep_by_speed(cdev->gadget, f, dev->ipa_port.out)) {
+	if (dev->bam_port.out && !dev->bam_port.out->desc
+		&& config_ep_by_speed(cdev->gadget, f, dev->bam_port.out)) {
 		pr_err("%s(): config_ep_by_speed failed.\n",
 				__func__);
-		dev->ipa_port.out->desc = NULL;
+		dev->bam_port.out->desc = NULL;
 		ret = -EINVAL;
 		goto err_disable_ep;
 	}
@@ -954,7 +986,7 @@
 					__func__);
 			return -ENODEV;
 		}
-		dev->ipa_port.in = ep;
+		dev->bam_port.in = ep;
 		ep->driver_data = cdev;
 	}
 
@@ -966,7 +998,7 @@
 			status = -ENODEV;
 			goto ep_auto_out_fail;
 		}
-		dev->ipa_port.out = ep;
+		dev->bam_port.out = ep;
 		ep->driver_data = cdev;
 	}
 
@@ -1058,11 +1090,11 @@
 		dev->notify->driver_data = NULL;
 		dev->notify = NULL;
 ep_auto_notify_fail:
-		dev->ipa_port.out->driver_data = NULL;
-		dev->ipa_port.out = NULL;
+		dev->bam_port.out->driver_data = NULL;
+		dev->bam_port.out = NULL;
 ep_auto_out_fail:
-		dev->ipa_port.in->driver_data = NULL;
-		dev->ipa_port.in = NULL;
+		dev->bam_port.in->driver_data = NULL;
+		dev->bam_port.in = NULL;
 
 	return status;
 }
@@ -1163,7 +1195,11 @@
 {
 	struct f_rmnet_opts *opts = container_of(f, struct f_rmnet_opts,
 						func_inst);
-	ipa_data_free(opts->dev->func_type);
+	if (opts->dev->xport_type == BAM_DMUX)
+		gbam_cleanup(opts->dev->bam_dmux_func_type);
+	else
+		ipa_data_free(opts->dev->ipa_func_type);
+
 	kfree(opts->dev);
 	kfree(opts);
 }
@@ -1194,14 +1230,20 @@
 	}
 
 	if (dev->qti_port_type >= QTI_NUM_PORTS ||
-		dev->func_type >= USB_IPA_NUM_FUNCS) {
+		dev->xport_type >= NR_XPORT_TYPES ||
+		dev->ipa_func_type >= USB_IPA_NUM_FUNCS ||
+		dev->bam_dmux_func_type >= BAM_DMUX_NUM_FUNCS) {
 		pr_err("%s: invalid prot\n", __func__);
 		ret = -EINVAL;
 		goto fail;
 	}
 
 	INIT_LIST_HEAD(&dev->cpkt_resp_q);
-	ret = ipa_data_setup(dev->func_type);
+	if (dev->xport_type == BAM_DMUX)
+		ret = gbam_setup(dev->bam_dmux_func_type);
+	else
+		ret = ipa_data_setup(dev->ipa_func_type);
+
 	if (ret)
 		goto fail;
 
diff --git a/drivers/usb/gadget/function/u_bam_dmux.c b/drivers/usb/gadget/function/u_bam_dmux.c
index 2ad184a..78dfe7b 100644
--- a/drivers/usb/gadget/function/u_bam_dmux.c
+++ b/drivers/usb/gadget/function/u_bam_dmux.c
@@ -21,6 +21,7 @@
 #include <linux/debugfs.h>
 #include <linux/bitops.h>
 #include <linux/termios.h>
+#include <linux/platform_device.h>
 
 #include <soc/qcom/bam_dmux.h>
 
@@ -28,32 +29,18 @@
 #include <linux/usb/usb_ctrl_qti.h>
 #include <linux/usb_bam.h>
 
-#include "usb_gadget_xport.h"
 #include "u_rmnet.h"
 
-#define BAM_N_PORTS	 2
-#define BAM2BAM_N_PORTS	 4
-
 static struct workqueue_struct *gbam_wq;
-static int n_bam_ports;
-static int n_bam2bam_ports;
 static unsigned int n_tx_req_queued;
 
-static unsigned int bam_ch_ids[BAM_N_PORTS] = {
+static unsigned int bam_ch_ids[BAM_DMUX_NUM_FUNCS] = {
+	BAM_DMUX_USB_RMNET_0,
 	BAM_DMUX_USB_RMNET_0,
 	BAM_DMUX_USB_DPL
 };
 
-static char bam_ch_names[BAM_N_PORTS][BAM_DMUX_CH_NAME_MAX_LEN];
-
-static const enum ipa_client_type usb_prod[BAM2BAM_N_PORTS] = {
-	IPA_CLIENT_USB_PROD, IPA_CLIENT_USB2_PROD,
-	IPA_CLIENT_USB3_PROD, IPA_CLIENT_USB4_PROD
-};
-static const enum ipa_client_type usb_cons[BAM2BAM_N_PORTS] = {
-	IPA_CLIENT_USB_CONS, IPA_CLIENT_USB2_CONS,
-	IPA_CLIENT_USB3_CONS, IPA_CLIENT_USB4_CONS
-};
+static char bam_ch_names[BAM_DMUX_NUM_FUNCS][BAM_DMUX_CH_NAME_MAX_LEN];
 
 #define BAM_PENDING_PKTS_LIMIT			220
 #define BAM_MUX_TX_PKT_DROP_THRESHOLD		1000
@@ -119,11 +106,6 @@
 	U_BAM_RESUME_E
 };
 
-struct sys2ipa_sw {
-	void		*teth_priv;
-	ipa_notify_cb	teth_cb;
-};
-
 struct bam_ch_info {
 	unsigned long		flags;
 	unsigned int		id;
@@ -141,22 +123,6 @@
 
 	struct usb_request	*rx_req;
 	struct usb_request	*tx_req;
-	bool			tx_req_dequeued;
-	bool			rx_req_dequeued;
-
-	u32			src_pipe_idx;
-	u32			dst_pipe_idx;
-	u8			src_connection_idx;
-	u8			dst_connection_idx;
-	enum usb_ctrl		usb_bam_type;
-
-	enum transport_type trans;
-	struct usb_bam_connect_ipa_params ipa_params;
-
-	/* added to support sys to ipa sw UL path */
-	struct sys2ipa_sw	ul_params;
-	enum usb_bam_pipe_type	src_pipe_type;
-	enum usb_bam_pipe_type	dst_pipe_type;
 
 	/* stats */
 	unsigned int		pending_pkts_with_bam;
@@ -184,21 +150,19 @@
 	spinlock_t		port_lock_dl;
 	spinlock_t		port_lock;
 
-	struct grmnet		*port_usb;
+	struct data_port	*port_usb;
 	struct usb_gadget	*gadget;
 
 	struct bam_ch_info	data_ch;
 
 	struct work_struct	connect_w;
 	struct work_struct	disconnect_w;
-	struct work_struct	suspend_w;
-	struct work_struct	resume_w;
 };
 
 static struct bam_portmaster {
 	struct gbam_port *port;
 	struct platform_driver pdrv;
-} bam_ports[BAM_N_PORTS];
+} bam_ports[BAM_DMUX_NUM_FUNCS];
 
 struct  u_bam_data_connect_info {
 	u32 usb_bam_pipe_idx;
@@ -206,10 +170,7 @@
 	unsigned long usb_bam_handle;
 };
 
-struct gbam_port *bam2bam_ports[BAM2BAM_N_PORTS];
 static void gbam_start_rx(struct gbam_port *port);
-static void gbam_start_endless_rx(struct gbam_port *port);
-static void gbam_start_endless_tx(struct gbam_port *port);
 static void gbam_notify(void *p, int event, unsigned long data);
 static void gbam_data_write_tobam(struct work_struct *w);
 
@@ -260,7 +221,6 @@
 	struct bam_ch_info *d;
 	struct sk_buff *skb;
 	dma_addr_t      skb_buf_dma_addr;
-	struct usb_gadget *gadget;
 
 	if (!port)
 		return NULL;
@@ -283,24 +243,7 @@
 			goto alloc_exit;
 
 		skb_reserve(skb, BAM_MUX_HDR);
-
-		if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
-
-			gadget = port->port_usb->gadget;
-
-			skb_buf_dma_addr =
-				dma_map_single(&gadget->dev, skb->data,
-					bam_mux_rx_req_size, DMA_BIDIRECTIONAL);
-
-			if (dma_mapping_error(&gadget->dev, skb_buf_dma_addr)) {
-				pr_err("%s: Could not DMA map SKB buffer\n",
-					__func__);
-				skb_buf_dma_addr = DMA_ERROR_CODE;
-			}
-		} else {
-			skb_buf_dma_addr = DMA_ERROR_CODE;
-		}
-
+		skb_buf_dma_addr = DMA_ERROR_CODE;
 
 		memcpy(skb->cb, &skb_buf_dma_addr,
 			sizeof(skb_buf_dma_addr));
@@ -308,6 +251,9 @@
 	} else {
 		pr_debug("%s: pull skb from pool\n", __func__);
 		skb = __skb_dequeue(&d->rx_skb_idle);
+		if (!skb)
+			goto alloc_exit;
+
 		if (skb_headroom(skb) < BAM_MUX_HDR)
 			skb_reserve(skb, BAM_MUX_HDR);
 	}
@@ -341,10 +287,13 @@
 		return;
 	d = &port->data_ch;
 
-	gadget = port->port_usb->gadget;
+	gadget = port->port_usb->cdev->gadget;
 
 	while (d->rx_skb_idle.qlen > 0) {
 		skb = __skb_dequeue(&d->rx_skb_idle);
+		if (!skb)
+			break;
+
 		dma_addr = gbam_get_dma_from_skb(skb);
 
 		if (gadget && dma_addr != DMA_ERROR_CODE) {
@@ -359,36 +308,6 @@
 	}
 }
 
-/*----- sys2bam towards the IPA --------------- */
-static void gbam_ipa_sys2bam_notify_cb(void *priv, enum ipa_dp_evt_type event,
-		unsigned long data)
-{
-	struct sys2ipa_sw	*ul = (struct sys2ipa_sw *)priv;
-	struct gbam_port	*port;
-	struct bam_ch_info	*d;
-
-	switch (event) {
-	case IPA_WRITE_DONE:
-		d = container_of(ul, struct bam_ch_info, ul_params);
-		port = container_of(d, struct gbam_port, data_ch);
-		/* call into bam_demux functionality that'll recycle the data */
-		gbam_notify(port, BAM_DMUX_WRITE_DONE, data);
-		break;
-	case IPA_RECEIVE:
-		/* call the callback given by tethering driver init function
-		 * (and was given to ipa_connect)
-		 */
-		if (ul->teth_cb)
-			ul->teth_cb(ul->teth_priv, event, data);
-		break;
-	default:
-		/* unexpected event */
-		pr_err("%s: unexpected event %d\n", __func__, event);
-		break;
-	}
-}
-
-
 /*--------------------------------------------- */
 
 /*------------data_path----------------------------*/
@@ -485,7 +404,7 @@
 	gbam_write_data_tohost(port);
 }
 
-void gbam_data_recv_cb(void *p, struct sk_buff *skb)
+static void gbam_data_recv_cb(void *p, struct sk_buff *skb)
 {
 	struct gbam_port	*port = p;
 	struct bam_ch_info	*d = &port->data_ch;
@@ -506,8 +425,7 @@
 
 	if (d->tx_skb_q.qlen > bam_mux_tx_pkt_drop_thld) {
 		d->tohost_drp_cnt++;
-		if (printk_ratelimited())
-			pr_err("%s: tx pkt dropped: tx_drop_cnt:%u\n",
+		printk_ratelimited(KERN_ERR "%s: tx pkt dropped: tx_drop_cnt:%u\n",
 					__func__, d->tohost_drp_cnt);
 		spin_unlock_irqrestore(&port->port_lock_dl, flags);
 		dev_kfree_skb_any(skb);
@@ -520,7 +438,7 @@
 	gbam_write_data_tohost(port);
 }
 
-void gbam_data_write_done(void *p, struct sk_buff *skb)
+static void gbam_data_write_done(void *p, struct sk_buff *skb)
 {
 	struct gbam_port	*port = p;
 	struct bam_ch_info	*d = &port->data_ch;
@@ -599,10 +517,7 @@
 
 	set_bit(BAM_CH_WRITE_INPROGRESS, &d->flags);
 
-	while (!gbam_ul_bam_limit_reached(d) &&
-			(d->trans != USB_GADGET_XPORT_BAM2BAM_IPA ||
-			usb_bam_get_prod_granted(d->usb_bam_type,
-					d->dst_connection_idx))) {
+	while (!gbam_ul_bam_limit_reached(d)) {
 		skb =  __skb_dequeue(&d->rx_skb_q);
 		if (!skb)
 			break;
@@ -617,23 +532,7 @@
 				d->pending_bytes_with_bam, port->port_num);
 
 		spin_unlock_irqrestore(&port->port_lock_ul, flags);
-		if (d->src_pipe_type == USB_BAM_PIPE_SYS2BAM) {
-			dma_addr_t         skb_dma_addr;
-			struct ipa_tx_meta ipa_meta = {0x0};
-
-			skb_dma_addr = gbam_get_dma_from_skb(skb);
-			if (skb_dma_addr != DMA_ERROR_CODE) {
-				ipa_meta.dma_address = skb_dma_addr;
-				ipa_meta.dma_address_valid = true;
-			}
-
-			ret = ipa_tx_dp(usb_prod[port->port_num],
-				skb,
-				&ipa_meta);
-		} else {
-			ret = msm_bam_dmux_write(d->id, skb);
-		}
-
+		ret = msm_bam_dmux_write(d->id, skb);
 		spin_lock_irqsave(&port->port_lock_ul, flags);
 		if (ret) {
 			pr_debug("%s: write error:%d\n", __func__, ret);
@@ -723,14 +622,12 @@
 		spin_lock(&port->port_lock_ul);
 		gbam_free_skb_to_pool(port, skb);
 		spin_unlock(&port->port_lock_ul);
-		req->buf = 0;
+		req->buf = NULL;
 		usb_ep_free_request(ep, req);
 		return;
 	default:
-		if (printk_ratelimited())
-			pr_err("%s: %s response error %d, %d/%d\n",
-				__func__, ep->name, status,
-				req->actual, req->length);
+		printk_ratelimited(KERN_ERR "%s: %s response error %d, %d/%d\n",
+			__func__, ep->name, status, req->actual, req->length);
 		spin_lock(&port->port_lock_ul);
 		gbam_free_skb_to_pool(port, skb);
 		spin_unlock(&port->port_lock_ul);
@@ -741,14 +638,6 @@
 
 	if (queue) {
 		__skb_queue_tail(&d->rx_skb_q, skb);
-		if ((d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) &&
-			!usb_bam_get_prod_granted(d->usb_bam_type,
-					d->dst_connection_idx)) {
-			list_add_tail(&req->list, &d->rx_idle);
-			spin_unlock(&port->port_lock_ul);
-			return;
-		}
-
 		queue_work(gbam_wq, &d->write_tobam_w);
 	}
 
@@ -778,11 +667,6 @@
 	req->dma = gbam_get_dma_from_skb(skb);
 	req->length = bam_mux_rx_req_size;
 
-	if (req->dma != DMA_ERROR_CODE)
-		req->dma_pre_mapped = true;
-	else
-		req->dma_pre_mapped = false;
-
 	req->context = skb;
 
 	status = usb_ep_queue(ep, req, GFP_ATOMIC);
@@ -791,8 +675,7 @@
 		gbam_free_skb_to_pool(port, skb);
 		spin_unlock(&port->port_lock_ul);
 
-		if (printk_ratelimited())
-			pr_err("%s: data rx enqueue err %d\n",
+		printk_ratelimited(KERN_ERR "%s: data rx enqueue err %d\n",
 					__func__, status);
 
 		spin_lock(&port->port_lock_ul);
@@ -801,20 +684,6 @@
 	}
 }
 
-static void gbam_endless_rx_complete(struct usb_ep *ep, struct usb_request *req)
-{
-	int status = req->status;
-
-	pr_debug("%s status: %d\n", __func__, status);
-}
-
-static void gbam_endless_tx_complete(struct usb_ep *ep, struct usb_request *req)
-{
-	int status = req->status;
-
-	pr_debug("%s status: %d\n", __func__, status);
-}
-
 static void gbam_start_rx(struct gbam_port *port)
 {
 	struct usb_request		*req;
@@ -850,11 +719,6 @@
 		req->dma = gbam_get_dma_from_skb(skb);
 		req->length = bam_mux_rx_req_size;
 
-		if (req->dma != DMA_ERROR_CODE)
-			req->dma_pre_mapped = true;
-		else
-			req->dma_pre_mapped = false;
-
 		req->context = skb;
 
 		spin_unlock_irqrestore(&port->port_lock_ul, flags);
@@ -863,8 +727,7 @@
 		if (ret) {
 			gbam_free_skb_to_pool(port, skb);
 
-			if (printk_ratelimited())
-				pr_err("%s: rx queue failed %d\n",
+			printk_ratelimited(KERN_ERR "%s: rx queue failed %d\n",
 							__func__, ret);
 
 			if (port->port_usb)
@@ -878,182 +741,6 @@
 	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 }
 
-static void gbam_start_endless_rx(struct gbam_port *port)
-{
-	struct bam_ch_info *d = &port->data_ch;
-	int status;
-	struct usb_ep *ep;
-	unsigned long flags;
-
-	spin_lock_irqsave(&port->port_lock_ul, flags);
-	if (!port->port_usb || !d->rx_req) {
-		spin_unlock_irqrestore(&port->port_lock_ul, flags);
-		pr_err("%s: port->port_usb is NULL", __func__);
-		return;
-	}
-
-	ep = port->port_usb->out;
-	spin_unlock_irqrestore(&port->port_lock_ul, flags);
-	pr_debug("%s: enqueue\n", __func__);
-	status = usb_ep_queue(ep, d->rx_req, GFP_ATOMIC);
-	if (status)
-		pr_err("%s: error enqueuing transfer, %d\n", __func__, status);
-}
-
-static void gbam_start_endless_tx(struct gbam_port *port)
-{
-	struct bam_ch_info *d = &port->data_ch;
-	int status;
-	struct usb_ep *ep;
-	unsigned long flags;
-
-	spin_lock_irqsave(&port->port_lock_dl, flags);
-	if (!port->port_usb || !d->tx_req) {
-		spin_unlock_irqrestore(&port->port_lock_dl, flags);
-		pr_err("%s: port->port_usb is NULL", __func__);
-		return;
-	}
-
-	ep = port->port_usb->in;
-	spin_unlock_irqrestore(&port->port_lock_dl, flags);
-	pr_debug("%s: enqueue\n", __func__);
-	status = usb_ep_queue(ep, d->tx_req, GFP_ATOMIC);
-	if (status)
-		pr_err("%s: error enqueuing transfer, %d\n", __func__, status);
-}
-
-static void gbam_stop_endless_rx(struct gbam_port *port)
-{
-	struct bam_ch_info *d = &port->data_ch;
-	int status;
-	unsigned long flags;
-	struct usb_ep *ep;
-
-	spin_lock_irqsave(&port->port_lock_ul, flags);
-	if (!port->port_usb) {
-		spin_unlock_irqrestore(&port->port_lock_ul, flags);
-		pr_err("%s: port->port_usb is NULL", __func__);
-		return;
-	}
-
-	ep = port->port_usb->out;
-	d->rx_req_dequeued = true;
-	spin_unlock_irqrestore(&port->port_lock_ul, flags);
-	pr_debug("%s: dequeue\n", __func__);
-	status = usb_ep_dequeue(ep, d->rx_req);
-	if (status)
-		pr_err("%s: error dequeuing transfer, %d\n", __func__, status);
-}
-
-static void gbam_stop_endless_tx(struct gbam_port *port)
-{
-	struct bam_ch_info *d = &port->data_ch;
-	int status;
-	unsigned long flags;
-	struct usb_ep *ep;
-
-	spin_lock_irqsave(&port->port_lock_dl, flags);
-	if (!port->port_usb) {
-		spin_unlock_irqrestore(&port->port_lock_dl, flags);
-		pr_err("%s: port->port_usb is NULL", __func__);
-		return;
-	}
-
-	ep = port->port_usb->in;
-	d->tx_req_dequeued = true;
-	spin_unlock_irqrestore(&port->port_lock_dl, flags);
-	pr_debug("%s: dequeue\n", __func__);
-	status = usb_ep_dequeue(ep, d->tx_req);
-	if (status)
-		pr_err("%s: error dequeuing transfer, %d\n", __func__, status);
-}
-
-
-/*
- * This function configured data fifo based on index passed to get bam2bam
- * configuration.
- */
-static void configure_data_fifo(enum usb_ctrl bam_type, 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(bam_type, idx,
-				&bam_info.usb_bam_pipe_idx,
-				NULL, &data_fifo, NULL);
-
-		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 usb_gadget *gadget = NULL;
-	struct bam_ch_info *d;
-	unsigned long flags;
-
-	if (port == NULL) {
-		pr_err("%s: port is NULL\n", __func__);
-		return;
-	}
-
-	spin_lock_irqsave(&port->port_lock, flags);
-	if (port->port_usb == NULL) {
-		pr_err("%s: port_usb is NULL, disconnected\n", __func__);
-		spin_unlock_irqrestore(&port->port_lock, flags);
-		return;
-	}
-
-	gadget = port->port_usb->gadget;
-	d = &port->data_ch;
-	spin_unlock_irqrestore(&port->port_lock, flags);
-
-	if (gadget == NULL) {
-		pr_err("%s: gadget is NULL\n", __func__);
-		return;
-	}
-
-	if (dir == USB_TO_PEER_PERIPHERAL) {
-		if (port->data_ch.src_pipe_type == USB_BAM_PIPE_BAM2BAM)
-			gbam_start_endless_rx(port);
-		else {
-			gbam_start_rx(port);
-			queue_work(gbam_wq, &d->write_tobam_w);
-		}
-	} else {
-		if (gadget_is_dwc3(gadget) &&
-		    msm_dwc3_reset_ep_after_lpm(gadget)) {
-			configure_data_fifo(d->usb_bam_type,
-				d->dst_connection_idx,
-				port->port_usb->in, d->dst_pipe_type);
-		}
-		gbam_start_endless_tx(port);
-	}
-}
-
-static void gbam_stop(void *param, enum usb_bam_pipe_dir dir)
-{
-	struct gbam_port *port = param;
-
-	if (dir == USB_TO_PEER_PERIPHERAL) {
-		/*
-		 * Only handling BAM2BAM, as there is no equivalent to
-		 * gbam_stop_endless_rx() for the SYS2BAM use case
-		 */
-		if (port->data_ch.src_pipe_type == USB_BAM_PIPE_BAM2BAM)
-			gbam_stop_endless_rx(port);
-	} else {
-		gbam_stop_endless_tx(port);
-	}
-}
-
 static int _gbam_start_io(struct gbam_port *port, bool in)
 {
 	unsigned long		flags;
@@ -1222,52 +909,6 @@
 	return;
 }
 
-static void gbam2bam_disconnect_work(struct work_struct *w)
-{
-	struct gbam_port *port =
-			container_of(w, struct gbam_port, disconnect_w);
-	struct bam_ch_info *d;
-	int ret;
-	unsigned long flags;
-
-	spin_lock_irqsave(&port->port_lock, flags);
-
-	if (!port->is_connected) {
-		pr_debug("%s: Port already disconnected. Bailing out.\n",
-			__func__);
-		spin_unlock_irqrestore(&port->port_lock, flags);
-		return;
-	}
-
-	port->is_connected = false;
-	d = &port->data_ch;
-
-	/*
-	 * Unlock the port here and not at the end of this work,
-	 * because we do not want to activate usb_bam, ipa and
-	 * tethe bridge logic in atomic context and wait uneeded time.
-	 * Either way other works will not fire until end of this work
-	 * and event functions (as bam_data_connect) will not influance
-	 * while lower layers connect pipes, etc.
-	 */
-	spin_unlock_irqrestore(&port->port_lock, flags);
-
-	if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
-		ret = usb_bam_disconnect_ipa(d->usb_bam_type, &d->ipa_params);
-		if (ret)
-			pr_err("%s: usb_bam_disconnect_ipa failed: err:%d\n",
-				__func__, ret);
-		usb_bam_free_fifos(d->usb_bam_type, d->src_connection_idx);
-		usb_bam_free_fifos(d->usb_bam_type, d->dst_connection_idx);
-		teth_bridge_disconnect(d->ipa_params.src_client);
-		/*
-		 * Decrement usage count which was incremented upon cable
-		 * connect or cable disconnect in suspended state
-		 */
-		usb_gadget_autopm_put_async(port->gadget);
-	}
-}
-
 static void gbam_connect_work(struct work_struct *w)
 {
 	struct gbam_port *port = container_of(w, struct gbam_port, connect_w);
@@ -1304,425 +945,6 @@
 	pr_debug("%s: done\n", __func__);
 }
 
-static void gbam2bam_connect_work(struct work_struct *w)
-{
-	struct gbam_port *port = container_of(w, struct gbam_port, connect_w);
-	struct usb_gadget *gadget = NULL;
-	struct teth_bridge_connect_params connect_params;
-	struct teth_bridge_init_params teth_bridge_params;
-	struct bam_ch_info *d;
-	u32 sps_params;
-	int ret;
-	unsigned long flags, flags_ul;
-
-	spin_lock_irqsave(&port->port_lock, flags);
-
-	if (port->last_event == U_BAM_DISCONNECT_E) {
-		pr_debug("%s: Port is about to disconnected. Bailing out.\n",
-			__func__);
-		spin_unlock_irqrestore(&port->port_lock, flags);
-		return;
-	}
-
-	if (port->is_connected) {
-		pr_debug("%s: Port already connected. Bail out.\n",
-			__func__);
-		spin_unlock_irqrestore(&port->port_lock, flags);
-		return;
-	}
-	port->is_connected = true;
-
-	spin_lock_irqsave(&port->port_lock_ul, flags_ul);
-	spin_lock(&port->port_lock_dl);
-	if (!port->port_usb) {
-		pr_debug("%s: usb cable is disconnected, exiting\n", __func__);
-		spin_unlock(&port->port_lock_dl);
-		spin_unlock_irqrestore(&port->port_lock_ul, flags_ul);
-		spin_unlock_irqrestore(&port->port_lock, flags);
-		return;
-	}
-
-	gadget = port->port_usb->gadget;
-	if (!gadget) {
-		spin_unlock(&port->port_lock_dl);
-		spin_unlock_irqrestore(&port->port_lock_ul, flags_ul);
-		spin_unlock_irqrestore(&port->port_lock, flags);
-		pr_err("%s: port_usb.gadget is NULL, exiting\n", __func__);
-		return;
-	}
-	d = &port->data_ch;
-
-	/*
-	 * Unlock the port here and not at the end of this work,
-	 * because we do not want to activate usb_bam, ipa and
-	 * tethe bridge logic in atomic context and wait uneeded time.
-	 * Either way other works will not fire until end of this work
-	 * and event functions (as bam_data_connect) will not influance
-	 * while lower layers connect pipes, etc.
-	 */
-	spin_unlock(&port->port_lock_dl);
-	spin_unlock_irqrestore(&port->port_lock_ul, flags_ul);
-
-	d->ipa_params.usb_connection_speed = gadget->speed;
-
-	/*
-	 * Invalidate prod and cons client handles from previous
-	 * disconnect.
-	 */
-	d->ipa_params.cons_clnt_hdl = -1;
-	d->ipa_params.prod_clnt_hdl = -1;
-
-	if (usb_bam_get_pipe_type(d->usb_bam_type, d->ipa_params.src_idx,
-			&d->src_pipe_type) ||
-		usb_bam_get_pipe_type(d->usb_bam_type, d->ipa_params.dst_idx,
-				&d->dst_pipe_type)) {
-		spin_unlock_irqrestore(&port->port_lock, flags);
-		pr_err("%s:usb_bam_get_pipe_type() failed\n", __func__);
-		return;
-	}
-	if (d->dst_pipe_type != USB_BAM_PIPE_BAM2BAM) {
-		spin_unlock_irqrestore(&port->port_lock, flags);
-		pr_err("%s: no software preparation for DL not using bam2bam\n",
-				__func__);
-		return;
-	}
-
-	spin_unlock_irqrestore(&port->port_lock, flags);
-	usb_bam_alloc_fifos(d->usb_bam_type, d->src_connection_idx);
-	usb_bam_alloc_fifos(d->usb_bam_type, d->dst_connection_idx);
-
-	spin_lock_irqsave(&port->port_lock, flags);
-	/* check if USB cable is disconnected or not */
-	if (!port || !port->port_usb) {
-		pr_debug("%s: cable is disconnected.\n",
-						 __func__);
-		spin_unlock_irqrestore(&port->port_lock,
-							flags);
-		goto free_fifos;
-	}
-	if (gadget_is_dwc3(gadget)) {
-		/* Configure for RX */
-		configure_data_fifo(d->usb_bam_type, d->src_connection_idx,
-				    port->port_usb->out, d->src_pipe_type);
-		sps_params = MSM_SPS_MODE | MSM_DISABLE_WB | MSM_PRODUCER |
-								d->src_pipe_idx;
-		d->rx_req->length = 32*1024;
-		d->rx_req->udc_priv = sps_params;
-		msm_ep_config(port->port_usb->out, d->rx_req);
-
-		/* Configure for TX */
-		configure_data_fifo(d->usb_bam_type, d->dst_connection_idx,
-				    port->port_usb->in, d->dst_pipe_type);
-		sps_params = MSM_SPS_MODE | MSM_DISABLE_WB | d->dst_pipe_idx;
-		d->tx_req->length = 32*1024;
-		d->tx_req->udc_priv = sps_params;
-		msm_ep_config(port->port_usb->in, d->tx_req);
-
-	} else {
-		/* Configure for RX */
-		get_bam2bam_connection_info(d->usb_bam_type,
-				d->src_connection_idx,
-				&d->src_pipe_idx,
-				NULL, NULL, NULL);
-		sps_params = (MSM_SPS_MODE | d->src_pipe_idx |
-				MSM_VENDOR_ID) & ~MSM_IS_FINITE_TRANSFER;
-		d->rx_req->udc_priv = sps_params;
-
-		/* Configure for TX */
-		get_bam2bam_connection_info(d->usb_bam_type,
-				d->dst_connection_idx,
-				&d->dst_pipe_idx,
-				NULL, NULL, NULL);
-		sps_params = (MSM_SPS_MODE | d->dst_pipe_idx |
-				MSM_VENDOR_ID) & ~MSM_IS_FINITE_TRANSFER;
-		d->tx_req->udc_priv = sps_params;
-
-	}
-
-	teth_bridge_params.client = d->ipa_params.src_client;
-	ret = teth_bridge_init(&teth_bridge_params);
-	if (ret) {
-		spin_unlock_irqrestore(&port->port_lock, flags);
-		pr_err("%s:teth_bridge_init() failed\n", __func__);
-		goto ep_unconfig;
-	}
-
-	/* Support for UL using system-to-IPA */
-	if (d->src_pipe_type == USB_BAM_PIPE_SYS2BAM) {
-		d->ul_params.teth_priv =
-			teth_bridge_params.private_data;
-		d->ul_params.teth_cb =
-			teth_bridge_params.usb_notify_cb;
-		d->ipa_params.notify = gbam_ipa_sys2bam_notify_cb;
-		d->ipa_params.priv = &d->ul_params;
-		d->ipa_params.reset_pipe_after_lpm = false;
-
-	} else {
-		d->ipa_params.notify =
-			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;
-	d->ipa_params.dir = USB_TO_PEER_PERIPHERAL;
-	spin_unlock_irqrestore(&port->port_lock, flags);
-	ret = usb_bam_connect_ipa(d->usb_bam_type, &d->ipa_params);
-	if (ret) {
-		pr_err("%s: usb_bam_connect_ipa failed: err:%d\n",
-			__func__, ret);
-		goto ep_unconfig;
-	}
-
-	spin_lock_irqsave(&port->port_lock, flags);
-	/* check if USB cable is disconnected or not */
-	if (port->last_event ==  U_BAM_DISCONNECT_E) {
-		spin_unlock_irqrestore(&port->port_lock, flags);
-		pr_debug("%s:%d: cable is disconnected.\n",
-						 __func__, __LINE__);
-		goto ep_unconfig;
-	}
-
-	/* Remove support for UL using system-to-IPA towards DL */
-	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;
-	}
-	if (d->dst_pipe_type == USB_BAM_PIPE_BAM2BAM)
-		d->ipa_params.reset_pipe_after_lpm =
-			(gadget_is_dwc3(gadget) &&
-			 msm_dwc3_reset_ep_after_lpm(gadget));
-	else
-		d->ipa_params.reset_pipe_after_lpm = false;
-	d->ipa_params.dir = PEER_PERIPHERAL_TO_USB;
-	spin_unlock_irqrestore(&port->port_lock, flags);
-	ret = usb_bam_connect_ipa(d->usb_bam_type, &d->ipa_params);
-	if (ret) {
-		pr_err("%s: usb_bam_connect_ipa failed: err:%d\n",
-			__func__, ret);
-		goto ep_unconfig;
-	}
-
-	spin_lock_irqsave(&port->port_lock, flags);
-	/* check if USB cable is disconnected or not */
-	if (port->last_event ==  U_BAM_DISCONNECT_E) {
-		spin_unlock_irqrestore(&port->port_lock, flags);
-		pr_debug("%s:%d: cable is disconnected.\n",
-						 __func__, __LINE__);
-		goto ep_unconfig;
-	}
-
-	spin_unlock_irqrestore(&port->port_lock, flags);
-	gqti_ctrl_update_ipa_pipes(port->port_usb, port->port_num,
-					d->ipa_params.ipa_prod_ep_idx,
-					d->ipa_params.ipa_cons_ep_idx);
-
-	connect_params.ipa_usb_pipe_hdl = d->ipa_params.prod_clnt_hdl;
-	connect_params.usb_ipa_pipe_hdl = d->ipa_params.cons_clnt_hdl;
-	connect_params.tethering_mode = TETH_TETHERING_MODE_RMNET;
-	connect_params.client_type = d->ipa_params.src_client;
-	ret = teth_bridge_connect(&connect_params);
-	if (ret) {
-		pr_err("%s:teth_bridge_connect() failed\n", __func__);
-		goto ep_unconfig;
-	}
-
-	/* queue in & out requests */
-	if (d->src_pipe_type == USB_BAM_PIPE_BAM2BAM) {
-		gbam_start_endless_rx(port);
-	} else {
-		/* The use-case of UL (OUT) ports using sys2bam is based on
-		 * partial reuse of the system-to-bam_demux code. The following
-		 * lines perform the branching out of the standard bam2bam flow
-		 * on the USB side of the UL channel
-		 */
-		if (_gbam_start_io(port, false)) {
-			pr_err("%s: _gbam_start_io failed\n", __func__);
-			return;
-		}
-		gbam_start_rx(port);
-	}
-	gbam_start_endless_tx(port);
-
-	pr_debug("%s: done\n", __func__);
-	return;
-
-ep_unconfig:
-	if (gadget_is_dwc3(gadget)) {
-		spin_lock_irqsave(&port->port_lock, flags);
-		/* check if USB cable is disconnected or not */
-		if (port->port_usb) {
-			msm_ep_unconfig(port->port_usb->in);
-			msm_ep_unconfig(port->port_usb->out);
-		}
-		spin_unlock_irqrestore(&port->port_lock, flags);
-	}
-free_fifos:
-	usb_bam_free_fifos(d->usb_bam_type, d->src_connection_idx);
-	usb_bam_free_fifos(d->usb_bam_type, d->dst_connection_idx);
-
-}
-
-static int gbam_wake_cb(void *param)
-{
-	struct gbam_port	*port = (struct gbam_port *)param;
-	struct usb_gadget	*gadget;
-	unsigned long flags;
-	struct usb_function *func;
-	int ret;
-
-	spin_lock_irqsave(&port->port_lock, flags);
-	if (!port->port_usb) {
-		pr_debug("%s: usb cable is disconnected, exiting\n",
-				__func__);
-		spin_unlock_irqrestore(&port->port_lock, flags);
-		return -ENODEV;
-	}
-
-	gadget = port->port_usb->gadget;
-	func = port->port_usb->f;
-	spin_unlock_irqrestore(&port->port_lock, flags);
-
-	pr_debug("%s: woken up by peer\n", __func__);
-
-	if ((gadget->speed == USB_SPEED_SUPER) &&
-	    (func->func_is_suspended))
-		ret = usb_func_wakeup(func);
-	else
-		ret = usb_gadget_wakeup(gadget);
-
-	if ((ret == -EBUSY) || (ret == -EAGAIN))
-		pr_debug("Remote wakeup is delayed due to LPM exit\n");
-	else if (ret)
-		pr_err("Failed to wake up the USB core. ret=%d\n", ret);
-
-	return ret;
-}
-
-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;
-	int ret;
-	unsigned long flags;
-
-	pr_debug("%s: suspend work started\n", __func__);
-
-	spin_lock_irqsave(&port->port_lock, flags);
-
-	if ((port->last_event == U_BAM_DISCONNECT_E) ||
-	    (port->last_event == U_BAM_RESUME_E)) {
-		pr_debug("%s: Port is about to disconnect/resume. Bail out\n",
-			__func__);
-		goto exit;
-	}
-
-	d = &port->data_ch;
-
-	ret = usb_bam_register_wake_cb(d->usb_bam_type, d->dst_connection_idx,
-					gbam_wake_cb, port);
-	if (ret) {
-		pr_err("%s(): Failed to register BAM wake callback.\n",
-			__func__);
-		goto exit;
-	}
-
-	if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
-		usb_bam_register_start_stop_cbs(d->usb_bam_type,
-			 d->dst_connection_idx, gbam_start, gbam_stop, port);
-
-		/*
-		 * release lock here because gbam_start() or
-		 * gbam_stop() called from usb_bam_suspend()
-		 * re-acquires port lock.
-		 */
-		spin_unlock_irqrestore(&port->port_lock, flags);
-		usb_bam_suspend(d->usb_bam_type, &d->ipa_params);
-		spin_lock_irqsave(&port->port_lock, flags);
-	}
-
-exit:
-	/*
-	 * Decrement usage count after IPA handshake is done to allow gadget
-	 * parent to go to lpm. This counter was incremented upon cable connect
-	 */
-	usb_gadget_autopm_put_async(port->gadget);
-
-	spin_unlock_irqrestore(&port->port_lock, flags);
-}
-
-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;
-	struct usb_gadget *gadget = NULL;
-	int ret;
-	unsigned long flags;
-
-	pr_debug("%s: resume work started\n", __func__);
-
-	spin_lock_irqsave(&port->port_lock, flags);
-
-	if (port->last_event == U_BAM_DISCONNECT_E || !port->port_usb) {
-		pr_debug("%s: usb cable is disconnected, exiting\n",
-			__func__);
-		goto exit;
-	}
-
-	d = &port->data_ch;
-	gadget = port->port_usb->gadget;
-
-	ret = usb_bam_register_wake_cb(d->usb_bam_type, d->dst_connection_idx,
-					NULL, NULL);
-	if (ret) {
-		pr_err("%s(): Failed to register BAM wake callback.\n",
-			__func__);
-		goto exit;
-	}
-
-	if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
-		if (gadget_is_dwc3(gadget) &&
-		    msm_dwc3_reset_ep_after_lpm(gadget)) {
-			if (d->tx_req_dequeued) {
-				msm_ep_unconfig(port->port_usb->in);
-				configure_data_fifo(d->usb_bam_type,
-					d->dst_connection_idx,
-					port->port_usb->in, d->dst_pipe_type);
-			}
-			if (d->rx_req_dequeued) {
-				msm_ep_unconfig(port->port_usb->out);
-				configure_data_fifo(d->usb_bam_type,
-					d->src_connection_idx,
-					port->port_usb->out, d->src_pipe_type);
-			}
-
-			spin_unlock_irqrestore(&port->port_lock, flags);
-			if (d->tx_req_dequeued)
-				msm_dwc3_reset_dbm_ep(port->port_usb->in);
-			if (d->rx_req_dequeued)
-				msm_dwc3_reset_dbm_ep(port->port_usb->out);
-			spin_lock_irqsave(&port->port_lock, flags);
-			if (port->port_usb) {
-				if (d->tx_req_dequeued)
-					msm_ep_config(port->port_usb->in,
-							d->tx_req);
-				if (d->rx_req_dequeued)
-					msm_ep_config(port->port_usb->out,
-							d->rx_req);
-			}
-		}
-		d->tx_req_dequeued = false;
-		d->rx_req_dequeued = false;
-		usb_bam_resume(d->usb_bam_type, &d->ipa_params);
-	}
-
-exit:
-	spin_unlock_irqrestore(&port->port_lock, flags);
-}
-
 /* BAM data channel ready, allow attempt to open */
 static int gbam_data_ch_probe(struct platform_device *pdev)
 {
@@ -1734,8 +956,11 @@
 
 	pr_debug("%s: name:%s\n", __func__, pdev->name);
 
-	for (i = 0; i < n_bam_ports; i++) {
+	for (i = 0; i < BAM_DMUX_NUM_FUNCS; i++) {
 		port = bam_ports[i].port;
+		if (!port)
+			continue;
+
 		d = &port->data_ch;
 
 		if (!strcmp(bam_ch_names[i], pdev->name)) {
@@ -1770,9 +995,12 @@
 
 	pr_debug("%s: name:%s\n", __func__, pdev->name);
 
-	for (i = 0; i < n_bam_ports; i++) {
+	for (i = 0; i < BAM_DMUX_NUM_FUNCS; i++) {
 		if (!strcmp(bam_ch_names[i], pdev->name)) {
 			port = bam_ports[i].port;
+			if (!port)
+				continue;
+
 			d = &port->data_ch;
 
 			spin_lock_irqsave(&port->port_lock_ul, flags);
@@ -1805,10 +1033,10 @@
 	return 0;
 }
 
-static void gbam_port_free(int portno)
+static void gbam_port_free(enum bam_dmux_func_type func)
 {
-	struct gbam_port *port = bam_ports[portno].port;
-	struct platform_driver *pdrv = &bam_ports[portno].pdrv;
+	struct gbam_port *port = bam_ports[func].port;
+	struct platform_driver *pdrv = &bam_ports[func].pdrv;
 
 	if (port)
 		platform_driver_unregister(pdrv);
@@ -1816,14 +1044,7 @@
 	kfree(port);
 }
 
-static void gbam2bam_port_free(int portno)
-{
-	struct gbam_port *port = bam2bam_ports[portno];
-
-	kfree(port);
-}
-
-static int gbam_port_alloc(int portno)
+static int gbam_port_alloc(enum bam_dmux_func_type func)
 {
 	struct gbam_port	*port;
 	struct bam_ch_info	*d;
@@ -1833,7 +1054,7 @@
 	if (!port)
 		return -ENOMEM;
 
-	port->port_num = portno;
+	port->port_num = func;
 
 	/* port initialization */
 	port->is_connected = false;
@@ -1853,60 +1074,20 @@
 	skb_queue_head_init(&d->tx_skb_q);
 	skb_queue_head_init(&d->rx_skb_q);
 	skb_queue_head_init(&d->rx_skb_idle);
-	d->id = bam_ch_ids[portno];
+	d->id = bam_ch_ids[func];
 
-	bam_ports[portno].port = port;
+	bam_ports[func].port = port;
 
-	scnprintf(bam_ch_names[portno], BAM_DMUX_CH_NAME_MAX_LEN,
-			"bam_dmux_ch_%d", bam_ch_ids[portno]);
-	pdrv = &bam_ports[portno].pdrv;
+	scnprintf(bam_ch_names[func], BAM_DMUX_CH_NAME_MAX_LEN,
+			"bam_dmux_ch_%d", bam_ch_ids[func]);
+	pdrv = &bam_ports[func].pdrv;
 	pdrv->probe = gbam_data_ch_probe;
 	pdrv->remove = gbam_data_ch_remove;
-	pdrv->driver.name = bam_ch_names[portno];
+	pdrv->driver.name = bam_ch_names[func];
 	pdrv->driver.owner = THIS_MODULE;
 
 	platform_driver_register(pdrv);
-	pr_debug("%s: port:%pK portno:%d\n", __func__, port, portno);
-
-	return 0;
-}
-
-static int gbam2bam_port_alloc(int portno)
-{
-	struct gbam_port	*port;
-	struct bam_ch_info	*d;
-
-	port = kzalloc(sizeof(struct gbam_port), GFP_KERNEL);
-	if (!port)
-		return -ENOMEM;
-
-	port->port_num = portno;
-
-	/* port initialization */
-	port->is_connected = false;
-	spin_lock_init(&port->port_lock_ul);
-	spin_lock_init(&port->port_lock_dl);
-	spin_lock_init(&port->port_lock);
-
-	INIT_WORK(&port->connect_w, gbam2bam_connect_work);
-	INIT_WORK(&port->disconnect_w, gbam2bam_disconnect_work);
-	INIT_WORK(&port->suspend_w, gbam2bam_suspend_work);
-	INIT_WORK(&port->resume_w, gbam2bam_resume_work);
-
-	/* data ch */
-	d = &port->data_ch;
-	d->port = port;
-	d->ipa_params.src_client = usb_prod[portno];
-	d->ipa_params.dst_client = usb_cons[portno];
-	bam2bam_ports[portno] = port;
-
-	/* UL workaround requirements */
-	skb_queue_head_init(&d->rx_skb_q);
-	skb_queue_head_init(&d->rx_skb_idle);
-	INIT_LIST_HEAD(&d->rx_idle);
-	INIT_WORK(&d->write_tobam_w, gbam_data_write_tobam);
-
-	pr_debug("%s: port:%pK portno:%d\n", __func__, port, portno);
+	pr_debug("%s: port:%pK portno:%d\n", __func__, port, func);
 
 	return 0;
 }
@@ -1928,7 +1109,7 @@
 	if (!buf)
 		return -ENOMEM;
 
-	for (i = 0; i < n_bam_ports; i++) {
+	for (i = 0; i < BAM_DMUX_NUM_FUNCS; i++) {
 		port = bam_ports[i].port;
 		if (!port)
 			continue;
@@ -1991,7 +1172,7 @@
 	int			i;
 	unsigned long		flags;
 
-	for (i = 0; i < n_bam_ports; i++) {
+	for (i = 0; i < BAM_DMUX_NUM_FUNCS; i++) {
 		port = bam_ports[i].port;
 		if (!port)
 			continue;
@@ -2021,48 +1202,12 @@
 	return count;
 }
 
-const struct file_operations gbam_stats_ops = {
+static const struct file_operations gbam_stats_ops = {
 	.read = gbam_read_stats,
 	.write = gbam_reset_stats,
 };
 
-static ssize_t gbam_rw_write(struct file *file, const char __user *ubuf,
-				size_t count, loff_t *ppos)
-{
-	struct gbam_port	*port = bam2bam_ports[0];
-	struct usb_function	*func;
-	struct usb_gadget	*gadget;
-	unsigned long		flags;
-
-	if (!port)
-		return -ENODEV;
-
-	spin_lock_irqsave(&port->port_lock, flags);
-	if (!port->port_usb) {
-		pr_debug("%s: usb cable is disconnected, exiting\n",
-				__func__);
-		spin_unlock_irqrestore(&port->port_lock, flags);
-		return -ENODEV;
-	}
-
-	gadget = port->port_usb->gadget;
-	func = port->port_usb->f;
-	spin_unlock_irqrestore(&port->port_lock, flags);
-
-	if ((gadget->speed == USB_SPEED_SUPER) && (func->func_is_suspended)) {
-		pr_debug("%s Initiating usb_func rwakeup\n", __func__);
-		usb_func_wakeup(func);
-	}
-
-	return count;
-}
-
-
-const struct file_operations debug_remote_wakeup_fops = {
-	.write = gbam_rw_write,
-};
-
-struct dentry *gbam_dent;
+static struct dentry *gbam_dent;
 static void gbam_debugfs_init(void)
 {
 	struct dentry *dfile;
@@ -2070,14 +1215,11 @@
 	if (gbam_dent)
 		return;
 
-	gbam_dent = debugfs_create_dir("usb_rmnet", 0);
+	gbam_dent = debugfs_create_dir("usb_rmnet", NULL);
 	if (!gbam_dent || IS_ERR(gbam_dent))
 		return;
 
-	debugfs_create_file("remote_wakeup", 0444, gbam_dent, 0,
-			&debug_remote_wakeup_fops);
-
-	dfile = debugfs_create_file("status", 0444, gbam_dent, 0,
+	dfile = debugfs_create_file("status", 0444, gbam_dent, NULL,
 			&gbam_stats_ops);
 	if (!dfile || IS_ERR(dfile)) {
 		debugfs_remove(gbam_dent);
@@ -2094,29 +1236,16 @@
 static inline void gbam_debugfs_remove(void) {}
 #endif
 
-void gbam_disconnect(struct grmnet *gr, u8 port_num, enum transport_type trans)
+void gbam_disconnect(struct data_port *gr, enum bam_dmux_func_type func)
 {
 	struct gbam_port	*port;
-	unsigned long		flags, flags_ul, flags_dl;
+	unsigned long		flags, flags_ul;
 	struct bam_ch_info	*d;
 
-	pr_debug("%s: grmnet:%pK port#%d\n", __func__, gr, port_num);
+	pr_debug("%s: grmnet:%pK port#%d\n", __func__, gr, func);
 
-	if (trans == USB_GADGET_XPORT_BAM2BAM) {
-		pr_err("%s: invalid xport#%d\n", __func__, trans);
-		return;
-	}
-	if (trans == USB_GADGET_XPORT_BAM_DMUX &&
-		port_num >= n_bam_ports) {
-		pr_err("%s: invalid bam portno#%d\n",
-			   __func__, port_num);
-		return;
-	}
-
-	if ((trans == USB_GADGET_XPORT_BAM2BAM_IPA) &&
-				port_num >= n_bam2bam_ports) {
-		pr_err("%s: invalid bam2bam portno#%d\n",
-			   __func__, port_num);
+	if (func >= BAM_DMUX_NUM_FUNCS) {
+		pr_err("%s: invalid bam portno#%d\n", __func__, func);
 		return;
 	}
 
@@ -2124,10 +1253,7 @@
 		pr_err("%s: grmnet port is null\n", __func__);
 		return;
 	}
-	if (trans == USB_GADGET_XPORT_BAM_DMUX)
-		port = bam_ports[port_num].port;
-	else
-		port = bam2bam_ports[port_num];
+	port = bam_ports[func].port;
 
 	if (!port) {
 		pr_err("%s: NULL port", __func__);
@@ -2142,124 +1268,58 @@
 		spin_unlock_irqrestore(&port->port_lock, flags);
 		return;
 	}
-	/*
-	 * Suspend with remote wakeup enabled. Increment usage
-	 * count when disconnect happens in suspended state.
-	 * Corresponding decrement happens in the end of this
-	 * function if IPA handshake is already done or it is done
-	 * in disconnect work after finishing IPA handshake.
-	 */
-	if (port->last_event == U_BAM_SUSPEND_E)
-		usb_gadget_autopm_get_noresume(port->gadget);
 
 	port->port_usb = gr;
 
-	if (trans == USB_GADGET_XPORT_BAM_DMUX)
-		gbam_free_buffers(port);
-	else if (trans == USB_GADGET_XPORT_BAM2BAM_IPA)
-		gbam_free_rx_buffers(port);
+	gbam_free_buffers(port);
 
 	spin_lock_irqsave(&port->port_lock_ul, flags_ul);
 	spin_lock(&port->port_lock_dl);
-	port->port_usb = 0;
+	port->port_usb = NULL;
 	n_tx_req_queued = 0;
 	spin_unlock(&port->port_lock_dl);
 	spin_unlock_irqrestore(&port->port_lock_ul, flags_ul);
 
 	usb_ep_disable(gr->in);
-	if (trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
-		spin_lock_irqsave(&port->port_lock_dl, flags_dl);
-		if (d->tx_req) {
-			usb_ep_free_request(gr->in, d->tx_req);
-			d->tx_req = NULL;
-		}
-		spin_unlock_irqrestore(&port->port_lock_dl, flags_dl);
-	}
 	/* disable endpoints */
-	if (gr->out) {
+	if (gr->out)
 		usb_ep_disable(gr->out);
-		if (trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
-			spin_lock_irqsave(&port->port_lock_ul, flags_ul);
-			if (d->rx_req) {
-				usb_ep_free_request(gr->out, d->rx_req);
-				d->rx_req = NULL;
-			}
-			spin_unlock_irqrestore(&port->port_lock_ul, flags_ul);
-		}
-	}
-
-	/*
-	 * Set endless flag to false as USB Endpoint is already
-	 * disable.
-	 */
-	if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
-
-		if (d->dst_pipe_type == USB_BAM_PIPE_BAM2BAM)
-			gr->in->endless = false;
-
-		if (d->src_pipe_type == USB_BAM_PIPE_BAM2BAM && gr->out)
-			gr->out->endless = false;
-	}
 
 	gr->in->driver_data = NULL;
 	if (gr->out)
 		gr->out->driver_data = NULL;
 
 	port->last_event = U_BAM_DISCONNECT_E;
-	/* Disable usb irq for CI gadget. It will be enabled in
-	 * usb_bam_disconnect_pipe() after disconnecting all pipes
-	 * and USB BAM reset is done.
-	 */
-	if (!gadget_is_dwc3(port->gadget) &&
-			(trans == USB_GADGET_XPORT_BAM2BAM_IPA))
-		msm_usb_irq_disable(true);
-
 	queue_work(gbam_wq, &port->disconnect_w);
 
 	spin_unlock_irqrestore(&port->port_lock, flags);
 }
 
-int gbam_connect(struct grmnet *gr, u8 port_num,
-		enum transport_type trans, u8 src_connection_idx,
-		u8 dst_connection_idx)
+int gbam_connect(struct data_port *gr, enum bam_dmux_func_type func)
 {
 	struct gbam_port	*port;
 	struct bam_ch_info	*d;
 	int			ret;
 	unsigned long		flags, flags_ul;
 
-	pr_debug("%s: grmnet:%pK port#%d\n", __func__, gr, port_num);
+	pr_debug("%s: grmnet:%pK port#%d\n", __func__, gr, func);
 
 	if (!gr) {
 		pr_err("%s: grmnet port is null\n", __func__);
 		return -ENODEV;
 	}
 
-	if (!gr->gadget) {
+	if (!gr->cdev->gadget) {
 		pr_err("%s: gadget handle not passed\n", __func__);
 		return -EINVAL;
 	}
 
-	if (trans == USB_GADGET_XPORT_BAM2BAM) {
-		pr_err("%s: invalid xport#%d\n", __func__, trans);
-		return -EINVAL;
-	}
-
-	if (trans == USB_GADGET_XPORT_BAM_DMUX && port_num >= n_bam_ports) {
-		pr_err("%s: invalid portno#%d\n", __func__, port_num);
+	if (func >= BAM_DMUX_NUM_FUNCS) {
+		pr_err("%s: invalid portno#%d\n", __func__, func);
 		return -ENODEV;
 	}
 
-	if ((trans == USB_GADGET_XPORT_BAM2BAM_IPA)
-			&& port_num >= n_bam2bam_ports) {
-		pr_err("%s: invalid portno#%d\n", __func__, port_num);
-		return -ENODEV;
-	}
-
-	if (trans == USB_GADGET_XPORT_BAM_DMUX)
-		port = bam_ports[port_num].port;
-	else
-		port = bam2bam_ports[port_num];
+	port = bam_ports[func].port;
 
 	if (!port) {
 		pr_err("%s: NULL port", __func__);
@@ -2269,108 +1329,28 @@
 	spin_lock_irqsave(&port->port_lock, flags);
 
 	d = &port->data_ch;
-	d->trans = trans;
 
 	spin_lock_irqsave(&port->port_lock_ul, flags_ul);
 	spin_lock(&port->port_lock_dl);
 	port->port_usb = gr;
-	port->gadget = port->port_usb->gadget;
+	port->gadget = port->port_usb->cdev->gadget;
 
-	if (trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
-		d->rx_req = usb_ep_alloc_request(port->port_usb->out,
-								GFP_ATOMIC);
-		if (!d->rx_req) {
-			pr_err("%s: RX request allocation failed\n", __func__);
-			d->rx_req = NULL;
-			spin_unlock(&port->port_lock_dl);
-			spin_unlock_irqrestore(&port->port_lock_ul, flags_ul);
-			spin_unlock_irqrestore(&port->port_lock, flags);
-			return -ENOMEM;
-		}
-
-		d->rx_req->context = port;
-		d->rx_req->complete = gbam_endless_rx_complete;
-		d->rx_req->length = 0;
-		d->rx_req->no_interrupt = 1;
-
-		d->tx_req = usb_ep_alloc_request(port->port_usb->in,
-								GFP_ATOMIC);
-		if (!d->tx_req) {
-			pr_err("%s: TX request allocation failed\n", __func__);
-			d->tx_req = NULL;
-			usb_ep_free_request(port->port_usb->out, d->rx_req);
-			d->rx_req = NULL;
-			spin_unlock(&port->port_lock_dl);
-			spin_unlock_irqrestore(&port->port_lock_ul, flags_ul);
-			spin_unlock_irqrestore(&port->port_lock, flags);
-			return -ENOMEM;
-		}
-
-		d->tx_req->context = port;
-		d->tx_req->complete = gbam_endless_tx_complete;
-		d->tx_req->length = 0;
-		d->tx_req->no_interrupt = 1;
-	}
-
-	if (d->trans == USB_GADGET_XPORT_BAM_DMUX) {
-		d->to_host = 0;
-		d->to_modem = 0;
-		d->pending_pkts_with_bam = 0;
-		d->pending_bytes_with_bam = 0;
-		d->tohost_drp_cnt = 0;
-		d->tomodem_drp_cnt = 0;
-		d->rx_flow_control_disable = 0;
-		d->rx_flow_control_enable = 0;
-		d->rx_flow_control_triggered = 0;
-		d->max_num_pkts_pending_with_bam = 0;
-		d->max_bytes_pending_with_bam = 0;
-		d->delayed_bam_mux_write_done = 0;
-	}
+	d->to_host = 0;
+	d->to_modem = 0;
+	d->pending_pkts_with_bam = 0;
+	d->pending_bytes_with_bam = 0;
+	d->tohost_drp_cnt = 0;
+	d->tomodem_drp_cnt = 0;
+	d->rx_flow_control_disable = 0;
+	d->rx_flow_control_enable = 0;
+	d->rx_flow_control_triggered = 0;
+	d->max_num_pkts_pending_with_bam = 0;
+	d->max_bytes_pending_with_bam = 0;
+	d->delayed_bam_mux_write_done = 0;
 
 	spin_unlock(&port->port_lock_dl);
 	spin_unlock_irqrestore(&port->port_lock_ul, flags_ul);
 
-	if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
-		d->src_connection_idx = src_connection_idx;
-		d->dst_connection_idx = dst_connection_idx;
-		d->usb_bam_type = usb_bam_get_bam_type(gr->gadget->name);
-		d->ipa_params.src_pipe = &(d->src_pipe_idx);
-		d->ipa_params.dst_pipe = &(d->dst_pipe_idx);
-		d->ipa_params.src_idx = src_connection_idx;
-		d->ipa_params.dst_idx = dst_connection_idx;
-
-		/*
-		 * Query pipe type using IPA src/dst index with
-		 * usbbam driver. It is being set either as
-		 * BAM2BAM or SYS2BAM.
-		 */
-		if (usb_bam_get_pipe_type(d->usb_bam_type,
-				d->ipa_params.src_idx, &d->src_pipe_type) ||
-		    usb_bam_get_pipe_type(d->usb_bam_type,
-				d->ipa_params.dst_idx, &d->dst_pipe_type)) {
-			pr_err("%s:usb_bam_get_pipe_type() failed\n",
-				__func__);
-			ret = -EINVAL;
-			usb_ep_free_request(port->port_usb->out, d->rx_req);
-			d->rx_req = NULL;
-			usb_ep_free_request(port->port_usb->in, d->tx_req);
-			d->tx_req = NULL;
-			goto exit;
-		}
-		/*
-		 * Check for pipe_type. If it is BAM2BAM, then it is required
-		 * to disable Xfer complete and Xfer not ready interrupts for
-		 * that particular endpoint. Hence it set endless flag based
-		 * it which is considered into UDC driver while enabling
-		 * USB Endpoint.
-		 */
-		if (d->dst_pipe_type == USB_BAM_PIPE_BAM2BAM)
-			port->port_usb->in->endless = true;
-
-		if (d->src_pipe_type == USB_BAM_PIPE_BAM2BAM)
-			port->port_usb->out->endless = true;
-	}
-
 	ret = usb_ep_enable(gr->in);
 	if (ret) {
 		pr_err("%s: usb_ep_enable failed eptype:IN ep:%pK",
@@ -2379,11 +1359,6 @@
 		d->rx_req = NULL;
 		usb_ep_free_request(port->port_usb->in, d->tx_req);
 		d->tx_req = NULL;
-		if (d->dst_pipe_type == USB_BAM_PIPE_BAM2BAM)
-			port->port_usb->in->endless = false;
-
-		if (d->src_pipe_type == USB_BAM_PIPE_BAM2BAM)
-			port->port_usb->out->endless = false;
 		goto exit;
 	}
 	gr->in->driver_data = port;
@@ -2398,30 +1373,18 @@
 		if (ret) {
 			pr_err("%s: usb_ep_enable failed eptype:OUT ep:%pK",
 					__func__, gr->out);
-			gr->in->driver_data = 0;
+			gr->in->driver_data = NULL;
 			usb_ep_disable(gr->in);
 			usb_ep_free_request(port->port_usb->out, d->rx_req);
 			d->rx_req = NULL;
 			usb_ep_free_request(port->port_usb->in, d->tx_req);
 			d->tx_req = NULL;
-			if (d->dst_pipe_type == USB_BAM_PIPE_BAM2BAM)
-				port->port_usb->in->endless = false;
-
-			if (d->src_pipe_type == USB_BAM_PIPE_BAM2BAM)
-				port->port_usb->out->endless = false;
 			goto exit;
 		}
 		gr->out->driver_data = port;
 	}
 
 	port->last_event = U_BAM_CONNECT_E;
-	/*
-	 * Increment usage count upon cable connect. Decrement after IPA
-	 * handshake is done in disconnect work (due to cable disconnect)
-	 * or in suspend work.
-	 */
-	if (trans == USB_GADGET_XPORT_BAM2BAM_IPA)
-		usb_gadget_autopm_get_noresume(port->gadget);
 	queue_work(gbam_wq, &port->connect_w);
 
 	ret = 0;
@@ -2430,24 +1393,14 @@
 	return ret;
 }
 
-void gbam_data_flush_workqueue(void)
+int gbam_setup(enum bam_dmux_func_type func)
 {
-	pr_debug("%s(): Flushing workqueue\n", __func__);
-	flush_workqueue(gbam_wq);
-}
-
-int gbam_setup(unsigned int no_bam_port)
-{
-	int	i;
 	int	ret;
-	int	bam_port_start = n_bam_ports;
-	int	total_bam_ports = bam_port_start + no_bam_port;
 
-	pr_debug("%s: requested BAM ports:%d\n", __func__, no_bam_port);
+	pr_debug("%s: requested BAM port:%d\n", __func__, func);
 
-	if (!no_bam_port || total_bam_ports > BAM_N_PORTS) {
-		pr_err("%s: Invalid num of ports count:%d\n",
-				__func__, no_bam_port);
+	if (func >= BAM_DMUX_NUM_FUNCS) {
+		pr_err("%s: Invalid num of ports count:%d\n", __func__, func);
 		return -EINVAL;
 	}
 
@@ -2461,171 +1414,54 @@
 		}
 	}
 
-	for (i = bam_port_start; i < (bam_port_start + no_bam_port); i++) {
-		n_bam_ports++;
-		pr_debug("gbam_port_alloc called for %d\n", i);
-		ret = gbam_port_alloc(i);
-		if (ret) {
-			n_bam_ports--;
-			pr_err("%s: Unable to alloc port:%d\n", __func__, i);
-			goto free_bam_ports;
-		}
+	ret = gbam_port_alloc(func);
+	if (ret) {
+		pr_err("%s: Unable to alloc port:%d\n", __func__, func);
+		goto destroy_wq;
 	}
 
 	gbam_debugfs_init();
 
-	return bam_port_start;
+	return 0;
 
-free_bam_ports:
-	for (i = 0; i < n_bam_ports; i++)
-		gbam_port_free(i);
+destroy_wq:
 	destroy_workqueue(gbam_wq);
 
 	return ret;
 }
 
-int gbam2bam_setup(unsigned int no_bam2bam_port)
-{
-	int	i;
-	int	ret;
-	int	bam2bam_port_start = n_bam2bam_ports;
-	int	total_bam2bam_ports = bam2bam_port_start + no_bam2bam_port;
-
-	pr_debug("%s: requested BAM2BAM ports:%d\n", __func__, no_bam2bam_port);
-
-	if (!no_bam2bam_port || total_bam2bam_ports > BAM2BAM_N_PORTS) {
-		pr_err("%s: Invalid num of ports count:%d\n",
-				__func__, no_bam2bam_port);
-		return -EINVAL;
-	}
-
-	if (!gbam_wq) {
-		gbam_wq = alloc_workqueue("k_gbam", WQ_UNBOUND |
-					WQ_MEM_RECLAIM, 1);
-		if (!gbam_wq) {
-			pr_err("%s: Unable to create workqueue gbam_wq\n",
-					__func__);
-			return -ENOMEM;
-		}
-	}
-
-	for (i = bam2bam_port_start; i < (bam2bam_port_start +
-				no_bam2bam_port); i++) {
-		n_bam2bam_ports++;
-		ret = gbam2bam_port_alloc(i);
-		if (ret) {
-			n_bam2bam_ports--;
-			pr_err("%s: Unable to alloc port:%d\n", __func__, i);
-			goto free_bam2bam_ports;
-		}
-	}
-
-	gbam_debugfs_init();
-
-	return bam2bam_port_start;
-
-free_bam2bam_ports:
-	for (i = 0; i < n_bam2bam_ports; i++)
-		gbam2bam_port_free(i);
-	destroy_workqueue(gbam_wq);
-
-	return ret;
-}
-
-void gbam_cleanup(void)
+void gbam_cleanup(enum bam_dmux_func_type func)
 {
 	gbam_debugfs_remove();
-}
-
-void gbam_suspend(struct grmnet *gr, u8 port_num, enum transport_type trans)
-{
-	struct gbam_port	*port;
-	struct bam_ch_info *d;
-	unsigned long flags;
-
-	if (trans != USB_GADGET_XPORT_BAM2BAM_IPA)
-		return;
-
-	port = bam2bam_ports[port_num];
-
-	if (!port) {
-		pr_err("%s: NULL port", __func__);
-		return;
-	}
-
-	spin_lock_irqsave(&port->port_lock, flags);
-
-	d = &port->data_ch;
-
-	pr_debug("%s: suspended port %d\n", __func__, port_num);
-
-	port->last_event = U_BAM_SUSPEND_E;
-	queue_work(gbam_wq, &port->suspend_w);
-
-	spin_unlock_irqrestore(&port->port_lock, flags);
-}
-
-void gbam_resume(struct grmnet *gr, u8 port_num, enum transport_type trans)
-{
-	struct gbam_port	*port;
-	struct bam_ch_info *d;
-	unsigned long flags;
-
-	if (trans != USB_GADGET_XPORT_BAM2BAM_IPA)
-		return;
-
-	port = bam2bam_ports[port_num];
-
-	if (!port) {
-		pr_err("%s: NULL port", __func__);
-		return;
-	}
-
-	spin_lock_irqsave(&port->port_lock, flags);
-
-	d = &port->data_ch;
-
-	pr_debug("%s: resumed port %d\n", __func__, port_num);
-
-	port->last_event = U_BAM_RESUME_E;
-	/*
-	 * 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 bam_disconnect
-	 * in suspended state.
-	 */
-	usb_gadget_autopm_get_noresume(port->gadget);
-	queue_work(gbam_wq, &port->resume_w);
-
-	spin_unlock_irqrestore(&port->port_lock, flags);
+	gbam_port_free(func);
 }
 
 int gbam_mbim_connect(struct usb_gadget *g, struct usb_ep *in,
 			struct usb_ep *out)
 {
-	struct grmnet *gr;
+	struct data_port *gr;
 
 	gr = kzalloc(sizeof(*gr), GFP_ATOMIC);
 	if (!gr)
 		return -ENOMEM;
 	gr->in = in;
 	gr->out = out;
-	gr->gadget = g;
+	gr->cdev->gadget = g;
 
-	return gbam_connect(gr, 0, USB_GADGET_XPORT_BAM_DMUX, 0, 0);
+	return gbam_connect(gr, BAM_DMUX_FUNC_MBIM);
 }
 
 void gbam_mbim_disconnect(void)
 {
-	struct gbam_port *port = bam_ports[0].port;
-	struct grmnet *gr = port->port_usb;
+	struct gbam_port *port = bam_ports[BAM_DMUX_FUNC_MBIM].port;
+	struct data_port *gr = port->port_usb;
 
 	if (!gr) {
 		pr_err("%s: port_usb is NULL\n", __func__);
 		return;
 	}
 
-	gbam_disconnect(gr, 0, USB_GADGET_XPORT_BAM_DMUX);
+	gbam_disconnect(gr, BAM_DMUX_FUNC_MBIM);
 	kfree(gr);
 }
 
@@ -2633,13 +1469,7 @@
 {
 	int ret = 0;
 
-	/*
-	 * MBIM requires only 1 USB_GADGET_XPORT_BAM_DMUX
-	 * port. The port is always 0 and is shared
-	 * between RMNET and MBIM.
-	 */
-	if (!n_bam_ports)
-		ret = gbam_setup(1);
+	ret = gbam_setup(BAM_DMUX_FUNC_MBIM);
 
 	return ret;
 }
diff --git a/drivers/usb/gadget/function/u_ctrl_qti.c b/drivers/usb/gadget/function/u_ctrl_qti.c
index 21839a3e..4ab7bc4 100644
--- a/drivers/usb/gadget/function/u_ctrl_qti.c
+++ b/drivers/usb/gadget/function/u_ctrl_qti.c
@@ -17,6 +17,8 @@
 #include <linux/cdev.h>
 #include <linux/debugfs.h>
 
+#include <soc/qcom/bam_dmux.h>
+
 #include "u_rmnet.h"
 #include "f_qdss.h"
 
@@ -206,7 +208,8 @@
 	qti_ctrl_queue_notify(port);
 }
 
-int gqti_ctrl_connect(void *gr, enum qti_port_type qport, unsigned int intf)
+int gqti_ctrl_connect(void *gr, enum qti_port_type qport, unsigned int intf,
+						enum data_xport_type dxport)
 {
 	struct qti_ctrl_port	*port;
 	struct grmnet *g_rmnet = NULL;
@@ -226,8 +229,16 @@
 
 	spin_lock_irqsave(&port->lock, flags);
 	port->port_type = qport;
-	port->ep_type = DATA_EP_TYPE_HSUSB;
-	port->intf = intf;
+	if (dxport == BAM_DMUX) {
+		port->ep_type = DATA_EP_TYPE_BAM_DMUX;
+		port->intf = (qport == QTI_PORT_RMNET) ?
+			BAM_DMUX_USB_RMNET_0 : BAM_DMUX_USB_DPL;
+		port->ipa_prod_idx = 0;
+		port->ipa_cons_idx = 0;
+	} else {
+		port->ep_type = DATA_EP_TYPE_HSUSB;
+		port->intf = intf;
+	}
 
 	if (gr) {
 		port->port_usb = gr;
diff --git a/drivers/usb/gadget/function/u_data_ipa.c b/drivers/usb/gadget/function/u_data_ipa.c
index f379028..32e8cc9 100644
--- a/drivers/usb/gadget/function/u_data_ipa.c
+++ b/drivers/usb/gadget/function/u_data_ipa.c
@@ -23,7 +23,6 @@
 #include <linux/usb_bam.h>
 
 #include "u_data_ipa.h"
-#include "u_rmnet.h"
 
 struct ipa_data_ch_info {
 	struct usb_request			*rx_req;
@@ -45,7 +44,7 @@
 	u8					src_connection_idx;
 	u8					dst_connection_idx;
 	enum usb_ctrl				usb_bam_type;
-	struct gadget_ipa_port			*port_usb;
+	struct data_port			*port_usb;
 	struct usb_gadget			*gadget;
 	atomic_t				pipe_connect_notified;
 	struct usb_bam_connect_ipa_params	ipa_params;
@@ -299,7 +298,7 @@
  * switch is being trigger. This API performs restoring USB endpoint operation
  * and disable USB endpoint used for accelerated path.
  */
-void ipa_data_disconnect(struct gadget_ipa_port *gp, enum ipa_func_type func)
+void ipa_data_disconnect(struct data_port *gp, enum ipa_func_type func)
 {
 	struct ipa_data_ch_info *port;
 	unsigned long flags;
@@ -402,7 +401,7 @@
 {
 	struct ipa_data_ch_info *port = container_of(w, struct ipa_data_ch_info,
 								connect_w);
-	struct gadget_ipa_port	*gport;
+	struct data_port	*gport;
 	struct usb_gadget	*gadget = NULL;
 	struct teth_bridge_connect_params connect_params;
 	struct teth_bridge_init_params teth_bridge_params;
@@ -730,7 +729,7 @@
  * initiate USB BAM IPA connection. This API is enabling accelerated endpoints
  * and schedule connect_work() which establishes USB IPA BAM communication.
  */
-int ipa_data_connect(struct gadget_ipa_port *gp, enum ipa_func_type func,
+int ipa_data_connect(struct data_port *gp, enum ipa_func_type func,
 		u8 src_connection_idx, u8 dst_connection_idx)
 {
 	struct ipa_data_ch_info *port;
@@ -939,7 +938,7 @@
  * It is being used to initiate USB BAM IPA suspend functionality
  * for USB bus suspend functionality.
  */
-void ipa_data_suspend(struct gadget_ipa_port *gp, enum ipa_func_type func,
+void ipa_data_suspend(struct data_port *gp, enum ipa_func_type func,
 			bool remote_wakeup_enabled)
 {
 	struct ipa_data_ch_info *port;
@@ -1050,7 +1049,7 @@
  * It is being used to initiate USB resume functionality
  * for USB bus resume case.
  */
-void ipa_data_resume(struct gadget_ipa_port *gp, enum ipa_func_type func,
+void ipa_data_resume(struct data_port *gp, enum ipa_func_type func,
 			bool remote_wakeup_enabled)
 {
 	struct ipa_data_ch_info *port;
diff --git a/drivers/usb/gadget/function/u_data_ipa.h b/drivers/usb/gadget/function/u_data_ipa.h
index 70d4293..d2d419b 100644
--- a/drivers/usb/gadget/function/u_data_ipa.h
+++ b/drivers/usb/gadget/function/u_data_ipa.h
@@ -34,19 +34,6 @@
 /* Max Number of IPA data ports supported */
 #define IPA_N_PORTS USB_IPA_NUM_FUNCS
 
-struct gadget_ipa_port {
-	struct usb_composite_dev	*cdev;
-	struct usb_function		*func;
-	int				rx_buffer_size;
-	struct usb_ep			*in;
-	struct usb_ep			*out;
-	int				ipa_consumer_ep;
-	int				ipa_producer_ep;
-	const struct usb_endpoint_descriptor	*in_ep_desc_backup;
-	const struct usb_endpoint_descriptor	*out_ep_desc_backup;
-
-};
-
 struct ipa_function_bind_info {
 	struct usb_string *string_defs;
 	int data_str_idx;
@@ -85,16 +72,16 @@
 };
 
 void ipa_data_port_select(enum ipa_func_type func);
-void ipa_data_disconnect(struct gadget_ipa_port *gp, enum ipa_func_type func);
-int ipa_data_connect(struct gadget_ipa_port *gp, enum ipa_func_type func,
+void ipa_data_disconnect(struct data_port *gp, enum ipa_func_type func);
+int ipa_data_connect(struct data_port *gp, enum ipa_func_type func,
 			u8 src_connection_idx, u8 dst_connection_idx);
 int ipa_data_setup(enum ipa_func_type func);
 void ipa_data_free(enum ipa_func_type func);
 
 void ipa_data_flush_workqueue(void);
-void ipa_data_resume(struct gadget_ipa_port *gp, enum ipa_func_type func,
+void ipa_data_resume(struct data_port *gp, enum ipa_func_type func,
 		bool remote_wakeup_enabled);
-void ipa_data_suspend(struct gadget_ipa_port *gp, enum ipa_func_type func,
+void ipa_data_suspend(struct data_port *gp, enum ipa_func_type func,
 		bool remote_wakeup_enabled);
 
 void ipa_data_set_ul_max_xfer_size(u32 ul_max_xfer_size);
@@ -109,11 +96,34 @@
 
 void ipa_data_stop_rndis_ipa(enum ipa_func_type func);
 
+#ifdef CONFIG_USB_F_QCRNDIS
 void *rndis_qc_get_ipa_priv(void);
 void *rndis_qc_get_ipa_rx_cb(void);
 bool rndis_qc_get_skip_ep_config(void);
 void *rndis_qc_get_ipa_tx_cb(void);
 void rndis_ipa_reset_trigger(void);
+#else
+static inline void *rndis_qc_get_ipa_priv(void)
+{
+	return NULL;
+}
+static inline void *rndis_qc_get_ipa_rx_cb(void)
+{
+	return NULL;
+}
+static inline bool rndis_qc_get_skip_ep_config(void)
+{
+	return true;
+}
+static inline void *rndis_qc_get_ipa_tx_cb(void)
+{
+	return NULL;
+}
+static inline void rndis_ipa_reset_trigger(void)
+{
+}
+#endif /* CONFIG_USB_F_QCRNDIS */
+
 #if IS_ENABLED(CONFIG_USB_CONFIGFS_RMNET_BAM)
 void gqti_ctrl_update_ipa_pipes(void *gr, enum qti_port_type qport,
 				u32 ipa_prod, u32 ipa_cons);
diff --git a/drivers/usb/gadget/function/u_rmnet.h b/drivers/usb/gadget/function/u_rmnet.h
index 0126932..f639722 100644
--- a/drivers/usb/gadget/function/u_rmnet.h
+++ b/drivers/usb/gadget/function/u_rmnet.h
@@ -20,12 +20,32 @@
 
 #include "f_qdss.h"
 
+enum bam_dmux_func_type {
+	BAM_DMUX_FUNC_RMNET,
+	BAM_DMUX_FUNC_MBIM,
+	BAM_DMUX_FUNC_DPL,
+	BAM_DMUX_NUM_FUNCS,
+};
+
 struct rmnet_ctrl_pkt {
 	void	*buf;
 	int	len;
 	struct list_head	list;
 };
 
+struct data_port {
+	struct usb_composite_dev	*cdev;
+	struct usb_function		*func;
+	int				rx_buffer_size;
+	struct usb_ep			*in;
+	struct usb_ep			*out;
+	int				ipa_consumer_ep;
+	int				ipa_producer_ep;
+	const struct usb_endpoint_descriptor	*in_ep_desc_backup;
+	const struct usb_endpoint_descriptor	*out_ep_desc_backup;
+
+};
+
 struct grmnet {
 	/* to usb host, aka laptop, windows pc etc. Will
 	 * be filled by usb driver of rmnet functionality
@@ -49,7 +69,23 @@
 	NR_CTRL_CLIENTS
 };
 
-int gqti_ctrl_connect(void *gr, enum qti_port_type qport, unsigned int intf);
+enum data_xport_type {
+	BAM_DMUX,
+	BAM2BAM_IPA,
+	NR_XPORT_TYPES
+};
+
+int gbam_connect(struct data_port *gr, enum bam_dmux_func_type func);
+void gbam_disconnect(struct data_port *gr, enum bam_dmux_func_type func);
+void gbam_cleanup(enum bam_dmux_func_type func);
+int gbam_setup(enum bam_dmux_func_type func);
+int gbam_mbim_connect(struct usb_gadget *g, struct usb_ep *in,
+			struct usb_ep *out);
+void gbam_mbim_disconnect(void);
+int gbam_mbim_setup(void);
+
+int gqti_ctrl_connect(void *gr, enum qti_port_type qport, unsigned int intf,
+						enum data_xport_type dxport);
 void gqti_ctrl_disconnect(void *gr, enum qti_port_type qport);
 int gqti_ctrl_init(void);
 void gqti_ctrl_cleanup(void);
diff --git a/include/linux/slimbus/slimbus.h b/include/linux/slimbus/slimbus.h
index 53af941..4b5dc54 100644
--- a/include/linux/slimbus/slimbus.h
+++ b/include/linux/slimbus/slimbus.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -601,7 +601,7 @@
 	int			(*framer_handover)(struct slim_controller *ctrl,
 				struct slim_framer *new_framer);
 	int			(*port_xfer)(struct slim_controller *ctrl,
-				u8 pn, phys_addr_t iobuf, u32 len,
+				u8 pn, void *buf, u32 len,
 				struct completion *comp);
 	enum slim_port_err	(*port_xfer_status)(struct slim_controller *ctr,
 				u8 pn, phys_addr_t *done_buf, u32 *done_len);
@@ -869,7 +869,7 @@
  * Client will call slim_port_get_xfer_status to get error and/or number of
  * bytes transferred if used asynchronously.
  */
-extern int slim_port_xfer(struct slim_device *sb, u32 ph, phys_addr_t iobuf,
+extern int slim_port_xfer(struct slim_device *sb, u32 ph, void *buf,
 				u32 len, struct completion *comp);
 
 /*
diff --git a/include/linux/usb_bam.h b/include/linux/usb_bam.h
index 84d7549..e5d4c04 100644
--- a/include/linux/usb_bam.h
+++ b/include/linux/usb_bam.h
@@ -426,7 +426,7 @@
  *
  * @return true when producer granted, false when prodcuer is released.
  */
-bool usb_bam_get_prod_granted(enum usb_ctrl bam_type, u8 idx);
+bool usb_bam_get_prod_granted(enum usb_ctrl bam_type);
 
 /* Allocates memory for data fifo and descriptor fifos. */
 int usb_bam_alloc_fifos(enum usb_ctrl cur_bam, u8 idx);
@@ -519,7 +519,7 @@
 	return -ENODEV;
 }
 
-static inline bool usb_bam_get_prod_granted(enum usb_ctrl bam_type, u8 idx)
+static inline bool usb_bam_get_prod_granted(enum usb_ctrl bam_type)
 {
 	return false;
 }
diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h
index f730b91..9e1aa1a 100644
--- a/include/sound/rawmidi.h
+++ b/include/sound/rawmidi.h
@@ -78,6 +78,7 @@
 	size_t xruns;		/* over/underruns counter */
 	/* misc */
 	spinlock_t lock;
+	struct mutex realloc_mutex;
 	wait_queue_head_t sleep;
 	/* event handler (new bytes, input only) */
 	void (*event)(struct snd_rawmidi_substream *substream);
diff --git a/kernel/sched/energy.c b/kernel/sched/energy.c
index 420cb52..77d8361 100644
--- a/kernel/sched/energy.c
+++ b/kernel/sched/energy.c
@@ -150,6 +150,7 @@
 	int cpu;
 	unsigned long *max_frequencies = NULL;
 	int ret;
+	bool is_sge_valid = false;
 
 	if (!sched_is_energy_aware())
 		return 0;
@@ -248,6 +249,7 @@
 					sge_l0->cap_states[i].power);
 			}
 
+			is_sge_valid = true;
 			dev_info(&pdev->dev,
 				"cpu=%d eff=%d [freq=%ld cap=%ld power_d0=%ld] -> [freq=%ld cap=%ld power_d0=%ld]\n",
 				cpu, efficiency,
@@ -271,7 +273,8 @@
 
 	kfree(max_frequencies);
 
-	walt_sched_energy_populated_callback();
+	if (is_sge_valid)
+		walt_sched_energy_populated_callback();
 	dev_info(&pdev->dev, "Sched-energy-costs capacity updated\n");
 	return 0;
 
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 16f8124..5143801 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -115,6 +115,7 @@
 		return -ENOMEM;
 	runtime->substream = substream;
 	spin_lock_init(&runtime->lock);
+	mutex_init(&runtime->realloc_mutex);
 	init_waitqueue_head(&runtime->sleep);
 	INIT_WORK(&runtime->event_work, snd_rawmidi_input_event_work);
 	runtime->event = NULL;
@@ -636,8 +637,10 @@
 			      struct snd_rawmidi_params * params)
 {
 	char *newbuf;
+	char *oldbuf;
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
-	
+	unsigned long flags;
+
 	if (substream->append && substream->use_count > 1)
 		return -EBUSY;
 	snd_rawmidi_drain_output(substream);
@@ -648,13 +651,22 @@
 		return -EINVAL;
 	}
 	if (params->buffer_size != runtime->buffer_size) {
-		newbuf = krealloc(runtime->buffer, params->buffer_size,
+		mutex_lock(&runtime->realloc_mutex);
+		newbuf = __krealloc(runtime->buffer, params->buffer_size,
 				  GFP_KERNEL);
-		if (!newbuf)
+		if (!newbuf) {
+			mutex_unlock(&runtime->realloc_mutex);
 			return -ENOMEM;
+		}
+		spin_lock_irqsave(&runtime->lock, flags);
+		oldbuf = runtime->buffer;
 		runtime->buffer = newbuf;
 		runtime->buffer_size = params->buffer_size;
 		runtime->avail = runtime->buffer_size;
+		spin_unlock_irqrestore(&runtime->lock, flags);
+		if (oldbuf != newbuf)
+			kfree(oldbuf);
+		mutex_unlock(&runtime->realloc_mutex);
 	}
 	runtime->avail_min = params->avail_min;
 	substream->active_sensing = !params->no_active_sensing;
@@ -666,7 +678,9 @@
 			     struct snd_rawmidi_params * params)
 {
 	char *newbuf;
+	char *oldbuf;
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
+	unsigned long flags;
 
 	snd_rawmidi_drain_input(substream);
 	if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) {
@@ -676,12 +690,21 @@
 		return -EINVAL;
 	}
 	if (params->buffer_size != runtime->buffer_size) {
-		newbuf = krealloc(runtime->buffer, params->buffer_size,
+		mutex_lock(&runtime->realloc_mutex);
+		newbuf = __krealloc(runtime->buffer, params->buffer_size,
 				  GFP_KERNEL);
-		if (!newbuf)
+		if (!newbuf) {
+			mutex_unlock(&runtime->realloc_mutex);
 			return -ENOMEM;
+		}
+		spin_lock_irqsave(&runtime->lock, flags);
+		oldbuf = runtime->buffer;
 		runtime->buffer = newbuf;
 		runtime->buffer_size = params->buffer_size;
+		spin_unlock_irqrestore(&runtime->lock, flags);
+		if (oldbuf != newbuf)
+			kfree(oldbuf);
+		mutex_unlock(&runtime->realloc_mutex);
 	}
 	runtime->avail_min = params->avail_min;
 	return 0;
@@ -954,6 +977,8 @@
 	unsigned long appl_ptr;
 
 	spin_lock_irqsave(&runtime->lock, flags);
+	if (userbuf)
+		mutex_lock(&runtime->realloc_mutex);
 	while (count > 0 && runtime->avail) {
 		count1 = runtime->buffer_size - runtime->appl_ptr;
 		if (count1 > count)
@@ -973,6 +998,7 @@
 			spin_unlock_irqrestore(&runtime->lock, flags);
 			if (copy_to_user(userbuf + result,
 					 runtime->buffer + appl_ptr, count1)) {
+				mutex_unlock(&runtime->realloc_mutex);
 				return result > 0 ? result : -EFAULT;
 			}
 			spin_lock_irqsave(&runtime->lock, flags);
@@ -981,6 +1007,8 @@
 		count -= count1;
 	}
 	spin_unlock_irqrestore(&runtime->lock, flags);
+	if (userbuf)
+		mutex_unlock(&runtime->realloc_mutex);
 	return result;
 }
 
@@ -1245,10 +1273,14 @@
 		return -EINVAL;
 
 	result = 0;
+	if (userbuf)
+		mutex_lock(&runtime->realloc_mutex);
 	spin_lock_irqsave(&runtime->lock, flags);
 	if (substream->append) {
 		if ((long)runtime->avail < count) {
 			spin_unlock_irqrestore(&runtime->lock, flags);
+			if (userbuf)
+				mutex_unlock(&runtime->realloc_mutex);
 			return -EAGAIN;
 		}
 	}
@@ -1284,6 +1316,8 @@
       __end:
 	count1 = runtime->avail < runtime->buffer_size;
 	spin_unlock_irqrestore(&runtime->lock, flags);
+	if (userbuf)
+		mutex_unlock(&runtime->realloc_mutex);
 	if (count1)
 		snd_rawmidi_output_trigger(substream, 1);
 	return result;