Merge "power: smb5: Disable charger-hw ADC channels before reading USBIN_V"
diff --git a/arch/arm64/configs/vendor/bengal-perf_defconfig b/arch/arm64/configs/vendor/bengal-perf_defconfig
index a0a0a41..f13b7f0 100644
--- a/arch/arm64/configs/vendor/bengal-perf_defconfig
+++ b/arch/arm64/configs/vendor/bengal-perf_defconfig
@@ -294,6 +294,7 @@
 CONFIG_JOYSTICK_XPAD=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_INPUT_MISC=y
+CONFIG_INPUT_QPNP_POWER_ON=y
 CONFIG_INPUT_UINPUT=y
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_VT is not set
@@ -316,6 +317,9 @@
 CONFIG_POWER_RESET_QCOM=y
 CONFIG_POWER_RESET_XGENE=y
 CONFIG_POWER_RESET_SYSCON=y
+CONFIG_QPNP_SMB5=y
+CONFIG_SMB1355_SLAVE_CHARGER=y
+CONFIG_QPNP_QG=y
 CONFIG_THERMAL=y
 CONFIG_THERMAL_WRITABLE_TRIPS=y
 CONFIG_THERMAL_GOV_USER_SPACE=y
@@ -323,10 +327,14 @@
 CONFIG_QCOM_SPMI_TEMP_ALARM=y
 CONFIG_THERMAL_TSENS=y
 CONFIG_QTI_ADC_TM=y
+CONFIG_MFD_I2C_PMIC=y
 CONFIG_MFD_SPMI_PMIC=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_QCOM_SMD_RPM=y
+CONFIG_REGULATOR_QPNP_LCDB=y
+CONFIG_REGULATOR_RPM_SMD=y
 CONFIG_REGULATOR_STUB=y
+CONFIG_REGULATOR_PM8008=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_CONTROLLER=y
@@ -392,6 +400,11 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_MSM=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_QTI_TRI_LED=y
+CONFIG_LEDS_QPNP_FLASH_V2=y
+CONFIG_LEDS_QPNP_VIBRATOR_LDO=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_PM8XXX=y
 CONFIG_DMADEVICES=y
@@ -401,6 +414,7 @@
 CONFIG_STAGING=y
 CONFIG_ASHMEM=y
 CONFIG_ION=y
+CONFIG_QPNP_REVID=y
 CONFIG_SPS=y
 CONFIG_SPS_SUPPORT_NDP_BAM=y
 CONFIG_IPA3=y
@@ -410,6 +424,7 @@
 CONFIG_IPA_UT=y
 CONFIG_QCOM_GENI_SE=y
 CONFIG_QCOM_CLK_SMD_RPM=y
+CONFIG_SPMI_PMIC_CLKDIV=y
 CONFIG_SM_GPUCC_BENGAL=y
 CONFIG_SM_DISPCC_BENGAL=y
 CONFIG_SM_DEBUGCC_BENGAL=y
@@ -471,6 +486,7 @@
 CONFIG_IIO=y
 CONFIG_QCOM_SPMI_ADC5=y
 CONFIG_PWM=y
+CONFIG_PWM_QTI_LPG=y
 CONFIG_ARM_GIC_V3_ACL=y
 CONFIG_QCOM_MPM=y
 CONFIG_PHY_XGENE=y
@@ -478,6 +494,7 @@
 CONFIG_ANDROID=y
 CONFIG_ANDROID_BINDER_IPC=y
 CONFIG_QCOM_QFPROM=y
+CONFIG_NVMEM_SPMI_SDAM=y
 CONFIG_SLIMBUS=y
 CONFIG_QCOM_KGSL=y
 CONFIG_EXT4_FS=y
diff --git a/arch/arm64/configs/vendor/bengal_defconfig b/arch/arm64/configs/vendor/bengal_defconfig
index 610d239..8ebbe61 100644
--- a/arch/arm64/configs/vendor/bengal_defconfig
+++ b/arch/arm64/configs/vendor/bengal_defconfig
@@ -304,6 +304,7 @@
 CONFIG_JOYSTICK_XPAD=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_INPUT_MISC=y
+CONFIG_INPUT_QPNP_POWER_ON=y
 CONFIG_INPUT_UINPUT=y
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_VT is not set
@@ -328,6 +329,9 @@
 CONFIG_POWER_RESET_QCOM=y
 CONFIG_POWER_RESET_XGENE=y
 CONFIG_POWER_RESET_SYSCON=y
+CONFIG_QPNP_SMB5=y
+CONFIG_SMB1355_SLAVE_CHARGER=y
+CONFIG_QPNP_QG=y
 CONFIG_THERMAL=y
 CONFIG_THERMAL_WRITABLE_TRIPS=y
 CONFIG_THERMAL_GOV_USER_SPACE=y
@@ -335,10 +339,14 @@
 CONFIG_QCOM_SPMI_TEMP_ALARM=y
 CONFIG_THERMAL_TSENS=y
 CONFIG_QTI_ADC_TM=y
+CONFIG_MFD_I2C_PMIC=y
 CONFIG_MFD_SPMI_PMIC=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_QCOM_SMD_RPM=y
+CONFIG_REGULATOR_QPNP_LCDB=y
+CONFIG_REGULATOR_RPM_SMD=y
 CONFIG_REGULATOR_STUB=y
+CONFIG_REGULATOR_PM8008=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_CONTROLLER=y
@@ -404,6 +412,11 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_MSM=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_QTI_TRI_LED=y
+CONFIG_LEDS_QPNP_FLASH_V2=y
+CONFIG_LEDS_QPNP_VIBRATOR_LDO=y
 CONFIG_EDAC=y
 CONFIG_EDAC_CORTEX_ARM64=y
 CONFIG_EDAC_CORTEX_ARM64_DBE_IRQ_ONLY=y
@@ -418,6 +431,7 @@
 CONFIG_STAGING=y
 CONFIG_ASHMEM=y
 CONFIG_ION=y
+CONFIG_QPNP_REVID=y
 CONFIG_SPS=y
 CONFIG_SPS_SUPPORT_NDP_BAM=y
 CONFIG_IPA3=y
@@ -427,6 +441,7 @@
 CONFIG_IPA_UT=y
 CONFIG_QCOM_GENI_SE=y
 CONFIG_QCOM_CLK_SMD_RPM=y
+CONFIG_SPMI_PMIC_CLKDIV=y
 CONFIG_SM_GPUCC_BENGAL=y
 CONFIG_SM_DISPCC_BENGAL=y
 CONFIG_SM_DEBUGCC_BENGAL=y
@@ -494,6 +509,7 @@
 CONFIG_IIO=y
 CONFIG_QCOM_SPMI_ADC5=y
 CONFIG_PWM=y
+CONFIG_PWM_QTI_LPG=y
 CONFIG_ARM_GIC_V3_ACL=y
 CONFIG_QCOM_MPM=y
 CONFIG_PHY_XGENE=y
@@ -501,6 +517,7 @@
 CONFIG_ANDROID=y
 CONFIG_ANDROID_BINDER_IPC=y
 CONFIG_QCOM_QFPROM=y
+CONFIG_NVMEM_SPMI_SDAM=y
 CONFIG_SLIMBUS=y
 CONFIG_QCOM_KGSL=y
 CONFIG_EXT4_FS=y
diff --git a/drivers/char/diag/diag_memorydevice.c b/drivers/char/diag/diag_memorydevice.c
index 0481222..aa77fb78 100644
--- a/drivers/char/diag/diag_memorydevice.c
+++ b/drivers/char/diag/diag_memorydevice.c
@@ -177,7 +177,7 @@
 {
 	int i, peripheral, pid = 0;
 	uint8_t found = 0;
-	unsigned long flags;
+	unsigned long flags, flags_sec;
 	struct diag_md_info *ch = NULL;
 	struct diag_md_session_t *session_info = NULL;
 
@@ -209,6 +209,16 @@
 	}
 
 	spin_lock_irqsave(&ch->lock, flags);
+	if (peripheral == APPS_DATA) {
+		spin_lock_irqsave(&driver->diagmem_lock, flags_sec);
+		if (!hdlc_data.allocated && !non_hdlc_data.allocated) {
+			spin_unlock_irqrestore(&driver->diagmem_lock,
+				flags_sec);
+			spin_unlock_irqrestore(&ch->lock, flags);
+			mutex_unlock(&driver->md_session_lock);
+			return -EINVAL;
+		}
+	}
 	for (i = 0; i < ch->num_tbl_entries && !found; i++) {
 		if (ch->tbl[i].buf != buf)
 			continue;
@@ -220,14 +230,16 @@
 		ch->tbl[i].len = 0;
 		ch->tbl[i].ctx = 0;
 	}
-	spin_unlock_irqrestore(&ch->lock, flags);
 
 	if (found) {
+		if (peripheral == APPS_DATA)
+			spin_unlock_irqrestore(&driver->diagmem_lock,
+				flags_sec);
+		spin_unlock_irqrestore(&ch->lock, flags);
 		mutex_unlock(&driver->md_session_lock);
 		return -ENOMEM;
 	}
 
-	spin_lock_irqsave(&ch->lock, flags);
 	for (i = 0; i < ch->num_tbl_entries && !found; i++) {
 		if (ch->tbl[i].len == 0) {
 			ch->tbl[i].buf = buf;
@@ -237,6 +249,8 @@
 			diag_ws_on_read(DIAG_WS_MUX, len);
 		}
 	}
+	if (peripheral == APPS_DATA)
+		spin_unlock_irqrestore(&driver->diagmem_lock, flags_sec);
 	spin_unlock_irqrestore(&ch->lock, flags);
 	mutex_unlock(&driver->md_session_lock);
 
diff --git a/drivers/char/diag/diag_mux.h b/drivers/char/diag/diag_mux.h
index 24d33bb..1288642 100644
--- a/drivers/char/diag/diag_mux.h
+++ b/drivers/char/diag/diag_mux.h
@@ -65,4 +65,5 @@
 int diag_mux_open_all(struct diag_logger_t *logger);
 int diag_mux_close_all(void);
 int diag_mux_switch_logging(int proc, int *new_mode, int *peripheral_mask);
+void diag_notify_md_client(uint8_t proc, uint8_t peripheral, int data);
 #endif
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index dc90e55..7c7af1e 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -197,6 +197,10 @@
 		return;
 
 	spin_lock_irqsave(&driver->diagmem_lock, flags);
