Merge "msm: wlan: Update regulatory database for SA"
diff --git a/arch/arm/configs/msm8909-perf_defconfig b/arch/arm/configs/msm8909-perf_defconfig
index 3f8ba5f..b4ae846 100644
--- a/arch/arm/configs/msm8909-perf_defconfig
+++ b/arch/arm/configs/msm8909-perf_defconfig
@@ -258,6 +258,7 @@
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_QPNP_POWER_ON=y
+CONFIG_STMVL53L0X=y
 CONFIG_INPUT_UINPUT=y
 CONFIG_SERIAL_MSM_HS=y
 CONFIG_SERIAL_MSM_SMD=y
@@ -429,6 +430,8 @@
 CONFIG_WCNSS_CORE_PRONTO=y
 CONFIG_WCNSS_REGISTER_DUMP_ON_BITE=y
 CONFIG_CNSS_CRYPTO=y
+CONFIG_IIO=y
+CONFIG_INV_ICM20602_IIO=y
 CONFIG_PWM=y
 CONFIG_PWM_QPNP=y
 CONFIG_QTI_MPM=y
diff --git a/arch/arm/configs/msm8909_defconfig b/arch/arm/configs/msm8909_defconfig
index 009ead2..4d1bda0 100644
--- a/arch/arm/configs/msm8909_defconfig
+++ b/arch/arm/configs/msm8909_defconfig
@@ -308,11 +308,18 @@
 CONFIG_QPNP_LINEAR_CHARGER=y
 CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
 CONFIG_THERMAL=y
+CONFIG_THERMAL_WRITABLE_TRIPS=y
+CONFIG_THERMAL_GOV_USER_SPACE=y
+CONFIG_THERMAL_GOV_LOW_LIMITS=y
+CONFIG_CPU_THERMAL=y
+CONFIG_DEVFREQ_THERMAL=y
 CONFIG_THERMAL_QPNP=y
 CONFIG_THERMAL_QPNP_ADC_TM=y
 CONFIG_THERMAL_TSENS=y
 CONFIG_MSM_BCL_PERIPHERAL_CTL=y
 CONFIG_QTI_THERMAL_LIMITS_DCVS=y
+CONFIG_QTI_QMI_COOLING_DEVICE=y
+CONFIG_REGULATOR_COOLING_DEVICE=y
 CONFIG_MFD_QCOM_RPM=y
 CONFIG_MFD_SPMI_PMIC=y
 CONFIG_MFD_SYSCON=y
diff --git a/arch/arm/configs/msm8909w-perf_defconfig b/arch/arm/configs/msm8909w-perf_defconfig
index 3094af9..0e56f7f 100644
--- a/arch/arm/configs/msm8909w-perf_defconfig
+++ b/arch/arm/configs/msm8909w-perf_defconfig
@@ -448,6 +448,7 @@
 CONFIG_QTI_MPM=y
 CONFIG_ANDROID=y
 CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_BINDER_IPC_32BIT=y
 CONFIG_STM=y
 CONFIG_SENSORS_SSC=y
 CONFIG_MSM_TZ_LOG=y
diff --git a/arch/arm/configs/msm8909w_defconfig b/arch/arm/configs/msm8909w_defconfig
index 2abc5c0..8351322 100644
--- a/arch/arm/configs/msm8909w_defconfig
+++ b/arch/arm/configs/msm8909w_defconfig
@@ -440,6 +440,7 @@
 CONFIG_QTI_MPM=y
 CONFIG_ANDROID=y
 CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_BINDER_IPC_32BIT=y
 CONFIG_SENSORS_SSC=y
 CONFIG_MSM_TZ_LOG=y
 CONFIG_EXT4_FS=y
diff --git a/arch/arm64/boot/dts/qcom/sdm845-670-usb-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-670-usb-common.dtsi
index 9b88356..c53367a 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-670-usb-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-670-usb-common.dtsi
@@ -141,7 +141,9 @@
 			 0x198 /* PLL_BIAS_CONTROL_2 */
 			 0x228 /* QUSB2PHY_SQ_CTRL1 */
 			 0x22c /* QUSB2PHY_SQ_CTRL2 */
-			 0x27c>; /* QUSB2PHY_DEBUG_CTRL1 */
+			 0x27c /* QUSB2PHY_DEBUG_CTRL1 */
+			 0x280 /* QUSB2PHY_DEBUG_CTRL2 */
+			 0x2a0>; /* QUSB2PHY_STAT5 */
 
 		qcom,qusb-phy-init-seq =
 			/* <value reg_offset> */
@@ -431,7 +433,9 @@
 			 0x198 /* PLL_BIAS_CONTROL_2 */
 			 0x228 /* QUSB2PHY_SQ_CTRL1 */
 			 0x22c /* QUSB2PHY_SQ_CTRL2 */
-			 0x27c>; /* QUSB2PHY_DEBUG_CTRL1 */
+			 0x27c /* QUSB2PHY_DEBUG_CTRL1 */
+			 0x280 /* QUSB2PHY_DEBUG_CTRL2 */
+			 0x2a0>; /* QUSB2PHY_STAT5 */
 
 		qcom,qusb-phy-init-seq =
 			/* <value reg_offset> */
diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig
index 8004333..f3c1e7b 100644
--- a/arch/arm64/configs/msm8953-perf_defconfig
+++ b/arch/arm64/configs/msm8953-perf_defconfig
@@ -471,6 +471,7 @@
 CONFIG_USB_DWC3_MSM=y
 CONFIG_USB_SERIAL=y
 CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_USB_LINK_LAYER_TEST=y
 CONFIG_NOP_USB_XCEIV=y
 CONFIG_DUAL_ROLE_USB_INTF=y
 CONFIG_USB_MSM_SSPHY_QMP=y
diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig
index 3cc3576..8401173c 100644
--- a/arch/arm64/configs/msm8953_defconfig
+++ b/arch/arm64/configs/msm8953_defconfig
@@ -481,6 +481,7 @@
 CONFIG_USB_DWC3_MSM=y
 CONFIG_USB_SERIAL=y
 CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_USB_LINK_LAYER_TEST=y
 CONFIG_NOP_USB_XCEIV=y
 CONFIG_DUAL_ROLE_USB_INTF=y
 CONFIG_USB_MSM_SSPHY_QMP=y
diff --git a/drivers/android/Kconfig b/drivers/android/Kconfig
index 01de42c..bb2a5b5 100644
--- a/drivers/android/Kconfig
+++ b/drivers/android/Kconfig
@@ -32,9 +32,9 @@
 	  therefore logically separated from the other devices.
 
 config ANDROID_BINDER_IPC_32BIT
-	bool
+	bool "Android Binder IPC 32BIT Driver"
 	depends on !64BIT && ANDROID_BINDER_IPC