+	if (data->flushed) {
+		spin_unlock_irqrestore(&driver->diagmem_lock, flags);
+		return;
+	}
 	data->flushed = 1;
 	spin_unlock_irqrestore(&driver->diagmem_lock, flags);
 	err = diag_mux_write(DIAG_LOCAL_PROC, data->buf, data->len,
@@ -3091,8 +3095,8 @@
 
 	wait_event_interruptible(driver->hdlc_wait_q,
 			(data->flushed == 0));
+	spin_lock_irqsave(&driver->diagmem_lock, flags);
 	if (!data->buf) {
-		spin_lock_irqsave(&driver->diagmem_lock, flags);
 		data->buf = diagmem_alloc(driver, DIAG_MAX_HDLC_BUF_SIZE +
 					APF_DIAG_PADDING,
 					  POOL_TYPE_HDLC);
@@ -3103,11 +3107,9 @@
 		}
 		data->allocated = 1;
 		data->flushed = 0;
-		spin_unlock_irqrestore(&driver->diagmem_lock, flags);
 	}
 
 	if ((DIAG_MAX_HDLC_BUF_SIZE - data->len) <= max_encoded_size) {
-		spin_lock_irqsave(&driver->diagmem_lock, flags);
 		data->flushed = 1;
 		spin_unlock_irqrestore(&driver->diagmem_lock, flags);
 		err = diag_mux_write(DIAG_LOCAL_PROC, data->buf, data->len,
@@ -3129,13 +3131,11 @@
 		}
 		data->allocated = 1;
 		data->flushed = 0;
-		spin_unlock_irqrestore(&driver->diagmem_lock, flags);
 	}
 
 	enc.dest = data->buf + data->len;
 	enc.dest_last = (void *)(data->buf + data->len + max_encoded_size);
 	diag_hdlc_encode(&send, &enc);
-
 	/*
 	 * This is to check if after HDLC encoding, we are still within
 	 * the limits of aggregation buffer. If not, we write out the
@@ -3144,7 +3144,6 @@
 	 */
 	if ((uintptr_t)enc.dest >= (uintptr_t)(data->buf +
 					       DIAG_MAX_HDLC_BUF_SIZE)) {
-		spin_lock_irqsave(&driver->diagmem_lock, flags);
 		data->flushed = 1;
 		spin_unlock_irqrestore(&driver->diagmem_lock, flags);
 		err = diag_mux_write(DIAG_LOCAL_PROC, data->buf, data->len,
@@ -3166,7 +3165,6 @@
 		}
 		data->allocated = 1;
 		data->flushed = 0;
-		spin_unlock_irqrestore(&driver->diagmem_lock, flags);
 
 		enc.dest = data->buf + data->len;
 		enc.dest_last = (void *)(data->buf + data->len +
@@ -3180,7 +3178,6 @@
 			DIAG_MAX_HDLC_BUF_SIZE;
 
 	if (pkt_type == DATA_TYPE_RESPONSE) {
-		spin_lock_irqsave(&driver->diagmem_lock, flags);
 		data->flushed = 1;
 		spin_unlock_irqrestore(&driver->diagmem_lock, flags);
 		err = diag_mux_write(DIAG_LOCAL_PROC, data->buf, data->len,
@@ -3189,8 +3186,9 @@
 			ret = -EIO;
 			goto fail_free_buf;
 		}
+		return PKT_ALLOC;
 	}
-
+	spin_unlock_irqrestore(&driver->diagmem_lock, flags);
 	return PKT_ALLOC;
 
 fail_free_buf:
@@ -3228,8 +3226,8 @@
 	}
 	wait_event_interruptible(driver->hdlc_wait_q,
 			(data->flushed == 0));
+	spin_lock_irqsave(&driver->diagmem_lock, flags);
 	if (!data->buf) {
-		spin_lock_irqsave(&driver->diagmem_lock, flags);
 		data->buf = diagmem_alloc(driver, DIAG_MAX_HDLC_BUF_SIZE +
 					APF_DIAG_PADDING,
 					  POOL_TYPE_HDLC);
@@ -3240,10 +3238,8 @@
 		}
 		data->allocated = 1;
 		data->flushed = 0;
-		spin_unlock_irqrestore(&driver->diagmem_lock, flags);
 	}
 	if ((DIAG_MAX_HDLC_BUF_SIZE - data->len) <= max_pkt_size) {
-		spin_lock_irqsave(&driver->diagmem_lock, flags);
 		data->flushed = 1;
 		spin_unlock_irqrestore(&driver->diagmem_lock, flags);
 		err = diag_mux_write(DIAG_LOCAL_PROC, data->buf, data->len,
@@ -3266,7 +3262,6 @@
 		}
 		data->allocated = 1;
 		data->flushed = 0;
-		spin_unlock_irqrestore(&driver->diagmem_lock, flags);
 	}
 
 	header.start = CONTROL_CHAR;
@@ -3279,7 +3274,6 @@
 	*(uint8_t *)(data->buf + data->len) = CONTROL_CHAR;
 	data->len += sizeof(uint8_t);
 	if (pkt_type == DATA_TYPE_RESPONSE) {
-		spin_lock_irqsave(&driver->diagmem_lock, flags);
 		data->flushed = 1;
 		spin_unlock_irqrestore(&driver->diagmem_lock, flags);
 		err = diag_mux_write(DIAG_LOCAL_PROC, data->buf, data->len,
@@ -3288,8 +3282,9 @@
 			ret = -EIO;
 			goto fail_free_buf;
 		}
+		return PKT_ALLOC;
 	}
-
+	spin_unlock_irqrestore(&driver->diagmem_lock, flags);
 	return PKT_ALLOC;
 
 fail_free_buf:
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index be31974..fe216df 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -1945,6 +1945,9 @@
 				DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
 				"No apps data buffer is allocated to be freed\n");
 			if (temp) {
+				DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
+				"Freeing Apps data buffer after write done hdlc.allocated: %d, non_hdlc.allocated: %d\n",
+				hdlc_data.allocated, non_hdlc_data.allocated);
 				diagmem_free(driver, temp->buf, POOL_TYPE_HDLC);
 				temp->buf = NULL;
 				temp->len = 0;
diff --git a/drivers/char/diag/diagfwd_bridge.c b/drivers/char/diag/diagfwd_bridge.c
index d2cb9b3..374d185 100644
--- a/drivers/char/diag/diagfwd_bridge.c
+++ b/drivers/char/diag/diagfwd_bridge.c
@@ -195,16 +195,21 @@
 	if (id < 0 || id >= NUM_REMOTE_DEV)
 		return -EINVAL;
 	bridge_info[id].inited = 1;
-	if (bridge_info[id].type == DIAG_DATA_TYPE)
+	if (bridge_info[id].type == DIAG_DATA_TYPE) {
+		diag_notify_md_client(BRIDGE_TO_MUX(id), 0, DIAG_STATUS_OPEN);
 		return diag_mux_queue_read(BRIDGE_TO_MUX(id));
-	else if (bridge_info[id].type == DIAG_DCI_TYPE)
+	} else if (bridge_info[id].type == DIAG_DCI_TYPE) {
 		return diag_dci_send_handshake_pkt(bridge_info[id].id);
+	}
 
 	return 0;
 }
 
 void diag_remote_dev_close(int id)
 {
+	if (bridge_info[id].type == DIAG_DATA_TYPE)
+		diag_notify_md_client(BRIDGE_TO_MUX(id), 0, DIAG_STATUS_CLOSED);
+
 }
 
 int diag_remote_dev_read_done(int id, unsigned char *buf, int len)
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index 76e5601..5acb25f 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -19,11 +19,10 @@
 #include "diag_mux.h"
 
 #define FEATURE_SUPPORTED(x)	((feature_mask << (i * 8)) & (1 << x))
-
+#define DIAG_GET_MD_DEVICE_SIG_MASK(proc) (0x100000 * (1 << proc))
 /* tracks which peripheral is undergoing SSR */
 static uint16_t reg_dirty[NUM_PERIPHERALS];
 static uint8_t diag_id = DIAG_ID_APPS;
-static void diag_notify_md_client(uint8_t peripheral, int data);
 
 static void diag_mask_update_work_fn(struct work_struct *work)
 {
@@ -42,7 +41,9 @@
 		return;
 	driver->mask_update |= PERIPHERAL_MASK(p_info->peripheral);
 	queue_work(driver->cntl_wq, &driver->mask_update_work);
-	diag_notify_md_client(p_info->peripheral, DIAG_STATUS_OPEN);
+	diag_notify_md_client(DIAG_LOCAL_PROC, p_info->peripheral,
+				DIAG_STATUS_OPEN);
+
 }
 
 void diag_cntl_channel_close(struct diagfwd_info *p_info)
@@ -66,7 +67,7 @@
 	driver->stm_state[peripheral] = DISABLE_STM;
 	driver->stm_state_requested[peripheral] = DISABLE_STM;
 	reg_dirty[peripheral] = 0;
-	diag_notify_md_client(peripheral, DIAG_STATUS_CLOSED);
+	diag_notify_md_client(DIAG_LOCAL_PROC, peripheral, DIAG_STATUS_CLOSED);
 }
 
 static void diag_stm_update_work_fn(struct work_struct *work)
@@ -97,9 +98,9 @@
 	}
 }
 
-void diag_notify_md_client(uint8_t peripheral, int data)
+void diag_notify_md_client(uint8_t proc, uint8_t peripheral, int data)
 {
-	int stat = 0, proc = DIAG_LOCAL_PROC;
+	int stat = 0;
 	struct siginfo info;
 	struct pid *pid_struct;
 	struct task_struct *result;
@@ -113,7 +114,10 @@
 	mutex_lock(&driver->md_session_lock);
 	memset(&info, 0, sizeof(struct siginfo));
 	info.si_code = SI_QUEUE;
-	info.si_int = (PERIPHERAL_MASK(peripheral) | data);
+	info.si_int = (DIAG_GET_MD_DEVICE_SIG_MASK(proc) | data);
+	if (proc == DIAG_LOCAL_PROC)
+		info.si_int = info.si_int |
+				(PERIPHERAL_MASK(peripheral) | data);
 	info.si_signo = SIGCONT;
 
 	if (!driver->md_session_map[proc][peripheral] ||
@@ -171,7 +175,7 @@
 	pd_msg = (struct diag_ctrl_msg_pd_status *)buf;
 	pd = pd_msg->pd_id;
 	status = (pd_msg->status == 0) ? DIAG_STATUS_OPEN : DIAG_STATUS_CLOSED;
-	diag_notify_md_client(peripheral, status);
+	diag_notify_md_client(DIAG_LOCAL_PROC, peripheral, status);
 }
 
 static void enable_stm_feature(uint8_t peripheral)
@@ -1886,11 +1890,9 @@
 		if (!P_FMASK_DIAGID_V2(i))
 			continue;
 		err = diagfwd_write(i, TYPE_CNTL, &ctrl_pkt, sizeof(ctrl_pkt));
-		if (err && err != -ENODEV) {
+		if (err && err != -ENODEV)
 			pr_err("diag: Unable to send PASSTHRU ctrl packet to peripheral %d, err: %d\n",
 				i, err);
-			return err;
-		}
 	}
 	return 0;
 }
diff --git a/drivers/clk/qcom/debugcc-bengal.c b/drivers/clk/qcom/debugcc-bengal.c
index 38b57e8..c1cb3dc 100644
--- a/drivers/clk/qcom/debugcc-bengal.c
+++ b/drivers/clk/qcom/debugcc-bengal.c
@@ -29,8 +29,8 @@
 };
 
 static int cpu_cc_debug_mux_sels[] = {
-	0x25,		/* perfcl_clk */
-	0x21,		/* pwrcl_clk */
+	0x1,		/* perfcl_clk */
+	0x0,		/* pwrcl_clk */
 };
 
 static int apss_cc_debug_mux_pre_divs[] = {
@@ -43,9 +43,9 @@
 	.debug_offset = 0x0,
 	.post_div_offset = 0x0,
 	.cbcr_offset = U32_MAX,
-	.src_sel_mask = 0x3FF,
+	.src_sel_mask = 0x3FF00,
 	.src_sel_shift = 8,
-	.post_div_mask = 0xF,
+	.post_div_mask = 0xF0000000,
 	.post_div_shift = 28,
 	.post_div_val = 1,
 	.mux_sels = cpu_cc_debug_mux_sels,
diff --git a/drivers/clk/qcom/gcc-bengal.c b/drivers/clk/qcom/gcc-bengal.c
index f099f85..7d5942c 100644
--- a/drivers/clk/qcom/gcc-bengal.c
+++ b/drivers/clk/qcom/gcc-bengal.c
@@ -3275,6 +3275,19 @@
 	},
 };
 