-	default y
+	default n
 	---help---
 	  The Binder API has been changed to support both 32 and 64bit
 	  applications in a mixed environment.
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index 8643667..19f2289 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -1,7 +1,7 @@
 /*
  * QTI Crypto Engine driver.
  *
- * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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
@@ -6118,13 +6118,15 @@
 int qce_close(void *handle)
 {
 	struct qce_device *pce_dev = (struct qce_device *) handle;
+	int ret = -1;
 
 	if (handle == NULL)
 		return -ENODEV;
 
 	mutex_lock(&qce_iomap_mutex);
-	qce_enable_clk(pce_dev);
-	qce_sps_exit(pce_dev);
+	ret = qce_enable_clk(pce_dev);
+	if (!ret)
+		qce_sps_exit(pce_dev);
 
 	if (pce_dev->iobase)
 		iounmap(pce_dev->iobase);
@@ -6137,7 +6139,8 @@
 	if (pce_dev->enable_s1_smmu)
 		qce_iommu_release_iomapping(pce_dev);
 
-	qce_disable_clk(pce_dev);
+	if (!ret)
+		qce_disable_clk(pce_dev);
 	__qce_deinit_clk(pce_dev);
 	mutex_unlock(&qce_iomap_mutex);
 	kfree(handle);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index d9839e7..a0a0daf 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1462,6 +1462,9 @@
 
 int dp_display_get_num_of_displays(void)
 {
+	if (!g_dp_display)
+		return 0;
+
 	return 1;
 }
 
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index 8af8298..cb4e82d 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -6189,6 +6189,7 @@
 	unsigned long flags;
 	bool found = false;
 	int ret, i = 0;
+	bool add_event = false;
 
 	crtc = to_sde_crtc(crtc_drm);
 	spin_lock_irqsave(&crtc->spin_lock, flags);
@@ -6238,11 +6239,24 @@
 		}
 
 		INIT_LIST_HEAD(&node->irq.list);
+
+		mutex_lock(&crtc->crtc_lock);
 		ret = node->func(crtc_drm, true, &node->irq);
+		if (!ret) {
+			spin_lock_irqsave(&crtc->spin_lock, flags);
+			list_add_tail(&node->list, &crtc->user_event_list);
+			add_event = true;
+			spin_unlock_irqrestore(&crtc->spin_lock, flags);
+		}
+		mutex_unlock(&crtc->crtc_lock);
+
 		sde_power_resource_enable(&priv->phandle, kms->core_client,
 				false);
 	}
 
+	if (add_event)
+		return 0;
+
 	if (!ret) {
 		spin_lock_irqsave(&crtc->spin_lock, flags);
 		list_add_tail(&node->list, &crtc->user_event_list);
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index 696b15c..ed0e7b8 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -2664,7 +2664,15 @@
 		SDE_DEBUG("info.is_connected = %s, info.is_primary = %s\n",
 			((info.is_connected) ? "true" : "false"),
 			((info.is_primary) ? "true" : "false"));
-		break;
+
+		/**
+		 * Since we are supporting one DSI for splash, use the display
+		 * which is marked as primary.
+		 */
+		if (!info.is_primary)
+			continue;
+		else
+			break;
 	}
 
 	if (!encoder) {
diff --git a/drivers/leds/leds-qpnp-wled.c b/drivers/leds/leds-qpnp-wled.c
index 861d987..d272ca6 100644
--- a/drivers/leds/leds-qpnp-wled.c
+++ b/drivers/leds/leds-qpnp-wled.c
@@ -22,6 +22,7 @@
 #include <linux/spmi.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/err.h>
 #include <linux/delay.h>
 #include <linux/leds-qpnp-wled.h>
@@ -420,6 +421,7 @@
 	bool			prev_state;
 	bool			stepper_en;
 	bool			ovp_irq_disabled;
+	bool			secure_mode;
 	bool			auto_calib_enabled;
 	bool			auto_calib_done;
 	bool			module_dis_perm;
@@ -936,6 +938,46 @@
 	return count;
 }
 
+/* sysfs function for irqs enable/disable */
+static ssize_t qpnp_wled_irq_control(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct qpnp_wled *wled = dev_get_drvdata(dev);
+	int val, rc;
+
+	rc = kstrtouint(buf, 0, &val);
+	if (rc < 0)
+		return rc;
+
+	if (val != 0 && val != 1)
+		return count;
+
+	mutex_lock(&wled->lock);
+	/* Disable irqs */
+	if (val == 1 && !wled->secure_mode) {
+		if (wled->ovp_irq > 0)
+			disable_irq(wled->ovp_irq);
+
+		if (wled->sc_irq > 0)
+			disable_irq(wled->sc_irq);
+
+		wled->secure_mode = true;
+	} else if (val == 0 && wled->secure_mode) {
+		if (wled->ovp_irq > 0)
+			enable_irq(wled->ovp_irq);
+
+		if (wled->sc_irq > 0)
+			enable_irq(wled->sc_irq);
+
+		wled->secure_mode = false;
+	}
+
+	mutex_unlock(&wled->lock);
+
+	return count;
+}
+
 /* sysfs show function for dim mode */
 static ssize_t qpnp_wled_dim_mode_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
@@ -1055,6 +1097,7 @@
 	__ATTR(ramp_ms, 0664, qpnp_wled_ramp_ms_show, qpnp_wled_ramp_ms_store),
 	__ATTR(ramp_step, 0664, qpnp_wled_ramp_step_show,
 		qpnp_wled_ramp_step_store),
+	__ATTR(secure_mode, 0664, NULL, qpnp_wled_irq_control),
 };
 
 /* worker for setting wled brightness */
@@ -1066,6 +1109,12 @@
 	wled = container_of(work, struct qpnp_wled, work);
 
 	mutex_lock(&wled->lock);
+
+	if (wled->secure_mode) {
+		pr_debug("Can not set brightness in secure_mode\n ");
+		goto unlock_mutex;
+	}
+
 	level = wled->cdev.brightness;
 
 	if (wled->brt_map_table) {
@@ -2162,6 +2211,7 @@
 
 	/* setup ovp and sc irqs */
 	if (wled->ovp_irq >= 0) {
+		irq_set_status_flags(wled->ovp_irq, IRQ_DISABLE_UNLAZY);
 		rc = devm_request_threaded_irq(&wled->pdev->dev, wled->ovp_irq,
 				NULL, qpnp_wled_ovp_irq_handler, IRQF_ONESHOT,
 				"qpnp_wled_ovp_irq", wled);
@@ -2182,6 +2232,7 @@
 
 	if (wled->sc_irq >= 0) {
 		wled->sc_cnt = 0;
+		irq_set_status_flags(wled->sc_irq, IRQ_DISABLE_UNLAZY);
 		rc = devm_request_threaded_irq(&wled->pdev->dev, wled->sc_irq,
 				NULL, qpnp_wled_sc_irq_handler, IRQF_ONESHOT,
 				"qpnp_wled_sc_irq", wled);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index 8a773e4..5bfb8e4 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -6205,15 +6205,17 @@
 		}
 		IPADBG("AP/USB SMMU atomic set\n");
 
-		if (iommu_domain_set_attr(cb->mapping->domain,
+		if (smmu_info.fast_map) {
+			if (iommu_domain_set_attr(cb->mapping->domain,
 				DOMAIN_ATTR_FAST,
 				&fast)) {
-			IPAERR("couldn't set fast map\n");
-			arm_iommu_release_mapping(cb->mapping);
-			cb->valid = false;
-			return -EIO;
+				IPAERR("couldn't set fast map\n");
+				arm_iommu_release_mapping(cb->mapping);
+				cb->valid = false;
+				return -EIO;
+			}
+			IPADBG("SMMU fast map set\n");
 		}
-		IPADBG("SMMU fast map set\n");
 	}
 
 	pr_info("IPA smmu_info.s1_bypass_arr[AP]=%d smmu_info.fast_map=%d\n",
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
index 7065e2c..2716d4a 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
@@ -1516,6 +1516,8 @@
 			ipa3_ctx->nat_mem.pdn_mem.size,
 			ipa3_ctx->nat_mem.pdn_mem.base,
 			ipa3_ctx->nat_mem.pdn_mem.phys_base);
+		ipa3_ctx->nat_mem.pdn_mem.base = NULL;
+		ipa3_ctx->nat_mem.dev.is_mem_allocated = false;
 	}
 
 	ipa3_nat_ipv6ct_free_mem(&ipa3_ctx->nat_mem.dev);
diff --git a/drivers/platform/msm/mhi_dev/mhi.h b/drivers/platform/msm/mhi_dev/mhi.h
index 26baa64..6cb2d7d 100644
--- a/drivers/platform/msm/mhi_dev/mhi.h
+++ b/drivers/platform/msm/mhi_dev/mhi.h
@@ -14,9 +14,8 @@
 #define __MHI_H
 
 #include <linux/msm_ep_pcie.h>
-#include <linux/types.h>
 #include <linux/ipc_logging.h>
-#include <linux/dma-mapping.h>
+#include <linux/msm_mhi_dev.h>
 
 /**
  * MHI control data structures alloted by the host, including
@@ -276,8 +275,6 @@
 #define MHI_MASK_ROWS_CH_EV_DB		4
 #define TRB_MAX_DATA_SIZE		8192
 #define MHI_CTRL_STATE			100
-#define IPA_DMA_SYNC                    1
-#define IPA_DMA_ASYNC                   0
 
 /*maximum trasnfer completion events buffer*/
 #define MAX_TR_EVENTS			50
@@ -360,13 +357,6 @@
 	MHI_DEV_POLL,
 };
 
-enum mhi_ctrl_info {
-	MHI_STATE_CONFIGURED = 0,
-	MHI_STATE_CONNECTED = 1,
-	MHI_STATE_DISCONNECTED = 2,
-	MHI_STATE_INVAL,
-};
-
 enum mhi_dev_tr_compl_evt_type {
 	SEND_EVENT_BUFFER,
 	SEND_EVENT_RD_OFFSET,
@@ -420,38 +410,6 @@
 
 #define MHI_DEV_MMIO_RANGE			0xc80
 
-enum cb_reason {
-	MHI_DEV_TRE_AVAILABLE = 0,
-	MHI_DEV_CTRL_UPDATE,
-};
-
-struct mhi_dev_client_cb_reason {
-	uint32_t		ch_id;
-	enum cb_reason		reason;
-};
-
-struct mhi_dev_client {
-	struct list_head		list;
-	struct mhi_dev_channel		*channel;
-	void (*event_trigger)(struct mhi_dev_client_cb_reason *cb);
-
-	/* mhi_dev calls are fully synchronous -- only one call may be
-	 * active per client at a time for now.
-	 */
-	struct mutex			write_lock;
-	wait_queue_head_t		wait;
-
-	/* trace logs */
-	spinlock_t			tr_lock;
-	unsigned int			tr_head;
-	unsigned int			tr_tail;
-	struct mhi_dev_trace		*tr_log;
-
-	/* client buffers */
-	struct mhi_dev_iov		*iov;
-	uint32_t			nr_iov;
-};
-
 struct ring_cache_req {
 	struct completion	*done;
 	void			*context;
@@ -609,32 +567,15 @@
 	/* MHI state info */
 	enum mhi_ctrl_info		ctrl_info;
 
-	/*Register for interrupt */
+	/*Register for interrupt*/
 	bool				mhi_int;
 	bool				mhi_int_en;
-
 	/* Registered client callback list */
 	struct list_head		client_cb_list;
 
 	struct kobj_uevent_env		kobj_env;
 };
 
-struct mhi_req {
-	u32                             chan;
-	u32                             mode;
-	u32				chain;
-	void                            *buf;
-	dma_addr_t                      dma;
-	u32                             snd_cmpl;
-	void                            *context;
-	size_t                          len;
-	size_t                          actual_len;
-	uint32_t                        rd_offset;
-	struct mhi_dev_client           *client;
-	struct list_head                list;
-	union mhi_dev_ring_element_type *el;
-	void (*client_cb)(void *req);
-};
 
 enum mhi_msg_level {
 	MHI_MSG_VERBOSE = 0x0,
@@ -660,70 +601,8 @@
 	} \
 } while (0)
 
-/* SW channel client list */
-enum mhi_client_channel {
-	MHI_CLIENT_LOOPBACK_OUT = 0,
-	MHI_CLIENT_LOOPBACK_IN = 1,
-	MHI_CLIENT_SAHARA_OUT = 2,
-	MHI_CLIENT_SAHARA_IN = 3,
-	MHI_CLIENT_DIAG_OUT = 4,
-	MHI_CLIENT_DIAG_IN = 5,
-	MHI_CLIENT_SSR_OUT = 6,
-	MHI_CLIENT_SSR_IN = 7,
-	MHI_CLIENT_QDSS_OUT = 8,
-	MHI_CLIENT_QDSS_IN = 9,
-	MHI_CLIENT_EFS_OUT = 10,
-	MHI_CLIENT_EFS_IN = 11,
-	MHI_CLIENT_MBIM_OUT = 12,
-	MHI_CLIENT_MBIM_IN = 13,
-	MHI_CLIENT_QMI_OUT = 14,
-	MHI_CLIENT_QMI_IN = 15,
-	MHI_CLIENT_IP_CTRL_0_OUT = 16,
-	MHI_CLIENT_IP_CTRL_0_IN = 17,
-	MHI_CLIENT_IP_CTRL_1_OUT = 18,
-	MHI_CLIENT_IP_CTRL_1_IN = 19,
-	MHI_CLIENT_DCI_OUT = 20,
-	MHI_CLIENT_DCI_IN = 21,
-	MHI_CLIENT_IP_CTRL_3_OUT = 22,
-	MHI_CLIENT_IP_CTRL_3_IN = 23,
-	MHI_CLIENT_IP_CTRL_4_OUT = 24,
-	MHI_CLIENT_IP_CTRL_4_IN = 25,
-	MHI_CLIENT_IP_CTRL_5_OUT = 26,
-	MHI_CLIENT_IP_CTRL_5_IN = 27,
-	MHI_CLIENT_IP_CTRL_6_OUT = 28,
-	MHI_CLIENT_IP_CTRL_6_IN = 29,
-	MHI_CLIENT_IP_CTRL_7_OUT = 30,
-	MHI_CLIENT_IP_CTRL_7_IN = 31,
-	MHI_CLIENT_DUN_OUT = 32,
-	MHI_CLIENT_DUN_IN = 33,
-	MHI_CLIENT_IP_SW_0_OUT = 34,
-	MHI_CLIENT_IP_SW_0_IN = 35,
-	MHI_CLIENT_ADB_OUT = 36,
-	MHI_CLIENT_ADB_IN = 37,
-	MHI_CLIENT_IP_SW_2_OUT = 38,
-	MHI_CLIENT_IP_SW_2_IN = 39,
-	MHI_CLIENT_IP_SW_3_OUT = 40,
-	MHI_CLIENT_IP_SW_3_IN = 41,
-	MHI_CLIENT_CSVT_OUT = 42,
-	MHI_CLIENT_CSVT_IN = 43,
-	MHI_CLIENT_SMCT_OUT = 44,
-	MHI_CLIENT_SMCT_IN = 45,
-	MHI_CLIENT_IP_SW_4_OUT  = 46,
-	MHI_CLIENT_IP_SW_4_IN  = 47,
-	MHI_MAX_SOFTWARE_CHANNELS,
-	MHI_CLIENT_TEST_OUT = 60,
-	MHI_CLIENT_TEST_IN = 61,
-	MHI_CLIENT_RESERVED_1_LOWER = 62,
-	MHI_CLIENT_RESERVED_1_UPPER = 99,
-	MHI_CLIENT_IP_HW_0_OUT = 100,
-	MHI_CLIENT_IP_HW_0_IN = 101,
-	MHI_CLIENT_RESERVED_2_LOWER = 102,
-	MHI_CLIENT_RESERVED_2_UPPER = 127,
-	MHI_MAX_CHANNELS = 102,
-	MHI_CLIENT_INVALID = 0xFFFFFFFF
-};
 
-/* Use ID 0 for legacy /dev/mhi_ctrl. Channel 0 is used for internal only */
+/* Use ID 0 for legacy /dev/mhi_ctrl. Channel 0 used for internal only */
 #define MHI_DEV_UEVENT_CTRL	0
 
 struct mhi_dev_uevent_info {
@@ -736,58 +615,6 @@
 	uint32_t	buf_size;
 };
 
-struct mhi_dev_client_cb_data {
-	void			*user_data;
-	enum mhi_client_channel	channel;
-	enum mhi_ctrl_info	ctrl_info;
-};
-
-typedef void (*mhi_state_cb)(struct mhi_dev_client_cb_data *cb_dat);
-
-struct mhi_dev_ready_cb_info {
-	struct list_head		list;
-	mhi_state_cb			cb;
-	struct mhi_dev_client_cb_data	cb_data;
-};
-
-/**
- * mhi_dev_open_channel() - Channel open for a given client done prior
- *		to read/write.
- * @chan_id:	Software Channel ID for the assigned client.
- * @handle_client: Structure device for client handle.
- * @notifier: Client issued callback notification.
- */
-int mhi_dev_open_channel(uint32_t chan_id,
-		struct mhi_dev_client **handle_client,
-		void (*event_trigger)(struct mhi_dev_client_cb_reason *cb));
-/**
- * mhi_dev_close_channel() - Channel close for a given client.
- */
-int mhi_dev_close_channel(struct mhi_dev_client *handle_client);
-
-/**
- * mhi_dev_read_channel() - Channel read for a given client
- * @mreq:       mreq is the client argument which includes meta info
- *              like write data location, buffer len, read offset, mode,
- *              chain and client call back function which will be invoked
- *              when data read is completed.
- */
-int mhi_dev_read_channel(struct mhi_req *mreq);
-
-/**
- * mhi_dev_write_channel() - Channel write for a given software client.
- * @wreq	wreq is the client argument which includes meta info like
- *              client handle, read data location, buffer length, mode,
- *              and client call back function which will free the packet.
- *              when data write is completed.
- */
-int mhi_dev_write_channel(struct mhi_req *wreq);
-
-/**
- * mhi_dev_channel_isempty() - Checks if there is any pending TRE's to process.
- * @handle_client:	Client Handle issued during mhi_dev_open_channel
- */
-int mhi_dev_channel_isempty(struct mhi_dev_client *handle);
 
 struct mhi_dev_trace {
 	unsigned int timestamp;
@@ -1065,7 +892,7 @@
 int mhi_dev_mmio_enable_erdb_interrupts(struct mhi_dev *dev);
 
 /**
- * mhi_dev_mmio_mask_erdb_interrupts() - Mask all Event doorbell
+ *mhi_dev_mmio_mask_erdb_interrupts() - Mask all Event doorbell
  *		interrupts.
  * @dev:	MHI device structure.
  */
@@ -1256,43 +1083,8 @@
  */
 int mhi_dev_net_interface_init(void);
 
-/**
- * mhi_dev_net_exit() - Clean up and close MHI Network interface module.
- */
-void mhi_dev_net_exit(void);
-
-/**
- * mhi_dev_notify_a7_event() - Used by PCIe driver to notify A7 MHI device
- *	interrupt after doorbell is received. Used by PCIe driver when MHI
- *	A7 interrupts are routed to PCIe instead of MHI device.
- */
 void mhi_dev_notify_a7_event(struct mhi_dev *mhi);
 
-/**
- * mhi_ctrl_state_info() - Provide MHI state info
- *		@idx: Channel number idx. Look at channel_state_info and
- *		pass the index for the corresponding channel.
- *		@info: Return the control info.
- *		MHI_STATE=CONFIGURED - MHI device is present but not ready
- *					for data traffic.
- *		MHI_STATE=CONNECTED - MHI device is ready for data transfer.
- *		MHI_STATE=DISCONNECTED - MHI device has its pipes suspended.
- *		exposes device nodes for the supported MHI software
- *		channels.
- */
-int mhi_ctrl_state_info(uint32_t idx, uint32_t *info);
-
-/**
- * uci_ctrl_update() - Update UCI once TRE's are available for clients to
- *			consume.
- */
 void uci_ctrl_update(struct mhi_dev_client_cb_reason *reason);
 
-/**
- * mhi_register_state_cb() - Clients can register and receive callback after
- *		MHI channel is connected or disconnected.
- */
-int mhi_register_state_cb(void (*mhi_state_cb)
-			(struct mhi_dev_client_cb_data *cb_data), void *data,
-			enum mhi_client_channel channel);
-#endif /* _MHI_H_ */
+#endif /* _MHI_H */
diff --git a/drivers/platform/msm/mhi_dev/mhi_sm.h b/drivers/platform/msm/mhi_dev/mhi_sm.h
index 01e127b..4b9307d 100644
--- a/drivers/platform/msm/mhi_dev/mhi_sm.h
+++ b/drivers/platform/msm/mhi_dev/mhi_sm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015,2017-2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015,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
diff --git a/drivers/regulator/qpnp-labibb-regulator.c b/drivers/regulator/qpnp-labibb-regulator.c
index 88c5697..d72af20 100644
--- a/drivers/regulator/qpnp-labibb-regulator.c
+++ b/drivers/regulator/qpnp-labibb-regulator.c
@@ -597,6 +597,7 @@
 	struct device			*dev;
 	struct platform_device		*pdev;
 	struct regmap			*regmap;
+	struct class			labibb_class;
 	struct pmic_revid_data		*pmic_rev_id;
 	u16				lab_base;
 	u16				ibb_base;
@@ -624,6 +625,8 @@
 	bool				notify_lab_vreg_ok_sts;
 	bool				detect_lab_sc;
 	bool				sc_detected;
+	 /* Tracks the secure UI mode entry/exit */
+	bool				secure_mode;
 	u32				swire_2nd_cmd_delay;
 	u32				swire_ibb_ps_enable_delay;
 };
@@ -2463,6 +2466,9 @@
 	int rc;
 	struct qpnp_labibb *labibb  = rdev_get_drvdata(rdev);
 
+	if (labibb->secure_mode)
+		return 0;
+
 	if (labibb->sc_detected) {
 		pr_info("Short circuit detected: disabled LAB/IBB rails\n");
 		return 0;
@@ -2500,6 +2506,9 @@
 	u8 val;
 	struct qpnp_labibb *labibb  = rdev_get_drvdata(rdev);
 
+	if (labibb->secure_mode)
+		return 0;
+
 	if (labibb->lab_vreg.vreg_enabled && !labibb->swire_control) {
 
 		if (!labibb->standalone)
@@ -2693,7 +2702,7 @@
 	u8 val;
 	struct qpnp_labibb *labibb = rdev_get_drvdata(rdev);
 
-	if (labibb->swire_control)
+	if (labibb->swire_control || labibb->secure_mode)
 		return 0;
 
 	if (min_uV < labibb->lab_vreg.min_volt) {
@@ -3072,6 +3081,8 @@
 	}
 
 	if (is_lab_vreg_ok_irq_available(labibb)) {
+		irq_set_status_flags(labibb->lab_vreg.lab_vreg_ok_irq,
+				     IRQ_DISABLE_UNLAZY);
 		rc = devm_request_threaded_irq(labibb->dev,
 				labibb->lab_vreg.lab_vreg_ok_irq, NULL,
 				lab_vreg_ok_handler,
@@ -3085,6 +3096,8 @@
 	}
 
 	if (labibb->lab_vreg.lab_sc_irq != -EINVAL) {
+		irq_set_status_flags(labibb->lab_vreg.lab_sc_irq,
+				     IRQ_DISABLE_UNLAZY);
 		rc = devm_request_threaded_irq(labibb->dev,
 				labibb->lab_vreg.lab_sc_irq, NULL,
 				labibb_sc_err_handler,
@@ -3568,6 +3581,9 @@
 	int rc = 0;
 	struct qpnp_labibb *labibb  = rdev_get_drvdata(rdev);
 
+	if (labibb->secure_mode)
+		return 0;
+
 	if (labibb->sc_detected) {
 		pr_info("Short circuit detected: disabled LAB/IBB rails\n");
 		return 0;
@@ -3593,6 +3609,9 @@
 	int rc;
 	struct qpnp_labibb *labibb  = rdev_get_drvdata(rdev);
 
+	if (labibb->secure_mode)
+		return 0;
+
 	if (labibb->ibb_vreg.vreg_enabled && !labibb->swire_control) {
 
 		if (!labibb->standalone)
@@ -3626,7 +3645,7 @@
 
 	struct qpnp_labibb *labibb = rdev_get_drvdata(rdev);
 
-	if (labibb->swire_control)
+	if (labibb->swire_control || labibb->secure_mode)
 		return 0;
 
 	rc = labibb->ibb_ver_ops->set_voltage(labibb, min_uV, max_uV);
@@ -3855,6 +3874,8 @@
 	}
 
 	if (labibb->ibb_vreg.ibb_sc_irq != -EINVAL) {
+		irq_set_status_flags(labibb->ibb_vreg.ibb_sc_irq,
+				     IRQ_DISABLE_UNLAZY);
 		rc = devm_request_threaded_irq(labibb->dev,
 				labibb->ibb_vreg.ibb_sc_irq, NULL,
 				labibb_sc_err_handler,
@@ -4016,6 +4037,49 @@
 	return rc;
 }
 
+static ssize_t qpnp_labibb_irq_control(struct class *c,
+				       struct class_attribute *attr,
+				       const char *buf, size_t count)
+{
+	struct qpnp_labibb *labibb = container_of(c, struct qpnp_labibb,
+						  labibb_class);
+	int val, rc;
+
+	rc = kstrtouint(buf, 0, &val);
+	if (rc < 0)
+		return rc;
+
+	if (val != 0 && val != 1)
+		return count;
+
+	/* Disable irqs */
+	if (val == 1 && !labibb->secure_mode) {
+		if (labibb->lab_vreg.lab_vreg_ok_irq > 0)
+			disable_irq(labibb->lab_vreg.lab_vreg_ok_irq);
+		if (labibb->lab_vreg.lab_sc_irq > 0)
+			disable_irq(labibb->lab_vreg.lab_sc_irq);
+		if (labibb->ibb_vreg.ibb_sc_irq > 0)
+			disable_irq(labibb->ibb_vreg.ibb_sc_irq);
+		labibb->secure_mode = true;
+	} else if (val == 0 && labibb->secure_mode) {
+		if (labibb->lab_vreg.lab_vreg_ok_irq > 0)
+			enable_irq(labibb->lab_vreg.lab_vreg_ok_irq);
+		if (labibb->lab_vreg.lab_sc_irq > 0)
+			enable_irq(labibb->lab_vreg.lab_sc_irq);
+		if (labibb->ibb_vreg.ibb_sc_irq > 0)
+			enable_irq(labibb->ibb_vreg.ibb_sc_irq);
+		labibb->secure_mode = false;
+	}
+
+	return count;
+}
+
+static struct class_attribute labibb_attributes[] = {
+	[0] = __ATTR(secure_mode, 0664, NULL,
+			 qpnp_labibb_irq_control),
+	 __ATTR_NULL,
+};
+
 static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
 {
 	struct qpnp_labibb *labibb;
@@ -4208,6 +4272,17 @@
 			CLOCK_MONOTONIC, HRTIMER_MODE_REL);
 	labibb->sc_err_check_timer.function = labibb_check_sc_err_count;
 	dev_set_drvdata(&pdev->dev, labibb);
+
+	labibb->labibb_class.name = "lcd_bias";
+	labibb->labibb_class.owner = THIS_MODULE;
+	labibb->labibb_class.class_attrs = labibb_attributes;
+
+	rc = class_register(&labibb->labibb_class);
+	if (rc < 0) {
+		pr_err("Failed to register labibb class rc=%d\n", rc);
+		return rc;
+	}
+
 	pr_info("LAB/IBB registered successfully, lab_vreg enable=%d ibb_vreg enable=%d swire_control=%d\n",
 						labibb->lab_vreg.vreg_enabled,
 						labibb->ibb_vreg.vreg_enabled,
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 0963aa3..10ae7eb 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -256,6 +256,7 @@
 #define DWC3_GUSB3PIPECTL_DISRXDETINP3	(1 << 28)
 #define DWC3_GUSB3PIPECTL_UX_EXIT_PX	(1 << 27)
 #define DWC3_GUSB3PIPECTL_REQP1P2P3	(1 << 24)
+#define DWC3_GUSB3PIPECTL_DISRXDETU3	(1 << 22)
 #define DWC3_GUSB3PIPECTL_DEP1P2P3(n)	((n) << 19)
 #define DWC3_GUSB3PIPECTL_DEP1P2P3_MASK	DWC3_GUSB3PIPECTL_DEP1P2P3(7)
 #define DWC3_GUSB3PIPECTL_DEP1P2P3_EN	DWC3_GUSB3PIPECTL_DEP1P2P3(1)
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index f99b2bd..9bcfa38 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -2347,6 +2347,12 @@
 
 	/* Suspend SS PHY */
 	if (dwc->maximum_speed == USB_SPEED_SUPER) {
+		if (mdwc->in_host_mode) {
+			u32 reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
+
+			reg |= DWC3_GUSB3PIPECTL_DISRXDETU3;
+			dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
+		}
 		/* indicate phy about SS mode */
 		if (dwc3_msm_is_superspeed(mdwc))
 			mdwc->ss_phy->flags |= DEVICE_IN_SS_MODE;
@@ -2531,6 +2537,13 @@
 		usb_phy_set_suspend(mdwc->ss_phy, 0);
 		mdwc->ss_phy->flags &= ~DEVICE_IN_SS_MODE;
 		mdwc->lpm_flags &= ~MDWC3_SS_PHY_SUSPEND;
+
+		if (mdwc->in_host_mode) {
+			u32 reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
+
+			reg &= ~DWC3_GUSB3PIPECTL_DISRXDETU3;
+			dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
+		}
 	}
 
 	mdwc->hs_phy->flags &= ~(PHY_HSFS_MODE | PHY_LS_MODE);
diff --git a/drivers/usb/phy/phy-msm-qusb-v2.c b/drivers/usb/phy/phy-msm-qusb-v2.c
index 6dfca9c..a17974c 100644
--- a/drivers/usb/phy/phy-msm-qusb-v2.c
+++ b/drivers/usb/phy/phy-msm-qusb-v2.c
@@ -76,6 +76,12 @@
 /* PERIPH_SS_PHY_REFGEN_NORTH_BG_CTRL register bits */
 #define BANDGAP_BYPASS			BIT(0)
 
+/* DEBUG_CTRL2 register value to program VSTATUS MUX for PHY status */
+#define DEBUG_CTRL2_MUX_PLL_LOCK_STATUS	0x4
+
+/* STAT5 register bits */
+#define VSTATUS_PLL_LOCK_STATUS_MASK	BIT(0)
+
 enum qusb_phy_reg {
 	PORT_TUNE1,
 	PLL_COMMON_STATUS_ONE,
@@ -87,6 +93,8 @@
 	SQ_CTRL1,
 	SQ_CTRL2,
 	DEBUG_CTRL1,
+	DEBUG_CTRL2,
+	STAT5,
 	USB2_PHY_REG_MAX,
 };
 
@@ -470,6 +478,18 @@
 							__func__);
 }
 
+static bool qusb_phy_pll_locked(struct qusb_phy *qphy)
+{
+	u32 val;
+
+	writel_relaxed(DEBUG_CTRL2_MUX_PLL_LOCK_STATUS,
+		       qphy->base + qphy->phy_reg[DEBUG_CTRL2]);
+
+	val = readl_relaxed(qphy->base + qphy->phy_reg[STAT5]);
+
+	return (val & VSTATUS_PLL_LOCK_STATUS_MASK);
+}
+
 static void qusb_phy_host_init(struct usb_phy *phy)
 {
 	u8 reg;
@@ -748,18 +768,12 @@
 			writel_relaxed(intr_mask,
 				qphy->base + qphy->phy_reg[INTR_CTRL]);
 
-			/* hold core PLL into reset */
-			writel_relaxed(CORE_PLL_EN_FROM_RESET |
-				CORE_RESET | CORE_RESET_MUX,
-				qphy->base +
-				qphy->phy_reg[PLL_CORE_INPUT_OVERRIDE]);
-
 			if (linestate & (LINESTATE_DP | LINESTATE_DM)) {
 				/* enable phy auto-resume */
 				writel_relaxed(0x91,
 					qphy->base + qphy->phy_reg[TEST1]);
-				/* flush the previous write before next write */
-				wmb();
+				/* Delay recommended between TEST1 writes */
+				usleep_range(10, 20);
 				writel_relaxed(0x90,
 					qphy->base + qphy->phy_reg[TEST1]);
 			}
@@ -788,12 +802,26 @@
 			writel_relaxed(0x00,
 				qphy->base + qphy->phy_reg[INTR_CTRL]);
 
-			/* bring core PLL out of reset */
-			writel_relaxed(CORE_PLL_EN_FROM_RESET, qphy->base +
-				qphy->phy_reg[PLL_CORE_INPUT_OVERRIDE]);
+			/* Reset PLL if needed */
+			if (!qusb_phy_pll_locked(qphy)) {
+				dev_dbg(phy->dev, "%s: reset PLL\n", __func__);
+				/* hold core PLL into reset */
+				writel_relaxed(CORE_PLL_EN_FROM_RESET |
+					CORE_RESET | CORE_RESET_MUX,
+					qphy->base +
+					qphy->phy_reg[PLL_CORE_INPUT_OVERRIDE]);
 
-			/* Makes sure that above write goes through */
-			wmb();
+				/* Wait for PLL to get reset */
+				usleep_range(10, 20);
+
+				/* bring core PLL out of reset */
+				writel_relaxed(CORE_PLL_EN_FROM_RESET,
+					qphy->base +
+					qphy->phy_reg[PLL_CORE_INPUT_OVERRIDE]);
+
+				/* Makes sure that above write goes through */
+				wmb();
+			}
 		} else { /* Cable connect case */
 			qusb_phy_enable_clocks(qphy, true);
 		}
diff --git a/drivers/video/fbdev/msm/mdss_mdp_debug.c b/drivers/video/fbdev/msm/mdss_mdp_debug.c
index bd4ee23..e7bd94a 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_debug.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_debug.c
@@ -1140,7 +1140,7 @@
 	struct mdss_mdp_pipe *pipe;
 	int i, cnt = 0;
 
-	if (!mixer)
+	if (!mixer || !mfd)
 		return;
 
 	seq_printf(s, "\n%s Mixer #%d  res=%dx%d roi[%d, %d, %d, %d] %s\n",
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
index 947a3fe..0ffe89c 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
@@ -1677,6 +1677,11 @@
 
 		/* re-assign to have the correct order in the context */
 		ctx = (struct mdss_mdp_cmd_ctx *) ctl->intf_ctx[MASTER_CTX];
+		if (!sctl) {
+			pr_err("invalid sctl\n");
+			goto exit;
+		}
+
 		sctx = (struct mdss_mdp_cmd_ctx *) sctl->intf_ctx[MASTER_CTX];
 		if (!ctx || !sctx) {
 			pr_err("invalid %s %s\n",
@@ -1784,6 +1789,11 @@
 
 		/* re-assign to have the correct order in the context */
 		ctx = (struct mdss_mdp_cmd_ctx *) ctl->intf_ctx[MASTER_CTX];
+		if (!sctl) {
+			pr_err("invalid sctl\n");
+			goto exit;
+		}
+
 		sctx = (struct mdss_mdp_cmd_ctx *) sctl->intf_ctx[MASTER_CTX];
 		if (!ctx || !sctx) {
 			pr_err("%s ERROR invalid %s %s\n", __func__,
diff --git a/include/linux/msm_mhi_dev.h b/include/linux/msm_mhi_dev.h
new file mode 100644
index 0000000..b96591b
--- /dev/null
+++ b/include/linux/msm_mhi_dev.h
@@ -0,0 +1,259 @@
+/* Copyright (c) 2015-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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MSM_MHI_DEV_H
+#define __MSM_MHI_DEV_H
+
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+
+#define IPA_DMA_SYNC                    1
+#define IPA_DMA_ASYNC                   0
+
+enum cb_reason {
+	MHI_DEV_TRE_AVAILABLE = 0,
+	MHI_DEV_CTRL_UPDATE,
+};
+
+struct mhi_dev_client_cb_reason {
+	uint32_t		ch_id;
+	enum cb_reason		reason;
+};
+
+struct mhi_dev_client {
+	struct list_head		list;
+	struct mhi_dev_channel		*channel;
+	void (*event_trigger)(struct mhi_dev_client_cb_reason *cb);
+
+	/* mhi_dev calls are fully synchronous -- only one call may be
+	 * active per client at a time for now.
+	 */
+	struct mutex			write_lock;
+	wait_queue_head_t		wait;
+
+	/* trace logs */
+	spinlock_t			tr_lock;
+	unsigned int			tr_head;
+	unsigned int			tr_tail;
+	struct mhi_dev_trace		*tr_log;
+
+	/* client buffers */
+	struct mhi_dev_iov		*iov;
+	uint32_t			nr_iov;
+};
+
+enum mhi_ctrl_info {
+	MHI_STATE_CONFIGURED = 0,
+	MHI_STATE_CONNECTED = 1,
+	MHI_STATE_DISCONNECTED = 2,
+	MHI_STATE_INVAL,
+};
+
+struct mhi_req {
+	u32                             chan;
+	u32                             mode;
+	u32				chain;
+	void                            *buf;
+	dma_addr_t                      dma;
+	u32                             snd_cmpl;
+	void                            *context;
+	size_t                          len;
+	size_t                          actual_len;
+	uint32_t                        rd_offset;
+	struct mhi_dev_client           *client;
+	struct list_head                list;
+	union mhi_dev_ring_element_type *el;
+	void (*client_cb)(void *req);
+};
+
+/* SW channel client list */
+enum mhi_client_channel {
+	MHI_CLIENT_LOOPBACK_OUT = 0,
+	MHI_CLIENT_LOOPBACK_IN = 1,
+	MHI_CLIENT_SAHARA_OUT = 2,
+	MHI_CLIENT_SAHARA_IN = 3,
+	MHI_CLIENT_DIAG_OUT = 4,
+	MHI_CLIENT_DIAG_IN = 5,
+	MHI_CLIENT_SSR_OUT = 6,
+	MHI_CLIENT_SSR_IN = 7,
+	MHI_CLIENT_QDSS_OUT = 8,
+	MHI_CLIENT_QDSS_IN = 9,
+	MHI_CLIENT_EFS_OUT = 10,
+	MHI_CLIENT_EFS_IN = 11,
+	MHI_CLIENT_MBIM_OUT = 12,
+	MHI_CLIENT_MBIM_IN = 13,
+	MHI_CLIENT_QMI_OUT = 14,
+	MHI_CLIENT_QMI_IN = 15,
+	MHI_CLIENT_IP_CTRL_0_OUT = 16,
+	MHI_CLIENT_IP_CTRL_0_IN = 17,
+	MHI_CLIENT_IP_CTRL_1_OUT = 18,
+	MHI_CLIENT_IP_CTRL_1_IN = 19,
+	MHI_CLIENT_DCI_OUT = 20,
+	MHI_CLIENT_DCI_IN = 21,
+	MHI_CLIENT_IP_CTRL_3_OUT = 22,
+	MHI_CLIENT_IP_CTRL_3_IN = 23,
+	MHI_CLIENT_IP_CTRL_4_OUT = 24,
+	MHI_CLIENT_IP_CTRL_4_IN = 25,
+	MHI_CLIENT_IP_CTRL_5_OUT = 26,
+	MHI_CLIENT_IP_CTRL_5_IN = 27,
+	MHI_CLIENT_IP_CTRL_6_OUT = 28,
+	MHI_CLIENT_IP_CTRL_6_IN = 29,
+	MHI_CLIENT_IP_CTRL_7_OUT = 30,
+	MHI_CLIENT_IP_CTRL_7_IN = 31,
+	MHI_CLIENT_DUN_OUT = 32,
+	MHI_CLIENT_DUN_IN = 33,
+	MHI_CLIENT_IP_SW_0_OUT = 34,
+	MHI_CLIENT_IP_SW_0_IN = 35,
+	MHI_CLIENT_ADB_OUT = 36,
+	MHI_CLIENT_ADB_IN = 37,
+	MHI_CLIENT_IP_SW_2_OUT = 38,
+	MHI_CLIENT_IP_SW_2_IN = 39,
+	MHI_CLIENT_IP_SW_3_OUT = 40,
+	MHI_CLIENT_IP_SW_3_IN = 41,
+	MHI_CLIENT_CSVT_OUT = 42,
+	MHI_CLIENT_CSVT_IN = 43,
+	MHI_CLIENT_SMCT_OUT = 44,
+	MHI_CLIENT_SMCT_IN = 45,
+	MHI_CLIENT_IP_SW_4_OUT  = 46,
+	MHI_CLIENT_IP_SW_4_IN  = 47,
+	MHI_MAX_SOFTWARE_CHANNELS,
+	MHI_CLIENT_TEST_OUT = 60,
+	MHI_CLIENT_TEST_IN = 61,
+	MHI_CLIENT_RESERVED_1_LOWER = 62,
+	MHI_CLIENT_RESERVED_1_UPPER = 99,
+	MHI_CLIENT_IP_HW_0_OUT = 100,
+	MHI_CLIENT_IP_HW_0_IN = 101,
+	MHI_CLIENT_RESERVED_2_LOWER = 102,
+	MHI_CLIENT_RESERVED_2_UPPER = 127,
+	MHI_MAX_CHANNELS = 102,
+	MHI_CLIENT_INVALID = 0xFFFFFFFF
+};
+
+struct mhi_dev_client_cb_data {
+	void			*user_data;
+	enum mhi_client_channel	channel;
+	enum mhi_ctrl_info	ctrl_info;
+};
+
+typedef void (*mhi_state_cb)(struct mhi_dev_client_cb_data *cb_dat);
+
+struct mhi_dev_ready_cb_info {
+	struct list_head		list;
+	mhi_state_cb			cb;
+	struct mhi_dev_client_cb_data	cb_data;
+};
+
+#if defined(CONFIG_MSM_MHI_DEV)
+/**
+ * mhi_dev_open_channel() - Channel open for a given client done prior
+ *		to read/write.
+ * @chan_id:	Software Channel ID for the assigned client.
+ * @handle_client: Structure device for client handle.
+ * @notifier: Client issued callback notification.
+ */
+int mhi_dev_open_channel(uint32_t chan_id,
+		struct mhi_dev_client **handle_client,
+		void (*event_trigger)(struct mhi_dev_client_cb_reason *cb));
+
+/**
+ * mhi_dev_close_channel() - Channel close for a given client.
+ */
+int mhi_dev_close_channel(struct mhi_dev_client *handle_client);
+
+/**
+ * mhi_dev_read_channel() - Channel read for a given client
+ * @mreq:       mreq is the client argument which includes meta info
+ *              like write data location, buffer len, read offset, mode,
+ *              chain and client call back function which will be invoked
+ *              when data read is completed.
+ */
+int mhi_dev_read_channel(struct mhi_req *mreq);
+
+/**
+ * mhi_dev_write_channel() - Channel write for a given software client.
+ * @wreq	wreq is the client argument which includes meta info like
+ *              client handle, read data location, buffer length, mode,
+ *              and client call back function which will free the packet.
+ *              when data write is completed.
+ */
+int mhi_dev_write_channel(struct mhi_req *wreq);
+
+/**
+ * mhi_dev_channel_isempty() - Checks if there is any pending TRE's to process.
+ * @handle_client:	Client Handle issued during mhi_dev_open_channel
+ */
+int mhi_dev_channel_isempty(struct mhi_dev_client *handle);
+
+/**
+ * mhi_ctrl_state_info() - Provide MHI state info
+ *		@idx: Channel number idx. Look at channel_state_info and
+ *		pass the index for the corresponding channel.
+ *		@info: Return the control info.
+ *		MHI_STATE=CONFIGURED - MHI device is present but not ready
+ *					for data traffic.
+ *		MHI_STATE=CONNECTED - MHI device is ready for data transfer.
+ *		MHI_STATE=DISCONNECTED - MHI device has its pipes suspended.
+ *		exposes device nodes for the supported MHI software
+ *		channels.
+ */
+int mhi_ctrl_state_info(uint32_t idx, uint32_t *info);
+
+/**
+ * mhi_register_state_cb() - Clients can register and receive callback after
+ *		MHI channel is connected or disconnected.
+ */
+int mhi_register_state_cb(void (*mhi_state_cb)
+			(struct mhi_dev_client_cb_data *cb_data), void *data,
+			enum mhi_client_channel channel);
+
+#else
+static inline int mhi_dev_open_channel(uint32_t chan_id,
+		struct mhi_dev_client **handle_client,
+		void (*event_trigger)(struct mhi_dev_client_cb_reason *cb))
+{
+	return -EINVAL;
+};
+
+static inline int mhi_dev_close_channel(struct mhi_dev_client *handle_client)
+{
+	return -EINVAL;
+};
+
+static inline int mhi_dev_read_channel(struct mhi_req *mreq)
+{
+	return -EINVAL;
+};
+
+static inline int mhi_dev_write_channel(struct mhi_req *wreq)
+{
+	return -EINVAL;
+};
+
+static inline int mhi_dev_channel_isempty(struct mhi_dev_client *handle)
+{
+	return -EINVAL;
+};
+
+static inline int mhi_ctrl_state_info(uint32_t idx, uint32_t *info)
+{
+	return -EINVAL;
+};
+
+static inline int mhi_register_state_cb(void (*mhi_state_cb)
+			(struct mhi_dev_client_cb_data *cb_data), void *data,
+			enum mhi_client_channel channel)
+{
+	return -EINVAL;
+};
+#endif
+
+#endif /* _MSM_MHI_DEV_H*/
diff --git a/mm/cma.c b/mm/cma.c
index e97ad01..1ccfaa1 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -466,7 +466,8 @@
 				bitmap_maxno, start, bitmap_count, mask,
 				offset);
 		if (bitmap_no >= bitmap_maxno) {
-			if (retry_after_sleep < max_retries) {
+			if ((retry_after_sleep < max_retries) &&
+						(ret == -EBUSY)) {
 				start = 0;
 				/*
 				 * update max retries if available free regions