+static struct clk_branch gcc_ufs_clkref_clk = {
+	.halt_reg = 0x8c000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8c000,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gcc_ufs_clkref_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
 static struct clk_branch gcc_ufs_phy_ahb_clk = {
 	.halt_reg = 0x45014,
 	.halt_check = BRANCH_HALT,
@@ -3744,6 +3757,7 @@
 	[GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr,
 	[GCC_SYS_NOC_UFS_PHY_AXI_CLK] = &gcc_sys_noc_ufs_phy_axi_clk.clkr,
 	[GCC_SYS_NOC_USB3_PRIM_AXI_CLK] = &gcc_sys_noc_usb3_prim_axi_clk.clkr,
+	[GCC_UFS_CLKREF_CLK] = &gcc_ufs_clkref_clk.clkr,
 	[GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr,
 	[GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr,
 	[GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr,
diff --git a/drivers/clk/qcom/gpucc-bengal.c b/drivers/clk/qcom/gpucc-bengal.c
index 90646d9..1bba610 100644
--- a/drivers/clk/qcom/gpucc-bengal.c
+++ b/drivers/clk/qcom/gpucc-bengal.c
@@ -53,7 +53,7 @@
 	"bi_tcxo",
 	"gpu_cc_pll0_out_main",
 	"gpu_cc_pll1_out_main",
-	"gpll0_out_main",
+	"gpll0",
 	"gpll0_out_main_div",
 	"core_bi_pll_test_se",
 };
@@ -74,7 +74,7 @@
 	"gpu_cc_pll0_out_aux2",
 	"gpu_cc_pll1_out_aux",
 	"gpu_cc_pll1_out_aux2",
-	"gpll0_out_main",
+	"gpll0",
 	"core_bi_pll_test_se",
 };
 
diff --git a/drivers/gpu/msm/adreno-gpulist.h b/drivers/gpu/msm/adreno-gpulist.h
index 4c5268a..50f9507 100644
--- a/drivers/gpu/msm/adreno-gpulist.h
+++ b/drivers/gpu/msm/adreno-gpulist.h
@@ -1280,8 +1280,8 @@
 static const struct adreno_reglist a612_hwcg_regs[] = {
 	{A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222},
 	{A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
-	{A6XX_RBBM_CLOCK_DELAY_SP0, 0x0000F3CF},
-	{A6XX_RBBM_CLOCK_HYST_SP0, 0x00000081},
+	{A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000081},
+	{A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
 	{A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222},
 	{A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
 	{A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.c b/drivers/gpu/msm/adreno_a6xx_gmu.c
index 80a39c8..2994aff 100644
--- a/drivers/gpu/msm/adreno_a6xx_gmu.c
+++ b/drivers/gpu/msm/adreno_a6xx_gmu.c
@@ -360,7 +360,16 @@
 	if (timed_poll_check(device,
 			A6XX_GMU_CM3_FW_INIT_RESULT,
 			val, GMU_START_TIMEOUT, mask)) {
-		dev_err(&gmu->pdev->dev, "GMU doesn't boot\n");
+		u32 val;
+
+		/*
+		 * The breadcrumb is written to a gmu virtual mapping
+		 * which points to dtcm byte offset 0x3fdc.
+		 */
+		gmu_core_regread(device,
+			A6XX_GMU_CM3_DTCM_START + (0x3fdc >> 2), &val);
+		dev_err(&gmu->pdev->dev, "GMU doesn't boot: 0x%x\n", val);
+
 		return -ETIMEDOUT;
 	}
 
diff --git a/drivers/gpu/msm/adreno_a6xx_snapshot.c b/drivers/gpu/msm/adreno_a6xx_snapshot.c
index eeb588a..c2a38f0 100644
--- a/drivers/gpu/msm/adreno_a6xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a6xx_snapshot.c
@@ -12,6 +12,9 @@
 #define A6XX_NUM_XIN_AXI_BLOCKS 5
 #define A6XX_NUM_XIN_CORE_BLOCKS 4
 
+/* Snapshot section size of each CP preemption record for A6XX  */
+#define A6XX_SNAPSHOT_CP_CTXRECORD_SIZE_IN_BYTES (64 * 1024)
+
 static const unsigned int a6xx_gras_cluster[] = {
 	0x8000, 0x8006, 0x8010, 0x8092, 0x8094, 0x809D, 0x80A0, 0x80A6,
 	0x80AF, 0x80F1, 0x8100, 0x8107, 0x8109, 0x8109, 0x8110, 0x8110,
@@ -1720,6 +1723,32 @@
 	return (count * 8) + sizeof(*header);
 }
 
+/* Snapshot the preemption related buffers */
+static size_t snapshot_preemption_record(struct kgsl_device *device,
+	u8 *buf, size_t remain, void *priv)
+{
+	struct kgsl_memdesc *memdesc = priv;
+	struct kgsl_snapshot_gpu_object_v2 *header =
+		(struct kgsl_snapshot_gpu_object_v2 *)buf;
+	u8 *ptr = buf + sizeof(*header);
+
+	if (remain < (A6XX_SNAPSHOT_CP_CTXRECORD_SIZE_IN_BYTES +
+						sizeof(*header))) {
+		SNAPSHOT_ERR_NOMEM(device, "PREEMPTION RECORD");
+		return 0;
+	}
+
+	header->size = A6XX_SNAPSHOT_CP_CTXRECORD_SIZE_IN_BYTES >> 2;
+	header->gpuaddr = memdesc->gpuaddr;
+	header->ptbase =
+		kgsl_mmu_pagetable_get_ttbr0(device->mmu.defaultpagetable);
+	header->type = SNAPSHOT_GPU_OBJECT_GLOBAL;
+
+	memcpy(ptr, memdesc->hostptr, A6XX_SNAPSHOT_CP_CTXRECORD_SIZE_IN_BYTES);
+
+	return A6XX_SNAPSHOT_CP_CTXRECORD_SIZE_IN_BYTES + sizeof(*header);
+}
+
 /*
  * a6xx_snapshot() - A6XX GPU snapshot function
  * @adreno_dev: Device being snapshotted
@@ -1733,6 +1762,7 @@
 {
 	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
 	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
+	struct adreno_ringbuffer *rb;
 	bool sptprac_on;
 	unsigned int i, roq_size, ucode_dbg_size;
 
@@ -1851,6 +1881,15 @@
 		a6xx_snapshot_dbgahb_regs(device, snapshot);
 	}
 
+	/* Preemption record */
+	if (adreno_is_preemption_enabled(adreno_dev)) {
+		FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
+			kgsl_snapshot_add_section(device,
+				KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2,
+				snapshot, snapshot_preemption_record,
+				&rb->preemption_desc);
+		}
+	}
 }
 
 static int _a6xx_crashdump_init_mvc(struct adreno_device *adreno_dev,
diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c
index d310bc0..59d4e07 100644
--- a/drivers/gpu/msm/adreno_dispatch.c
+++ b/drivers/gpu/msm/adreno_dispatch.c
@@ -1380,6 +1380,22 @@
 
 	user_ts = *timestamp;
 
+	/*
+	 * If there is only one drawobj in the array and it is of
+	 * type SYNCOBJ_TYPE, skip comparing user_ts as it can be 0
+	 */
+	if (!(count == 1 && drawobj[0]->type == SYNCOBJ_TYPE) &&
+		(drawctxt->base.flags & KGSL_CONTEXT_USER_GENERATED_TS)) {
+		/*
+		 * User specified timestamps need to be greater than the last
+		 * issued timestamp in the context
+		 */
+		if (timestamp_cmp(drawctxt->timestamp, user_ts) >= 0) {
+			spin_unlock(&drawctxt->lock);
+			return -ERANGE;
+		}
+	}
+
 	for (i = 0; i < count; i++) {
 
 		switch (drawobj[i]->type) {
diff --git a/drivers/gpu/msm/kgsl_gmu_core.c b/drivers/gpu/msm/kgsl_gmu_core.c
index 71b77c6..4e3bbfb 100644
--- a/drivers/gpu/msm/kgsl_gmu_core.c
+++ b/drivers/gpu/msm/kgsl_gmu_core.c
@@ -101,14 +101,13 @@
 
 bool gmu_core_scales_bandwidth(struct kgsl_device *device)
 {
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
 	if (device->gmu_core.type == GMU_CORE_TYPE_PCC)
 		return false;
-	else {
-		struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 
-		return gmu_core_gpmu_isenabled(device) &&
-			   (ADRENO_GPUREV(adreno_dev) >= ADRENO_REV_A640);
-	}
+	return gmu_core_gpmu_isenabled(device) &&
+		   (ADRENO_GPUREV(adreno_dev) >= ADRENO_REV_A640);
 }
 
 int gmu_core_init(struct kgsl_device *device)
diff --git a/drivers/hwtracing/coresight/coresight-byte-cntr.c b/drivers/hwtracing/coresight/coresight-byte-cntr.c
index af638f6..e0454e7 100644
--- a/drivers/hwtracing/coresight/coresight-byte-cntr.c
+++ b/drivers/hwtracing/coresight/coresight-byte-cntr.c
@@ -11,6 +11,7 @@
 #include <linux/delay.h>
 #include <linux/uaccess.h>
 #include <linux/usb/usb_qdss.h>
+#include <linux/time.h>
 
 #include "coresight-byte-cntr.h"
 #include "coresight-priv.h"
@@ -19,6 +20,7 @@
 #define USB_BLK_SIZE 65536
 #define USB_SG_NUM (USB_BLK_SIZE / PAGE_SIZE)
 #define USB_BUF_NUM 255
+#define USB_TIME_OUT (5 * HZ)
 
 static struct tmc_drvdata *tmcdrvdata;
 
@@ -315,91 +317,180 @@
 	return ret;
 }
 
-static void usb_read_work_fn(struct work_struct *work)
+static int usb_transfer_small_packet(struct qdss_request *usb_req,
+			struct byte_cntr *drvdata, size_t *small_size)
 {
-	int ret, i, seq = 0;
-	struct qdss_request *usb_req = NULL;
+	int ret = 0;
 	struct etr_buf *etr_buf = tmcdrvdata->etr_buf;
-	size_t actual, req_size;
-	char *buf;
-	struct byte_cntr *drvdata =
-		container_of(work, struct byte_cntr, read_work);
+	size_t req_size, actual;
+	long w_offset;
 
-	while (tmcdrvdata->enable
-		&& tmcdrvdata->out_mode == TMC_ETR_OUT_MODE_USB) {
-		if (!atomic_read(&drvdata->irq_cnt)) {
-			ret = wait_event_interruptible(drvdata->usb_wait_wq,
-				atomic_read(&drvdata->irq_cnt) > 0
-				|| !tmcdrvdata->enable || tmcdrvdata->out_mode
-				!= TMC_ETR_OUT_MODE_USB
-				|| !drvdata->read_active);
-			if (ret == -ERESTARTSYS || !tmcdrvdata->enable
-			|| tmcdrvdata->out_mode != TMC_ETR_OUT_MODE_USB
-			|| !drvdata->read_active)
-				break;
-		}
+	w_offset = tmc_sg_get_rwp_offset(tmcdrvdata);
+	req_size = ((w_offset < drvdata->offset) ? etr_buf->size : 0) +
+				w_offset - drvdata->offset;
+	req_size = (req_size < USB_BLK_SIZE) ? req_size : USB_BLK_SIZE;
 
-		req_size = USB_BLK_SIZE;
-		seq++;
+	while (req_size > 0) {
+
 		usb_req = devm_kzalloc(tmcdrvdata->dev, sizeof(*usb_req),
-					GFP_KERNEL);
-		if (!usb_req)
-			return;
-		usb_req->sg = devm_kzalloc(tmcdrvdata->dev,
-			sizeof(*(usb_req->sg)) * USB_SG_NUM, GFP_KERNEL);
-		if (!usb_req->sg) {
-			devm_kfree(tmcdrvdata->dev, usb_req->sg);
-			return;
+			GFP_KERNEL);
+		if (!usb_req) {
+			ret = -EFAULT;
+			goto out;
 		}
-		usb_req->length = USB_BLK_SIZE;
+
+		actual = tmc_etr_buf_get_data(etr_buf, drvdata->offset,
+					req_size, &usb_req->buf);
+		usb_req->length = actual;
 		drvdata->usb_req = usb_req;
-		for (i = 0; i < USB_SG_NUM; i++) {
-			actual = tmc_etr_buf_get_data(etr_buf, drvdata->offset,
-					PAGE_SIZE, &buf);
-			if (actual <= 0) {
-				devm_kfree(tmcdrvdata->dev, usb_req->sg);
-				devm_kfree(tmcdrvdata->dev, usb_req);
-				usb_req = NULL;
-				dev_err(tmcdrvdata->dev, "No data in ETR\n");
-				return;
-			}
-			sg_set_buf(&usb_req->sg[i], buf, actual);
-			if (i == 0)
-				usb_req->buf = buf;
-			req_size -= actual;
-			if ((drvdata->offset + actual) >= tmcdrvdata->size)
-				drvdata->offset = 0;
-			else
-				drvdata->offset += actual;
-			if (i == USB_SG_NUM - 1)
-				sg_mark_end(&usb_req->sg[i]);
-		}
-		usb_req->num_sgs = i;
+		req_size -= actual;
+
+		if ((drvdata->offset + actual) >= tmcdrvdata->size)
+			drvdata->offset = 0;
+		else
+			drvdata->offset += actual;
+
+		*small_size += actual;
+
 		if (atomic_read(&drvdata->usb_free_buf) > 0) {
-			ret = usb_qdss_write(tmcdrvdata->usbch,
-					drvdata->usb_req);
+			ret = usb_qdss_write(tmcdrvdata->usbch, usb_req);
+
 			if (ret) {
-				devm_kfree(tmcdrvdata->dev, usb_req->sg);
 				devm_kfree(tmcdrvdata->dev, usb_req);
 				usb_req = NULL;
 				drvdata->usb_req = NULL;
 				dev_err(tmcdrvdata->dev,
 					"Write data failed:%d\n", ret);
-				if (ret == -EAGAIN)
-					continue;
-				return;
+				goto out;
 			}
-			atomic_dec(&drvdata->usb_free_buf);
 
+			atomic_dec(&drvdata->usb_free_buf);
 		} else {
 			dev_dbg(tmcdrvdata->dev,
-			"Drop data, offset = %d, seq = %d, irq = %d\n",
-				drvdata->offset, seq,
-				atomic_read(&drvdata->irq_cnt));
-			devm_kfree(tmcdrvdata->dev, usb_req->sg);
+			"Drop data, offset = %d, len = %d\n",
+				drvdata->offset, req_size);
 			devm_kfree(tmcdrvdata->dev, usb_req);
 			drvdata->usb_req = NULL;
 		}
+	}
+
+out:
+	return ret;
+}
+
+static void usb_read_work_fn(struct work_struct *work)
+{
+	int ret, i, seq = 0;
+	struct qdss_request *usb_req = NULL;
+	struct etr_buf *etr_buf = tmcdrvdata->etr_buf;
+	size_t actual, req_size, req_sg_num, small_size = 0;
+	char *buf;
+	struct byte_cntr *drvdata =
+		container_of(work, struct byte_cntr, read_work);
+
+
+	while (tmcdrvdata->enable
+		&& tmcdrvdata->out_mode == TMC_ETR_OUT_MODE_USB) {
+		if (!atomic_read(&drvdata->irq_cnt)) {
+			ret =  wait_event_interruptible_timeout(
+				drvdata->usb_wait_wq,
+				atomic_read(&drvdata->irq_cnt) > 0
+				|| !tmcdrvdata->enable || tmcdrvdata->out_mode
+				!= TMC_ETR_OUT_MODE_USB
+				|| !drvdata->read_active, USB_TIME_OUT);
+			if (ret == -ERESTARTSYS || !tmcdrvdata->enable
+			|| tmcdrvdata->out_mode != TMC_ETR_OUT_MODE_USB
+			|| !drvdata->read_active)
+				break;
+
+			if (ret == 0) {
+				ret = usb_transfer_small_packet(usb_req,
+						drvdata, &small_size);
+				if (ret && ret != -EAGAIN)
+					return;
+				continue;
+			}
+		}
+
+		req_size = USB_BLK_SIZE - small_size;
+		small_size = 0;
+
+		if (req_size > 0) {
+			seq++;
+			req_sg_num = (req_size - 1) / PAGE_SIZE + 1;
+			usb_req = devm_kzalloc(tmcdrvdata->dev,
+						sizeof(*usb_req), GFP_KERNEL);
+			if (!usb_req)
+				return;
+			usb_req->sg = devm_kzalloc(tmcdrvdata->dev,
+					sizeof(*(usb_req->sg)) * req_sg_num,
+					GFP_KERNEL);
+			if (!usb_req->sg) {
+				devm_kfree(tmcdrvdata->dev, usb_req);
+				usb_req = NULL;
+				return;
+			}
+
+			for (i = 0; i < req_sg_num; i++) {
+				actual = tmc_etr_buf_get_data(etr_buf,
+							drvdata->offset,
+							PAGE_SIZE, &buf);
+
+				if (actual <= 0) {
+					devm_kfree(tmcdrvdata->dev,
+							usb_req->sg);
+					devm_kfree(tmcdrvdata->dev, usb_req);
+					usb_req = NULL;
+					dev_err(tmcdrvdata->dev, "No data in ETR\n");
+					return;
+				}
+
+				sg_set_buf(&usb_req->sg[i], buf, actual);
+
+				if (i == 0)
+					usb_req->buf = buf;
+				if (i == req_sg_num - 1)
+					sg_mark_end(&usb_req->sg[i]);
+
+				if ((drvdata->offset + actual) >=
+					tmcdrvdata->size)
+					drvdata->offset = 0;
+				else
+					drvdata->offset += actual;
+			}
+
+			usb_req->length = req_size;
+			drvdata->usb_req = usb_req;
+			usb_req->num_sgs = i;
+
+			if (atomic_read(&drvdata->usb_free_buf) > 0) {
+				ret = usb_qdss_write(tmcdrvdata->usbch,
+						drvdata->usb_req);
+				if (ret) {
+					devm_kfree(tmcdrvdata->dev,
+							usb_req->sg);
+					devm_kfree(tmcdrvdata->dev, usb_req);
+					usb_req = NULL;
+					drvdata->usb_req = NULL;
+					dev_err(tmcdrvdata->dev,
+						"Write data failed:%d\n", ret);
+					if (ret == -EAGAIN)
+						continue;
+					return;
+				}
+				atomic_dec(&drvdata->usb_free_buf);
+
+			} else {
+				dev_dbg(tmcdrvdata->dev,
+				"Drop data, offset = %d, seq = %d, irq = %d\n",
+					drvdata->offset, seq,
+					atomic_read(&drvdata->irq_cnt));
+				devm_kfree(tmcdrvdata->dev, usb_req->sg);
+				devm_kfree(tmcdrvdata->dev, usb_req);
+				drvdata->usb_req = NULL;
+			}
+		}
+
 		if (atomic_read(&drvdata->irq_cnt) > 0)
 			atomic_dec(&drvdata->irq_cnt);
 	}
@@ -412,7 +503,8 @@
 	atomic_inc(&drvdata->usb_free_buf);
 	if (d_req->status)
 		pr_err_ratelimited("USB write failed err:%d\n", d_req->status);
-	devm_kfree(tmcdrvdata->dev, d_req->sg);
+	if (d_req->sg)
+		devm_kfree(tmcdrvdata->dev, d_req->sg);
 	devm_kfree(tmcdrvdata->dev, d_req);
 }
 
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index a8dec53..9a7609e 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -215,6 +215,20 @@
 	tmc_free_data_pages(sg_table);
 }
 
+long tmc_sg_get_rwp_offset(struct tmc_drvdata *drvdata)
+{
+	struct etr_buf *etr_buf = drvdata->etr_buf;
+	struct etr_sg_table *etr_table = etr_buf->private;
+	struct tmc_sg_table *table = etr_table->sg_table;
+	u64 rwp;
+	long w_offset;
+
+	rwp = tmc_read_rwp(drvdata);
+	w_offset = tmc_sg_get_data_page_offset(table, rwp);
+
+	return w_offset;
+}
+
 /*
  * Alloc pages for the table. Since this will be used by the device,
  * allocate the pages closer to the device (i.e, dev_to_node(dev)
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index a30e360..22b9fbc 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -325,7 +325,7 @@
 ssize_t tmc_etr_buf_get_data(struct etr_buf *etr_buf,
 				u64 offset, size_t len, char **bufpp);
 int tmc_etr_switch_mode(struct tmc_drvdata *drvdata, const char *out_mode);
-
+long tmc_sg_get_rwp_offset(struct tmc_drvdata *drvdata);
 
 #define TMC_REG_PAIR(name, lo_off, hi_off)				\
 static inline u64							\
diff --git a/drivers/media/platform/msm/cvp/cvp_hfi.c b/drivers/media/platform/msm/cvp/cvp_hfi.c
index 95f5a56..0fc5c12 100644
--- a/drivers/media/platform/msm/cvp/cvp_hfi.c
+++ b/drivers/media/platform/msm/cvp/cvp_hfi.c
@@ -581,8 +581,10 @@
 {
 	int rc;
 
+	cvp_dsp_set_cvp_ssr();
+
 	if (!(device->dsp_flags & DSP_INIT)) {
-		dprintk(CVP_DBG, "%s: dsp not inited\n", __func__);
+		dprintk(CVP_WARN, "%s: dsp not inited\n", __func__);
 		return 0;
 	}
 
@@ -1442,6 +1444,9 @@
 	iris_hfi_for_each_clock(device, cl) {
 		if (cl->has_scaling) {/* has_scaling */
 			device->clk_freq = freq;
+			if (msm_cvp_clock_voting)
+				freq = msm_cvp_clock_voting;
+
 			rc = clk_set_rate(cl->clk, freq);
 			if (rc) {
 				dprintk(CVP_ERR,
diff --git a/drivers/media/platform/msm/cvp/msm_cvp.c b/drivers/media/platform/msm/cvp/msm_cvp.c
index 0c8a5c9..015aa8e 100644
--- a/drivers/media/platform/msm/cvp/msm_cvp.c
+++ b/drivers/media/platform/msm/cvp/msm_cvp.c
@@ -420,9 +420,9 @@
 	rc = msm_cvp_smem_map_dma_buf(inst, &cbuf->smem);
 	if (rc) {
 		dprintk(CVP_ERR,
-		"%s: %x : fd %d %s size %d",
+		"%s: %x : fd %d size %d",
 		"map persist failed", hash32_ptr(inst->session), cbuf->smem.fd,
-		cbuf->smem.dma_buf->name, cbuf->smem.size);
+		cbuf->smem.size);
 		goto exit;
 	}
 
diff --git a/drivers/media/platform/msm/cvp/msm_cvp_core.c b/drivers/media/platform/msm/cvp/msm_cvp_core.c
index bedf843..a4a86de 100644
--- a/drivers/media/platform/msm/cvp/msm_cvp_core.c
+++ b/drivers/media/platform/msm/cvp/msm_cvp_core.c
@@ -16,6 +16,7 @@
 #include "msm_cvp_clocks.h"
 #include <linux/dma-buf.h>
 #include <uapi/media/msm_media_info.h>
+#include <synx_api.h>
 
 #define MAX_EVENTS 30
 #define NUM_CYCLES16X16_HCD_FRAME 95
@@ -302,6 +303,8 @@
 
 	kref_init(&inst->kref);
 
+	synx_initialize(NULL);
+
 	inst->session_type = session_type;
 	inst->state = MSM_CVP_CORE_UNINIT_DONE;
 	inst->core = core;
@@ -353,6 +356,8 @@
 	DEINIT_MSM_CVP_LIST(&inst->cvpdspbufs);
 	DEINIT_MSM_CVP_LIST(&inst->frames);
 
+	synx_uninitialize();
+
 	kfree(inst);
 	inst = NULL;
 err_invalid_core:
@@ -388,6 +393,8 @@
 	list_del(&inst->list);
 	mutex_unlock(&core->lock);
 
+	synx_uninitialize();
+
 	DEINIT_MSM_CVP_LIST(&inst->persistbufs);
 	DEINIT_MSM_CVP_LIST(&inst->cvpcpubufs);
 	DEINIT_MSM_CVP_LIST(&inst->cvpdspbufs);
diff --git a/drivers/media/platform/msm/cvp/msm_cvp_debug.c b/drivers/media/platform/msm/cvp/msm_cvp_debug.c
index 063ef64..9d61d2ac 100644
--- a/drivers/media/platform/msm/cvp/msm_cvp_debug.c
+++ b/drivers/media/platform/msm/cvp/msm_cvp_debug.c
@@ -6,7 +6,8 @@
 #define CREATE_TRACE_POINTS
 #define MAX_SSR_STRING_LEN 10
 #include "msm_cvp_debug.h"
-#include "cvp_hfi_api.h"
+#include "msm_cvp_common.h"
+#include "cvp_core_hfi.h"
 
 int msm_cvp_debug = CVP_ERR | CVP_WARN | CVP_FW;
 EXPORT_SYMBOL(msm_cvp_debug);
@@ -190,8 +191,6 @@
 	__debugfs_create(u32, "debug_output", &msm_cvp_debug_out) &&
 	__debugfs_create(bool, "disable_thermal_mitigation",
 			&msm_cvp_thermal_mitigation_disabled) &&
-	__debugfs_create(u32, "core_clock_voting",
-			&msm_cvp_clock_voting) &&
 	__debugfs_create(bool, "disable_cvp_syscache",
 			&msm_cvp_syscache_disable);
 
@@ -209,6 +208,62 @@
 	return NULL;
 }
 
+static int _clk_rate_set(void *data, u64 val)
+{
+	struct msm_cvp_core *core;
+	struct cvp_hfi_device *dev;
+	struct allowed_clock_rates_table *tbl = NULL;
+	unsigned int tbl_size, i;
+
+	core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
+	dev = core->device;
+	tbl = core->resources.allowed_clks_tbl;
+	tbl_size = core->resources.allowed_clks_tbl_size;
+
+	if (val == 0) {
+		struct iris_hfi_device *hdev = dev->hfi_device_data;
+
+		msm_cvp_clock_voting = 0;
+		call_hfi_op(dev, scale_clocks, hdev, hdev->clk_freq);
+		return 0;
+	}
+
+	for (i = 0; i < tbl_size; i++)
+		if (val <= tbl[i].clock_rate)
+			break;
+
+	if (i == tbl_size)
+		msm_cvp_clock_voting = tbl[tbl_size-1].clock_rate;
+	else
+		msm_cvp_clock_voting = tbl[i].clock_rate;
+
+	dprintk(CVP_WARN, "Override cvp_clk_rate with %d\n",
+			msm_cvp_clock_voting);
+
+	call_hfi_op(dev, scale_clocks, dev->hfi_device_data,
+		msm_cvp_clock_voting);
+
+	return 0;
+}
+
+static int _clk_rate_get(void *data, u64 *val)
+{
+	struct msm_cvp_core *core;
+	struct iris_hfi_device *hdev;
+
+	core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
+	hdev = core->device->hfi_device_data;
+	if (msm_cvp_clock_voting)
+		*val = msm_cvp_clock_voting;
+	else
+		*val = hdev->clk_freq;
+
+	return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(clk_rate_fops, _clk_rate_get, _clk_rate_set, "%llu\n");
+
+
 struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core,
 		struct dentry *parent)
 {
@@ -235,6 +290,12 @@
 		dprintk(CVP_ERR, "debugfs_create_file: fail\n");
 		goto failed_create_dir;
 	}
+	if (!debugfs_create_file("clock_rate", 0644, dir,
+			NULL, &clk_rate_fops)) {
+		dprintk(CVP_ERR, "debugfs_create_file: clock_rate fail\n");
+		goto failed_create_dir;
+	}
+
 failed_create_dir:
 	return dir;
 }
@@ -370,7 +431,7 @@
 	info = debugfs_create_file("info", 0444, dir,
 			idata, &inst_info_fops);
 	if (!info) {
-		dprintk(CVP_ERR, "debugfs_create_file: fail\n");
+		dprintk(CVP_ERR, "debugfs_create_file: info fail\n");
 		goto failed_create_file;
 	}
 
diff --git a/drivers/media/platform/msm/cvp/msm_cvp_dsp.c b/drivers/media/platform/msm/cvp/msm_cvp_dsp.c
index 4b6d92e..1eab89a 100644
--- a/drivers/media/platform/msm/cvp/msm_cvp_dsp.c
+++ b/drivers/media/platform/msm/cvp/msm_cvp_dsp.c
@@ -350,6 +350,15 @@
 	return err;
 }
 
+void cvp_dsp_set_cvp_ssr(void)
+{
+	struct cvp_dsp_apps *me = &gfa_cv;
+
+	mutex_lock(&me->smd_mutex);
+	me->cvp_shutdown = STATUS_SSR;
+	mutex_unlock(&me->smd_mutex);
+}
+
 int cvp_dsp_shutdown(uint32_t session_flag)
 {
 	struct msm_cvp_core *core;
@@ -377,7 +386,6 @@
 	}
 
 	mutex_lock(&me->smd_mutex);
-	me->cvp_shutdown = STATUS_SSR;
 	local_cmd_msg.msg_ptr = cmd_msg.msg_ptr;
 	local_cmd_msg.msg_ptr_len = cmd_msg.msg_ptr_len;
 	mutex_unlock(&me->smd_mutex);
diff --git a/drivers/media/platform/msm/cvp/msm_cvp_dsp.h b/drivers/media/platform/msm/cvp/msm_cvp_dsp.h
index ee7a847..6cc14b2 100644
--- a/drivers/media/platform/msm/cvp/msm_cvp_dsp.h
+++ b/drivers/media/platform/msm/cvp/msm_cvp_dsp.h
@@ -54,6 +54,13 @@
 int cvp_dsp_shutdown(uint32_t session_flag);
 
 /*
+ * API for CVP driver to set CVP status during
+ * cvp subsystem error.
+ *
+ */
+void cvp_dsp_set_cvp_ssr(void);
+
+/*
  * API to register iova buffer address with CDSP
  *
  * @session_id:     cvp session id
diff --git a/drivers/media/platform/msm/synx/synx.c b/drivers/media/platform/msm/synx/synx.c
index d801b97..7809130 100644
--- a/drivers/media/platform/msm/synx/synx.c
+++ b/drivers/media/platform/msm/synx/synx.c
@@ -1313,21 +1313,12 @@
 	return 0;
 }
 
-static int synx_close(struct inode *inode, struct file *filep)
+static void synx_table_cleanup(void)
 {
 	int rc = 0;
 	int i;
-	struct synx_device *synx_dev = NULL;
-	struct synx_client *client;
 	struct synx_import_data *data, *tmp_data;
 
-	pr_debug("Enter %s from pid: %d\n", __func__, current->pid);
-
-	synx_dev = get_synx_device(filep);
-	client = filep->private_data;
-
-	mutex_lock(&synx_dev->table_lock);
-
 	synx_dev->open_cnt--;
 	if (!synx_dev->open_cnt) {
 		for (i = 1; i < SYNX_MAX_OBJS; i++) {
@@ -1398,7 +1389,20 @@
 			kfree(data);
 		}
 	}
+}
 
+static int synx_close(struct inode *inode, struct file *filep)
+{
+	struct synx_device *synx_dev = NULL;
+	struct synx_client *client;
+
+	pr_debug("Enter %s from pid: %d\n", __func__, current->pid);
+
+	synx_dev = get_synx_device(filep);
+	client = filep->private_data;
+
+	mutex_lock(&synx_dev->table_lock);
+	synx_table_cleanup();
 	list_del_init(&client->list);
 	kfree(client);
 	mutex_unlock(&synx_dev->table_lock);
@@ -1420,6 +1424,32 @@
 #endif
 };
 
+int synx_initialize(struct synx_initialization_params *params)
+{
+	pr_debug("Enter %s from pid: %d\n", __func__, current->pid);
+
+	mutex_lock(&synx_dev->table_lock);
+	synx_dev->open_cnt++;
+	mutex_unlock(&synx_dev->table_lock);
+
+	if (params)
+		pr_debug("synx client session initialized for %s\n",
+			params->name);
+	return 0;
+}
+
+int synx_uninitialize(void)
+{
+	pr_debug("Enter %s from pid: %d\n",
+		__func__, current->pid);
+
+	mutex_lock(&synx_dev->table_lock);
+	synx_table_cleanup();
+	mutex_unlock(&synx_dev->table_lock);
+
+	return 0;
+}
+
 int synx_register_ops(const struct synx_register_params *params)
 {
 	s32 rc;
diff --git a/drivers/media/platform/msm/synx/synx_api.h b/drivers/media/platform/msm/synx/synx_api.h
index 978a561..a892558 100644
--- a/drivers/media/platform/msm/synx/synx_api.h
+++ b/drivers/media/platform/msm/synx/synx_api.h
@@ -44,6 +44,16 @@
 	u32 type;
 };
 
+/**
+ * struct synx_initialization_params - Session params (optional)
+ *
+ * @name : Client session name
+ *         Only first 64 bytes are accepted, rest will be ignored
+ */
+struct synx_initialization_params {
+	const char *name;
+};
+
 /* Kernel APIs */
 
 /* @brief: Register operations for external synchronization
@@ -71,6 +81,25 @@
 int synx_deregister_ops(const struct synx_register_params *params);
 
 /**
+ * @brief: Initializes a new client session
+ *
+ * @param params : Pointer to session init params
+ *
+ * @return Status of operation. Zero in case of success.
+ * -EINVAL will be returned if params is not valid.
+ * -ENOMEM will be returned if the kernel can't allocate space for
+ * new client
+ */
+int synx_initialize(struct synx_initialization_params *params);
+
+/**
+ * @brief: Destroys the client session
+ *
+ * @return Status of operation. Zero in case of success.
+ */
+int synx_uninitialize(void);
+
+/**
  * @brief: Creates a synx object
  *
  *  The newly created synx obj is assigned to synx_obj.
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 59fbf6f..667c06d 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -1350,17 +1350,19 @@
 				ion_fd, ret);
 		goto err_detach;
 	}
-	*sgt = new_sgt;
-	*attach = new_attach;
-	*dmabuf = new_dma_buf;
 
 	ret = qseecom_create_bridge_for_secbuf(ion_fd, new_dma_buf, new_sgt);
 	if (ret) {
 		pr_err("failed to create bridge for fd %d\n", ion_fd);
-		goto err_detach;
+		goto err_unmap_attachment;
 	}
+	*sgt = new_sgt;
+	*attach = new_attach;
+	*dmabuf = new_dma_buf;
 	return ret;
 
+err_unmap_attachment:
+	dma_buf_unmap_attachment(new_attach, new_sgt, DMA_BIDIRECTIONAL);
 err_detach:
 	dma_buf_detach(new_dma_buf, new_attach);
 err_put:
diff --git a/drivers/net/wireless/ath/wil6210/config.c b/drivers/net/wireless/ath/wil6210/config.c
index 0a63851..6e47f45 100644
--- a/drivers/net/wireless/ath/wil6210/config.c
+++ b/drivers/net/wireless/ath/wil6210/config.c
@@ -668,7 +668,7 @@
 
 		/* parse new line */
 		name = strsep(&buffer, "=");
-		if (!name) {
+		if (!name || !buffer) {
 			wil_err(wil, "file parse error at line %d. expecting '='\n",
 				line_index);
 			rc = -EINVAL;
diff --git a/drivers/net/wireless/cnss2/debug.c b/drivers/net/wireless/cnss2/debug.c
index 8eafc35..4d577aa 100644
--- a/drivers/net/wireless/cnss2/debug.c
+++ b/drivers/net/wireless/cnss2/debug.c
@@ -654,6 +654,9 @@
 		case DISABLE_IO_COHERENCY:
 			seq_puts(s, "DISABLE_IO_COHERENCY");
 			continue;
+		case IGNORE_PCI_LINK_FAILURE:
+			seq_puts(s, "IGNORE_PCI_LINK_FAILURE");
+			continue;
 		}
 
 		seq_printf(s, "UNKNOWN-%d", i);
diff --git a/drivers/net/wireless/cnss2/main.h b/drivers/net/wireless/cnss2/main.h
index 1fa6458..431ea90 100644
--- a/drivers/net/wireless/cnss2/main.h
+++ b/drivers/net/wireless/cnss2/main.h
@@ -242,6 +242,7 @@
 	ENABLE_DAEMON_SUPPORT,
 	DISABLE_DRV,
 	DISABLE_IO_COHERENCY,
+	IGNORE_PCI_LINK_FAILURE,
 };
 
 enum cnss_bdf_type {
diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c
index 6576508..a7e6ed0 100644
--- a/drivers/net/wireless/cnss2/pci.c
+++ b/drivers/net/wireless/cnss2/pci.c
@@ -66,6 +66,9 @@
 #define FORCE_WAKE_DELAY_MAX_US			6000
 #define FORCE_WAKE_DELAY_TIMEOUT_US		60000
 
+#define POWER_ON_RETRY_MAX_TIMES		3
+#define POWER_ON_RETRY_DELAY_MS			200
+
 static struct cnss_pci_reg ce_src[] = {
 	{ "SRC_RING_BASE_LSB", QCA6390_CE_SRC_RING_BASE_LSB_OFFSET },
 	{ "SRC_RING_BASE_MSB", QCA6390_CE_SRC_RING_BASE_MSB_OFFSET },
@@ -391,7 +394,6 @@
 			     u32 offset, u32 *val)
 {
 	int ret;
-	unsigned long flags;
 
 	ret = cnss_pci_check_link_status(pci_priv);
 	if (ret)
@@ -403,12 +405,12 @@
 		return 0;
 	}
 
-	spin_lock_irqsave(&pci_reg_window_lock, flags);
+	spin_lock_bh(&pci_reg_window_lock);
 	cnss_pci_select_window(pci_priv, offset);
 
 	*val = readl_relaxed(pci_priv->bar + WINDOW_START +
 			     (offset & WINDOW_RANGE_MASK));
-	spin_unlock_irqrestore(&pci_reg_window_lock, flags);
+	spin_unlock_bh(&pci_reg_window_lock);
 
 	return 0;
 }
@@ -417,7 +419,6 @@
 			      u32 val)
 {
 	int ret;
-	unsigned long flags;
 
 	ret = cnss_pci_check_link_status(pci_priv);
 	if (ret)
@@ -429,12 +430,12 @@
 		return 0;
 	}
 
-	spin_lock_irqsave(&pci_reg_window_lock, flags);
+	spin_lock_bh(&pci_reg_window_lock);
 	cnss_pci_select_window(pci_priv, offset);
 
 	writel_relaxed(val, pci_priv->bar + WINDOW_START +
 		       (offset & WINDOW_RANGE_MASK));
-	spin_unlock_irqrestore(&pci_reg_window_lock, flags);
+	spin_unlock_bh(&pci_reg_window_lock);
 
 	return 0;
 }
@@ -447,7 +448,8 @@
 
 	ret = cnss_pci_force_wake_request(dev);
 	if (ret) {
-		cnss_pr_err("Failed to request force wake\n");
+		if (ret != -EAGAIN)
+			cnss_pr_err("Failed to request force wake\n");
 		return ret;
 	}
 
@@ -471,7 +473,7 @@
 	int ret;
 
 	ret = cnss_pci_force_wake_release(dev);
-	if (ret)
+	if (ret && ret != -EAGAIN)
 		cnss_pr_err("Failed to release force wake\n");
 
 	return ret;
@@ -710,8 +712,10 @@
 	}
 
 	ret = cnss_set_pci_link(pci_priv, PCI_LINK_UP);
-	if (ret)
+	if (ret) {
+		ret = -EAGAIN;
 		goto out;
+	}
 
 	pci_priv->pci_link_state = PCI_LINK_UP;
 
@@ -804,6 +808,18 @@
 }
 EXPORT_SYMBOL(cnss_pci_is_device_down);
 
+void cnss_pci_lock_reg_window(struct device *dev, unsigned long *flags)
+{
+	spin_lock_bh(&pci_reg_window_lock);
+}
+EXPORT_SYMBOL(cnss_pci_lock_reg_window);
+
+void cnss_pci_unlock_reg_window(struct device *dev, unsigned long *flags)
+{
+	spin_unlock_bh(&pci_reg_window_lock);
+}
+EXPORT_SYMBOL(cnss_pci_unlock_reg_window);
+
 static char *cnss_mhi_state_to_str(enum cnss_mhi_state mhi_state)
 {
 	switch (mhi_state) {
@@ -1549,13 +1565,14 @@
 	int ret = 0;
 	struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
 	unsigned int timeout;
+	int retry = 0;
 
-	if (plat_priv->ramdump_info_v2.dump_data_valid ||
-	    test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) {
+	if (plat_priv->ramdump_info_v2.dump_data_valid) {
 		cnss_pci_clear_dump_info(pci_priv);
 		cnss_pci_deinit_mhi(pci_priv);
 	}
 
+retry:
 	ret = cnss_power_on_device(plat_priv);
 	if (ret) {
 		cnss_pr_err("Failed to power on device, err = %d\n", ret);
@@ -1565,6 +1582,18 @@
 	ret = cnss_resume_pci_link(pci_priv);
 	if (ret) {
 		cnss_pr_err("Failed to resume PCI link, err = %d\n", ret);
+		if (test_bit(IGNORE_PCI_LINK_FAILURE,
+			     &plat_priv->ctrl_params.quirks)) {
+			cnss_pr_dbg("Ignore PCI link resume failure\n");
+			ret = 0;
+			goto out;
+		}
+		if (ret == -EAGAIN && retry++ < POWER_ON_RETRY_MAX_TIMES) {
+			cnss_power_off_device(plat_priv);
+			cnss_pr_dbg("Retry to resume PCI link #%d\n", retry);
+			msleep(POWER_ON_RETRY_DELAY_MS * retry);
+			goto retry;
+		}
 		goto power_off;
 	}
 
@@ -1593,6 +1622,8 @@
 		if (ret)
 			goto stop_mhi;
 	} else if (timeout) {
+		if (test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state))
+			timeout = timeout << 1;
 		mod_timer(&plat_priv->fw_boot_timer,
 			  jiffies + msecs_to_jiffies(timeout << 1));
 	}
@@ -1638,8 +1669,7 @@
 	ret = cnss_suspend_pci_link(pci_priv);
 	if (ret)
 		cnss_pr_err("Failed to suspend PCI link, err = %d\n", ret);
-	if (!plat_priv->ramdump_info_v2.dump_data_valid &&
-	    !test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state))
+	if (!plat_priv->ramdump_info_v2.dump_data_valid)
 		cnss_pci_deinit_mhi(pci_priv);
 
 	cnss_power_off_device(plat_priv);
@@ -1860,7 +1890,7 @@
 
 	timeout = cnss_get_boot_timeout(&pci_priv->pci_dev->dev);
 	ret = wait_for_completion_timeout(&plat_priv->cal_complete,
-					  msecs_to_jiffies(timeout));
+					  msecs_to_jiffies(timeout) << 2);
 	if (!ret) {
 		cnss_pr_err("Timeout waiting for calibration to complete\n");
 		cal_info->cal_status = CNSS_CAL_TIMEOUT;
@@ -2899,11 +2929,22 @@
 
 void cnss_pci_fw_boot_timeout_hdlr(struct cnss_pci_data *pci_priv)
 {
+	struct cnss_plat_data *plat_priv;
+
 	if (!pci_priv)
 		return;
 
 	cnss_fatal_err("Timeout waiting for FW ready indication\n");
 
+	plat_priv = pci_priv->plat_priv;
+	if (!plat_priv)
+		return;
+
+	if (test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state)) {
+		cnss_pr_dbg("Ignore FW ready timeout for calibration mode\n");
+		return;
+	}
+
 	cnss_schedule_recovery(&pci_priv->pci_dev->dev,
 			       CNSS_REASON_TIMEOUT);
 }
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
index 408a206..78e768a 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
@@ -927,7 +927,7 @@
 int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)
 {
 	struct ipa3_ep_context *ep;
-	int i, ipa_ep_idx, wan_handle;
+	int i, ipa_ep_idx, wan_handle, coal_ep_id;
 	int result = -EINVAL;
 	struct ipahal_reg_coal_qmap_cfg qmap_cfg;
 	struct ipahal_reg_coal_evict_lru evict_lru;
@@ -957,6 +957,7 @@
 		goto fail_gen;
 	}
 
+	coal_ep_id = ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_COAL_CONS);
 	/* save the input config parameters */
 	if (sys_in->client == IPA_CLIENT_APPS_WAN_COAL_CONS)
 		ep_cfg_copy = sys_in->ipa_ep_cfg;
@@ -1008,7 +1009,12 @@
 		ep->sys->db_timer.function = ipa3_ring_doorbell_timer_fn;
 
 		/* create IPA PM resources for handling polling mode */
-		if (IPA_CLIENT_IS_CONS(sys_in->client)) {
+		if (sys_in->client == IPA_CLIENT_APPS_WAN_CONS &&
+			coal_ep_id != IPA_EP_NOT_ALLOCATED &&
+			ipa3_ctx->ep[coal_ep_id].valid == 1) {
+			/* Use coalescing pipe PM handle for default pipe also*/
+			ep->sys->pm_hdl = ipa3_ctx->ep[coal_ep_id].sys->pm_hdl;
+		} else if (IPA_CLIENT_IS_CONS(sys_in->client)) {
 			pm_reg.name = ipa_clients_strings[sys_in->client];
 			pm_reg.callback = ipa_pm_sys_pipe_cb;
 			pm_reg.user_data = ep->sys;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c
index 10506c0..1d711e1 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c
@@ -2322,8 +2322,12 @@
 		}
 		if (ul_prod != IPA_CLIENT_MAX) {
 			/* No teth started yet, disable UL channel */
-			ipa_mpm_start_stop_mhip_chan(IPA_MPM_MHIP_CHAN_UL,
-						probe_id, MPM_MHIP_STOP);
+			ret = ipa3_stop_gsi_channel(ipa_ep_idx);
+			if (ret) {
+				IPA_MPM_ERR("MHIP Stop channel err = %d\n",
+					ret);
+				goto fail_stop_channel;
+			}
 		}
 		if (is_acted)
 			ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, true,
@@ -2362,6 +2366,7 @@
 
 fail_gsi_setup:
 fail_start_channel:
+fail_stop_channel:
 fail_smmu:
 	if (ipa_mpm_ctx->dev_info.ipa_smmu_enabled)
 		IPA_MPM_DBG("SMMU failed\n");
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index 645fd62..3a5de5d 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -7634,15 +7634,11 @@
 				client_type);
 		}
 	}
-	if (IPA_CLIENT_IS_PROD(ep->client)) {
-		IPADBG("Calling gsi_stop_channel ch:%lu\n",
-			ep->gsi_chan_hdl);
-		res = gsi_stop_channel(ep->gsi_chan_hdl);
-		IPADBG("gsi_stop_channel ch: %lu returned %d\n",
-			ep->gsi_chan_hdl, res);
-		return res;
-	}
 
+	/*
+	 * Apply the GSI stop retry logic if GSI returns err code to retry.
+	 * Apply the retry logic for ipa_client_prod as well as ipa_client_cons.
+	 */
 	for (i = 0; i < IPA_GSI_CHANNEL_STOP_MAX_RETRY; i++) {
 		IPADBG("Calling gsi_stop_channel ch:%lu\n",
 			ep->gsi_chan_hdl);
diff --git a/drivers/power/supply/qcom/qpnp-smb5.c b/drivers/power/supply/qcom/qpnp-smb5.c
index 86cc6c2..383b1de 100644
--- a/drivers/power/supply/qcom/qpnp-smb5.c
+++ b/drivers/power/supply/qcom/qpnp-smb5.c
@@ -303,11 +303,10 @@
 {
 	struct smb_charger *chg = &chip->chg;
 	struct pmic_revid_data *pmic_rev_id;
-	struct device_node *revid_dev_node;
+	struct device_node *revid_dev_node, *node = chg->dev->of_node;
 	int rc = 0;
 
-	revid_dev_node = of_parse_phandle(chip->chg.dev->of_node,
-					  "qcom,pmic-revid", 0);
+	revid_dev_node = of_parse_phandle(node, "qcom,pmic-revid", 0);
 	if (!revid_dev_node) {
 		pr_err("Missing qcom,pmic-revid property\n");
 		return -EINVAL;
@@ -378,6 +377,12 @@
 	chg->chg_freq.freq_below_otg_threshold	= 800;
 	chg->chg_freq.freq_above_otg_threshold	= 800;
 
+	if (of_property_read_bool(node, "qcom,disable-sw-thermal-regulation"))
+		chg->wa_flags &= ~SW_THERM_REGULATION_WA;
+
+	if (of_property_read_bool(node, "qcom,disable-fcc-restriction"))
+		chg->main_fcc_max = -EINVAL;
+
 out:
 	of_node_put(revid_dev_node);
 	return rc;
diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c
index 437a529..2577100 100644
--- a/drivers/power/supply/qcom/smb5-lib.c
+++ b/drivers/power/supply/qcom/smb5-lib.c
@@ -1869,6 +1869,16 @@
 	u8 stat;
 	int rc, suspend = 0;
 
+	rc = smblib_get_prop_from_bms(chg,
+			POWER_SUPPLY_PROP_DEBUG_BATTERY, &pval);
+	if (rc < 0) {
+		pr_err_ratelimited("Couldn't get debug battery prop rc=%d\n",
+				rc);
+	} else if (pval.intval == 1) {
+		val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+		return 0;
+	}
+
 	if (chg->dbc_usbov) {
 		rc = smblib_get_prop_usb_present(chg, &pval);
 		if (rc < 0) {
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index 0be91c8..c1e399a 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -83,6 +83,7 @@
 	{NULL, "vdd-cx-mx", 752000, 752000, 0, 0, false},
 	{NULL, "vdd-1.8-xo", 1800000, 1800000, 0, 0, false},
 	{NULL, "vdd-1.3-rfa", 1304000, 1304000, 0, 0, false},
+	{NULL, "vdd-3.3-ch1", 3312000, 3312000, 0, 0, false},
 	{NULL, "vdd-3.3-ch0", 3312000, 3312000, 0, 0, false},
 };
 
diff --git a/drivers/thermal/qcom/adc-tm.c b/drivers/thermal/qcom/adc-tm.c
index f8d82d4..537912c 100644
--- a/drivers/thermal/qcom/adc-tm.c
+++ b/drivers/thermal/qcom/adc-tm.c
@@ -350,6 +350,8 @@
 	adc_tm->base = reg;
 	adc_tm->dt_channels = dt_chan_num;
 
+	platform_set_drvdata(pdev, adc_tm);
+
 	revid_dev_node = of_parse_phandle(node, "qcom,pmic-revid", 0);
 	if (revid_dev_node) {
 		adc_tm->pmic_rev_id = get_revid_data(revid_dev_node);
@@ -393,7 +395,6 @@
 	}
 
 	list_add_tail(&adc_tm->list, &adc_tm_device_list);
-	platform_set_drvdata(pdev, adc_tm);
 	return 0;
 fail:
 	i = 0;
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index f92bd98..58ca7ef 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -3514,12 +3514,13 @@
 	}
 
 	/*
-	 * Create freezable workqueue for sm_work so that it gets scheduled only
-	 * after pm_resume has happened completely. This helps in avoiding race
-	 * conditions between xhci_plat_resume and xhci_runtime_resume; and also
-	 * between hcd disconnect and xhci_resume.
+	 * Create an ordered freezable workqueue for sm_work so that it gets
+	 * scheduled only after pm_resume has happened completely. This helps
+	 * in avoiding race conditions between xhci_plat_resume and
+	 * xhci_runtime_resume and also between hcd disconnect and xhci_resume.
 	 */
-	mdwc->sm_usb_wq = create_freezable_workqueue("k_sm_usb");
+	mdwc->sm_usb_wq = alloc_ordered_workqueue("k_sm_usb",
+						WQ_FREEZABLE | WQ_MEM_RECLAIM);
 	if (!mdwc->sm_usb_wq) {
 		destroy_workqueue(mdwc->dwc3_wq);
 		return -ENOMEM;
diff --git a/drivers/usb/gadget/function/f_cdev.c b/drivers/usb/gadget/function/f_cdev.c
index 6060761..3bbf33b 100644
--- a/drivers/usb/gadget/function/f_cdev.c
+++ b/drivers/usb/gadget/function/f_cdev.c
@@ -866,6 +866,9 @@
 {
 	struct f_cdev *port = func_to_port(f);
 
+	/* Reset string id */
+	cser_string_defs[0].id = 0;
+
 	usb_free_all_descriptors(f);
 	usb_cser_free_req(port->port_usb.notify, port->port_usb.notify_req);
 }
diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c
index c9f043d..3211960 100644
--- a/drivers/usb/gadget/function/f_gsi.c
+++ b/drivers/usb/gadget/function/f_gsi.c
@@ -3085,6 +3085,13 @@
 
 	ipa_usb_deinit_teth_prot(gsi->prot_id);
 
+	/* Reset string ids */
+	rndis_gsi_string_defs[0].id = 0;
+	ecm_gsi_string_defs[0].id   = 0;
+	rmnet_gsi_string_defs[0].id = 0;
+	mbim_gsi_string_defs[0].id  = 0;
+	qdss_gsi_string_defs[0].id  = 0;
+
 	if (gsi->prot_id == IPA_USB_RNDIS) {
 		gsi->d_port.sm_state = STATE_UNINITIALIZED;
 		rndis_deregister(gsi->params);
diff --git a/drivers/usb/gadget/function/f_qdss.c b/drivers/usb/gadget/function/f_qdss.c
index 1212e7e..c137669 100644
--- a/drivers/usb/gadget/function/f_qdss.c
+++ b/drivers/usb/gadget/function/f_qdss.c
@@ -511,6 +511,10 @@
 
 	flush_workqueue(qdss->wq);
 
+	/* Reset string ids */
+	qdss_string_defs[QDSS_DATA_IDX].id = 0;
+	qdss_string_defs[QDSS_CTRL_IDX].id = 0;
+
 	qdss->debug_inface_enabled = 0;
 
 	clear_eps(f);
diff --git a/include/dt-bindings/clock/qcom,gcc-bengal.h b/include/dt-bindings/clock/qcom,gcc-bengal.h
index 6e07413..28cde9e 100644
--- a/include/dt-bindings/clock/qcom,gcc-bengal.h
+++ b/include/dt-bindings/clock/qcom,gcc-bengal.h
@@ -173,6 +173,7 @@
 #define GCC_CAMSS_CPHY_0_CLK					165
 #define GCC_CAMSS_CPHY_1_CLK					166
 #define GCC_CAMSS_CPHY_2_CLK					167
+#define GCC_UFS_CLKREF_CLK					168
 
 /* GCC resets */
 #define GCC_QUSB2PHY_PRIM_BCR					0
diff --git a/include/linux/regulator/rpm-smd-regulator.h b/include/linux/regulator/rpm-smd-regulator.h
index 973f77f..901f084 100644
--- a/include/linux/regulator/rpm-smd-regulator.h
+++ b/include/linux/regulator/rpm-smd-regulator.h
@@ -131,3 +131,4 @@
 {
 }
 #endif
+#endif
diff --git a/include/net/cnss2.h b/include/net/cnss2.h
index fa46903..ee6cbb7 100644
--- a/include/net/cnss2.h
+++ b/include/net/cnss2.h
@@ -190,6 +190,9 @@
 extern void cnss_remove_pm_qos(struct device *dev);
 extern void cnss_lock_pm_sem(struct device *dev);
 extern void cnss_release_pm_sem(struct device *dev);
+extern void cnss_pci_lock_reg_window(struct device *dev, unsigned long *flags);
+extern void cnss_pci_unlock_reg_window(struct device *dev,
+				       unsigned long *flags);
 extern int cnss_wlan_pm_control(struct device *dev, bool vote);
 extern int cnss_auto_suspend(struct device *dev);
 extern int cnss_auto_resume(struct device *dev);
diff --git a/mm/compaction.c b/mm/compaction.c
index 2666774..0fca624 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -270,14 +270,15 @@
 
 	/* Ensure the start of the pageblock or zone is online and valid */
 	block_pfn = pageblock_start_pfn(pfn);
-	block_page = pfn_to_online_page(max(block_pfn, zone->zone_start_pfn));
+	block_pfn = max(block_pfn, zone->zone_start_pfn);
+	block_page = pfn_to_online_page(block_pfn);
 	if (block_page) {
 		page = block_page;
 		pfn = block_pfn;
 	}
 
 	/* Ensure the end of the pageblock or zone is online and valid */
-	block_pfn += pageblock_nr_pages;
+	block_pfn = pageblock_end_pfn(pfn) - 1;
 	block_pfn = min(block_pfn, zone_end_pfn(zone) - 1);
 	end_page = pfn_to_online_page(block_pfn);
 	if (!end_page)
@@ -303,7 +304,7 @@
 
 		page += (1 << PAGE_ALLOC_COSTLY_ORDER);
 		pfn += (1 << PAGE_ALLOC_COSTLY_ORDER);
-	} while (page < end_page);
+	} while (page <= end_page);
 
 	return false;
 }
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index d515d13..7bc3a22 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -918,7 +918,7 @@
 	unsigned long nva_start_addr, unsigned long size,
 	enum fit_type type)
 {
-	struct vmap_area *lva;
+	struct vmap_area *lva = NULL;
 
 	if (type == FL_FIT_TYPE) {
 		/*
@@ -977,7 +977,7 @@
 	if (type != FL_FIT_TYPE) {
 		augment_tree_propagate_from(va);
 
-		if (type == NE_FIT_TYPE)
+		if (lva)	/* type == NE_FIT_TYPE */
 			insert_vmap_area_augment(lva, &va->rb_node,
 				&free_vmap_area_root, &free_vmap_area_list);
 	}
@@ -3149,9 +3149,19 @@
 			goto overflow;
 
 		/*
+		 * If required width exeeds current VA block, move
+		 * base downwards and then recheck.
+		 */
+		if (base + end > va->va_end) {
+			base = pvm_determine_end_from_reverse(&va, align) - end;
+			term_area = area;
+			continue;
+		}
+
+		/*
 		 * If this VA does not fit, move base downwards and recheck.
 		 */
-		if (base + start < va->va_start || base + end > va->va_end) {
+		if (base + start < va->va_start) {
 			va = node_to_va(rb_prev(&va->rb_node));
 			base = pvm_determine_end_from_reverse(&va, align) - end;
 			term_area = area;