Merge branch 'android-msm-pixel-4.14-sc-security' into android-msm-pixel-4.14-sc

Oct 2021.1

Bug: 195384623
Change-Id: I56d5a2701708d599d9a7cf3db7092847f2aaf123
diff --git a/Documentation/ABI/testing/sysfs-class-udc b/Documentation/ABI/testing/sysfs-class-udc
new file mode 100644
index 0000000..7501288
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-udc
@@ -0,0 +1,16 @@
+What:		/sys/class/udc/<udc name>/device/usb_data_enabled
+Date:		December 2020
+Contact:	"Ray Chi" <raychi@google.com>
+Description:
+		The attribute can allow user space can check and modify
+		the value to enable or disable usb functionality. Therefore,
+		if the attritube is set to 0, USB host and USB peripheral
+		modes wouldn't be working.
+
+		Example:
+		Enable USB data functionality
+		# echo 1 > /sys/class/udc/.../device/usb_data_enabled
+
+		Disable USB data functionality
+		# echo 0 > /sys/class/udc/.../device/usb_data_enabled
+
diff --git a/arch/arm64/boot/dts/google/sm7150-sunfish-battery.dtsi b/arch/arm64/boot/dts/google/sm7150-sunfish-battery.dtsi
index f6c760a..a3fb8aa 100644
--- a/arch/arm64/boot/dts/google/sm7150-sunfish-battery.dtsi
+++ b/arch/arm64/boot/dts/google/sm7150-sunfish-battery.dtsi
@@ -72,11 +72,12 @@
 &pm6150_qg {
 	qcom,battery-data = <&sunfish_batterydata>;
 	qcom,cl-feedback-on;
-	qcom,cl-max-increment = <5>;
-	qcom,cl-max-decrement = <10>;
+	qcom,cl-max-increment = <3>;
+	qcom,cl-max-decrement = <5>;
 	qcom,cl-min-limit = <500>;
 	qcom,cl-max-limit = <0>;
 	qcom,cl-min-delta-batt-soc = <10>;
+	google,cl-degrade = <50>;
 	qcom,cl-wt-enable;
 	qcom,qg-iterm-ma = <460>;
 	qcom,vbatt-cutoff-mv = <3300>;
@@ -258,6 +259,7 @@
 		google,bd-recharge-soc = <79>;
 		/* Enable TEMP-DEFEND */
 		google,bd-temp-enable;
+		google,bd-temp-dry-run;
 	};
 
 	google_overheat_mitigation: google,overheat_mitigation {
diff --git a/arch/arm64/boot/dts/google/sm8150-floral-battery.dtsi b/arch/arm64/boot/dts/google/sm8150-floral-battery.dtsi
index 2a9cec6..84dde38 100644
--- a/arch/arm64/boot/dts/google/sm8150-floral-battery.dtsi
+++ b/arch/arm64/boot/dts/google/sm8150-floral-battery.dtsi
@@ -227,6 +227,7 @@
 		google,bd-recharge-soc = <79>;
 		/* Enable TEMP-DEFEND */
 		google,bd-temp-enable;
+		google,bd-temp-dry-run;
 	};
 
 	google_wlc_charger: google,wlc_charger {
diff --git a/arch/arm64/boot/dts/google/sm8150-floral-usb.dtsi b/arch/arm64/boot/dts/google/sm8150-floral-usb.dtsi
index 79b24fe..d873803 100644
--- a/arch/arm64/boot/dts/google/sm8150-floral-usb.dtsi
+++ b/arch/arm64/boot/dts/google/sm8150-floral-usb.dtsi
@@ -21,6 +21,7 @@
 &pm8150b_pdphy {
 	google,ext_vbus-supported;
 	ext-vbus-supply = <&ext_5v_boost>;
+	goog,wlc-supported;
 
 	usb_con: connector {
 		compatible = "usb-c-connector";
diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
index c8c5151..3264664 100644
--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
@@ -1836,7 +1836,6 @@
 		qcom,bark-time = <11000>;
 		qcom,pet-time = <9360>;
 		qcom,ipi-ping;
-		qcom,wakeup-enable;
 		qcom,scandump-sizes = <0x10100 0x10100 0x10100 0x10100
 		0x18100 0x18100 0x18100 0x18100>;
 	};
diff --git a/build.config.floral_debug_memory b/build.config.floral_debug_memory
index 811d0d0..c64068f 100644
--- a/build.config.floral_debug_memory
+++ b/build.config.floral_debug_memory
@@ -11,7 +11,6 @@
          -e CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC \
          -e CONFIG_BOOTPARAM_HUNG_TASK_PANIC \
          -e CONFIG_WQ_WATCHDOG \
-         -e CONFIG_PANIC_ON_RT_THROTTLING \
          -e CONFIG_RCU_EQS_DEBUG \
          -e CONFIG_DEVMEM \
          -e CONFIG_DEBUG_OBJECTS \
diff --git a/build.config.sunfish_debug_memory b/build.config.sunfish_debug_memory
index f82f4bb..ce636cb 100644
--- a/build.config.sunfish_debug_memory
+++ b/build.config.sunfish_debug_memory
@@ -11,7 +11,6 @@
          -e CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC \
          -e CONFIG_BOOTPARAM_HUNG_TASK_PANIC \
          -e CONFIG_WQ_WATCHDOG \
-         -e CONFIG_PANIC_ON_RT_THROTTLING \
          -e CONFIG_RCU_EQS_DEBUG \
          -e CONFIG_DEVMEM \
          -e CONFIG_DEBUG_OBJECTS \
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 8ba90ef..6b8fb6b 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2021, 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
@@ -1294,13 +1294,30 @@
 		if (((ctrl->val >> 16) < inst->capability.frame_rate.min ||
 			(ctrl->val >> 16) > inst->capability.frame_rate.max) &&
 			ctrl->val != INT_MAX) {
-			dprintk(VIDC_ERR, "Invalid operating rate %u\n",
-				(ctrl->val >> 16));
-			rc = -ENOTSUPP;
+			if (!is_realtime_session(inst)) {
+				if ((ctrl->val >> 16) <
+					inst->capability.frame_rate.min) {
+					inst->clk_data.operating_rate =
+					inst->capability.frame_rate.min << 16;
+				} else {
+					inst->clk_data.operating_rate =
+					inst->capability.frame_rate.max << 16;
+				}
+				dprintk(VIDC_DBG,
+					"inst(%pK) operating rate capped from %d to %d\n",
+					inst, ctrl->val >> 16,
+					inst->clk_data.operating_rate >> 16);
+				inst->operating_rate_set = true;
+			} else {
+				dprintk(VIDC_ERR, "Invalid operating rate %u\n",
+					(ctrl->val >> 16));
+				rc = -ENOTSUPP;
+			}
 		} else if (ctrl->val == INT_MAX) {
 			dprintk(VIDC_DBG,
 				"inst(%pK) Request for turbo mode\n", inst);
 			inst->clk_data.turbo_mode = true;
+			inst->operating_rate_set = true;
 		} else if (msm_vidc_validate_operating_rate(inst, ctrl->val)) {
 			dprintk(VIDC_ERR, "Failed to set operating rate\n");
 			rc = -ENOTSUPP;
@@ -1310,6 +1327,7 @@
 				inst, inst->clk_data.operating_rate >> 16,
 					ctrl->val >> 16);
 			inst->clk_data.operating_rate = ctrl->val;
+			inst->operating_rate_set = true;
 			inst->clk_data.turbo_mode = false;
 		}
 		break;
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 785eeb83..0e8609f 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2021, 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
@@ -1185,6 +1185,16 @@
 		),
 		.qmenu = roi_map_type,
 	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VENC_COMPLEXITY,
+		.name = "Encoder complexity",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 0,
+		.maximum = 100,
+		.default_value = 100,
+		.step = 1,
+		.qmenu = NULL,
+	},
 };
 
 #define NUM_CTRLS ARRAY_SIZE(msm_venc_ctrls)
@@ -1462,6 +1472,12 @@
 		request_iframe.enable = true;
 		pdata = &request_iframe;
 		break;
+	case V4L2_CID_MPEG_VIDC_VENC_COMPLEXITY:
+		if (is_realtime_session(inst)) {
+			dprintk(VIDC_DBG,
+				"Client is setting complexity for RT session\n");
+		}
+		break;
 	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
 	{
 		struct hal_buffer_requirements *buff_req_buffer = NULL;
@@ -2080,11 +2096,26 @@
 		break;
 	case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE:
 		if (((ctrl->val >> 16) < inst->capability.frame_rate.min ||
-			 (ctrl->val >> 16) > inst->capability.frame_rate.max) &&
-			  ctrl->val != INT_MAX) {
-			dprintk(VIDC_ERR, "Invalid operating rate %u\n",
-				(ctrl->val >> 16));
-			rc = -ENOTSUPP;
+			(ctrl->val >> 16) > inst->capability.frame_rate.max) &&
+			ctrl->val != INT_MAX) {
+			if (!is_realtime_session(inst)) {
+				if ((ctrl->val >> 16) <
+					inst->capability.frame_rate.min) {
+					inst->clk_data.operating_rate =
+					inst->capability.frame_rate.min << 16;
+				} else {
+					inst->clk_data.operating_rate =
+					inst->capability.frame_rate.max << 16;
+				}
+				dprintk(VIDC_DBG,
+					"inst(%pK) operating rate capped from %d to %d\n",
+					inst,  ctrl->val >> 16,
+					inst->clk_data.operating_rate >> 16);
+			} else {
+				dprintk(VIDC_ERR, "Invalid operating rate %u\n",
+					(ctrl->val >> 16));
+				rc = -ENOTSUPP;
+			}
 		} else if (ctrl->val == INT_MAX) {
 			dprintk(VIDC_DBG, "inst(%pK) Request for turbo mode\n",
 				inst);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 28a4e6d..e69e631 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2021, 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
@@ -1165,6 +1165,13 @@
 		goto fail_start;
 	}
 
+	if (inst->session_type == MSM_VIDC_DECODER &&
+		!inst->operating_rate_set && !is_realtime_session(inst)) {
+		inst->clk_data.turbo_mode = true;
+		dprintk(VIDC_INFO,
+			"inst(%pK) setting turbo mode ");
+	}
+
 	/* Assign Core and LP mode for current session */
 	rc = msm_vidc_decide_core_and_power_mode(inst);
 	if (rc) {
@@ -1908,6 +1915,7 @@
 	inst->clk_data.ddr_bw = 0;
 	inst->clk_data.sys_cache_bw = 0;
 	inst->clk_data.bitrate = 0;
+	inst->operating_rate_set = false;
 	inst->clk_data.work_route = 1;
 	inst->clk_data.core_id = VIDC_CORE_ID_DEFAULT;
 	inst->bit_depth = MSM_VIDC_BIT_DEPTH_8;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
index 40d3085..573e3c1 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
@@ -1452,6 +1452,7 @@
 	struct hfi_device *hdev = NULL;
 	enum hal_perf_mode venc_mode;
 	u32 rc_mode = 0;
+	int complexity;
 
 	hdev = inst->core->device;
 	if (inst->session_type != MSM_VIDC_ENCODER) {
@@ -1472,7 +1473,10 @@
 		V4L2_CID_MPEG_VIDEO_BITRATE_MODE);
 	if (rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ)
 		enable = false;
-
+	complexity = msm_comm_g_ctrl_for_id(inst,
+		V4L2_CID_MPEG_VIDC_VENC_COMPLEXITY);
+	if (!is_realtime_session(inst) && !complexity)
+		enable = true;
 	prop_id = HAL_CONFIG_VENC_PERF_MODE;
 	venc_mode = enable ? HAL_PERF_MODE_POWER_SAVE :
 		HAL_PERF_MODE_POWER_MAX_QUALITY;
@@ -1488,9 +1492,9 @@
 	inst->flags = enable ?
 		inst->flags | VIDC_LOW_POWER :
 		inst->flags & ~VIDC_LOW_POWER;
-
 	dprintk(VIDC_PROF,
-		"Power Save Mode for inst: %pK Enable = %d\n", inst, enable);
+			"Power Save Mode for inst: %pK Enable = %d\n",
+			inst, enable);
 fail_power_mode_set:
 	return rc;
 }
@@ -1560,6 +1564,7 @@
 	u32 current_inst_load = 0, current_inst_lp_load = 0,
 		min_load = 0, min_lp_load = 0;
 	u32 min_core_id, min_lp_core_id;
+	u32 complexity;
 
 	if (!inst || !inst->core || !inst->core->device) {
 		dprintk(VIDC_ERR,
@@ -1669,9 +1674,21 @@
 				inst->clk_data.core_id);
 		msm_vidc_move_core_to_power_save_mode(core, min_lp_core_id);
 	} else {
-		rc = -EINVAL;
-		dprintk(VIDC_ERR,
-			"Sorry ... Core Can't support this load\n");
+		complexity = msm_comm_g_ctrl_for_id(inst,
+			V4L2_CID_MPEG_VIDC_VENC_COMPLEXITY);
+		if (!is_realtime_session(inst)) {
+			if (inst->session_type == MSM_VIDC_ENCODER)
+				msm_vidc_power_save_mode_enable(inst,
+					(complexity == 0));
+			inst->clk_data.core_id = min_core_id;
+			dprintk(VIDC_DBG, "Supporting NRT session");
+			goto decision_done;
+
+		} else {
+			rc = -EINVAL;
+			dprintk(VIDC_ERR,
+				"Sorry ... Core Can't support this load\n");
+		}
 		return rc;
 	}
 
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 8718371..40bd328 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2021, 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
@@ -500,6 +500,7 @@
 	struct work_struct batch_work;
 	bool decode_batching;
 	u32 max_filled_length;
+	bool operating_rate_set;
 };
 
 extern struct msm_vidc_drv *vidc_driver;
diff --git a/drivers/power/supply/google/google_battery.c b/drivers/power/supply/google/google_battery.c
index c904f1a..b534580 100644
--- a/drivers/power/supply/google/google_battery.c
+++ b/drivers/power/supply/google/google_battery.c
@@ -2748,6 +2748,12 @@
 	ssoc_state->buck_enabled = ben;
 }
 
+static void bd_trickle_reset(struct batt_ssoc_state *ssoc_state)
+{
+	ssoc_state->bd_trickle_cnt = 0;
+	ssoc_state->disconnect_time = 0;
+}
+
 /* called holding chg_lock */
 static int batt_chg_logic(struct batt_drv *batt_drv)
 {
@@ -4135,6 +4141,26 @@
 
 static DEVICE_ATTR_RW(bd_trickle_reset_sec);
 
+static ssize_t bd_clear_store(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	struct power_supply *psy = container_of(dev, struct power_supply, dev);
+	struct batt_drv *batt_drv = power_supply_get_drvdata(psy);
+	int ret = 0, val = 0;
+
+	ret = kstrtoint(buf, 0, &val);
+	if (ret < 0)
+		return ret;
+
+	if (val)
+		bd_trickle_reset(&batt_drv->ssoc_state);
+
+	return count;
+}
+
+static DEVICE_ATTR_WO(bd_clear);
+
 static ssize_t health_safety_margin_show(struct device *dev,
 				   struct device_attribute *attr, char *buf)
 {
@@ -4187,6 +4213,7 @@
 	&dev_attr_bd_trickle_recharge_soc.attr,
 	&dev_attr_bd_trickle_dry_run.attr,
 	&dev_attr_bd_trickle_reset_sec.attr,
+	&dev_attr_bd_clear.attr,
 	&dev_attr_health_safety_margin.attr,
 	NULL,
 };
diff --git a/drivers/power/supply/google/google_charger.c b/drivers/power/supply/google/google_charger.c
index e3af0fc..98d8f86 100644
--- a/drivers/power/supply/google/google_charger.c
+++ b/drivers/power/supply/google/google_charger.c
@@ -1222,6 +1222,10 @@
 		pr_info("MSC_CHG disable_charging %d -> %d",
 			chg_drv->disable_charging, disable_charging);
 
+		GPSY_SET_PROP(chg_drv->chg_psy,
+			      POWER_SUPPLY_PROP_SAFETY_TIMER_ENABLE,
+			      !disable_charging);
+
 		/* voted but not applied since msc_interval_votable <= 0 */
 		vote(chg_drv->msc_fcc_votable,
 		     MSC_USER_CHG_LEVEL_VOTER,
@@ -2657,6 +2661,40 @@
 static DEVICE_ATTR(bd_temp_dry_run, 0660,
 		   show_bd_temp_dry_run, set_bd_temp_dry_run);
 
+static ssize_t bd_clear_store(struct device *dev, struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	struct chg_drv *chg_drv = dev_get_drvdata(dev);
+	int ret = 0, val = 0;
+
+	ret = kstrtoint(buf, 0, &val);
+	if (ret < 0)
+		return ret;
+
+	if (!val)
+		return ret;
+
+	mutex_lock(&chg_drv->bd_lock);
+
+	ret = bd_batt_set_state(chg_drv, false, -1);
+	if (ret < 0)
+		pr_err("MSC_BD set_batt_state (%d)\n", ret);
+
+	bd_reset(&chg_drv->bd_state);
+
+	if (chg_drv->chg_psy)
+		power_supply_changed(chg_drv->chg_psy);
+
+	mutex_unlock(&chg_drv->bd_lock);
+
+	if (chg_drv->bat_psy)
+		power_supply_changed(chg_drv->bat_psy);
+
+	return count;
+}
+
+static DEVICE_ATTR_WO(bd_clear);
+
 /* TODO: now created in qcom code, create in chg_create_votables() */
 static int chg_find_votables(struct chg_drv *chg_drv)
 {
@@ -3121,6 +3159,12 @@
 		return ret;
 	}
 
+	ret = device_create_file(chg_drv->device, &dev_attr_bd_clear);
+	if (ret != 0) {
+		pr_err("Failed to create bd_clear files, ret=%d\n", ret);
+		return ret;
+	}
+
 #ifdef CONFIG_DEBUG_FS
 	de = debugfs_create_dir("google_charger", 0);
 	if (!de)
diff --git a/drivers/power/supply/google/sm7150_bms.c b/drivers/power/supply/google/sm7150_bms.c
index 20c58a5..909a657 100644
--- a/drivers/power/supply/google/sm7150_bms.c
+++ b/drivers/power/supply/google/sm7150_bms.c
@@ -1081,6 +1081,13 @@
 	case POWER_SUPPLY_PROP_RERUN_AICL:
 		(void)sm7150_rerun_aicl(bms);
 		break;
+	case POWER_SUPPLY_PROP_SAFETY_TIMER_ENABLE:
+		val = pval->intval ? FAST_CHARGE_SAFETY_TIMER_EN : 0;
+		rc = sm7150_masked_write(bms->pmic_regmap,
+					 CHGR_SAFETY_TIMER_ENABLE_CFG_REG,
+					 FAST_CHARGE_SAFETY_TIMER_EN, val);
+		pr_info("SAFETY_TIMER_ENABLE : val=%d (%d)\n", val, rc);
+		break;
 	default:
 		pr_err("setting unsupported property: %d\n", psp);
 		break;
diff --git a/drivers/power/supply/google/sm8150_bms.c b/drivers/power/supply/google/sm8150_bms.c
index 94a002c..0652684 100644
--- a/drivers/power/supply/google/sm8150_bms.c
+++ b/drivers/power/supply/google/sm8150_bms.c
@@ -995,6 +995,13 @@
 	case POWER_SUPPLY_PROP_RERUN_AICL:
 		(void)sm8150_rerun_aicl(bms);
 		break;
+	case POWER_SUPPLY_PROP_SAFETY_TIMER_ENABLE:
+		val = pval->intval ? FAST_CHARGE_SAFETY_TIMER_EN : 0;
+		rc = sm8150_masked_write(bms->pmic_regmap,
+					 CHGR_SAFETY_TIMER_ENABLE_CFG_REG,
+					 FAST_CHARGE_SAFETY_TIMER_EN, val);
+		pr_info("SAFETY_TIMER_ENABLE : val=%d (%d)\n", val, rc);
+		break;
 	default:
 		pr_err("setting unsupported property: %d\n", psp);
 		break;
diff --git a/drivers/power/supply/max1720x_battery.c b/drivers/power/supply/max1720x_battery.c
index bacd4b0..8cad308 100644
--- a/drivers/power/supply/max1720x_battery.c
+++ b/drivers/power/supply/max1720x_battery.c
@@ -1505,7 +1505,7 @@
 
 	if (chip->health_status & MAX1720X_STATUS_TMX) {
 		chip->health_status &= ~MAX1720X_STATUS_TMX;
-		return POWER_SUPPLY_HEALTH_OVERHEAT;
+		return POWER_SUPPLY_HEALTH_HOT;
 	}
 
 	return POWER_SUPPLY_HEALTH_GOOD;
@@ -2848,7 +2848,7 @@
 	pm_runtime_get_sync(chip->dev);
 	if (!chip->init_complete || !chip->resume_complete) {
 		pm_runtime_put_sync(chip->dev);
-		return -EAGAIN;
+		return IRQ_HANDLED;
 	}
 
 	pm_runtime_put_sync(chip->dev);
diff --git a/drivers/power/supply/qcom/fg-alg.c b/drivers/power/supply/qcom/fg-alg.c
index 3df3e25..d3178c7 100644
--- a/drivers/power/supply/qcom/fg-alg.c
+++ b/drivers/power/supply/qcom/fg-alg.c
@@ -19,6 +19,8 @@
 #include <linux/slab.h>
 #include <linux/sort.h>
 #include "fg-alg.h"
+#include "qg-sdam.h"
+#include "qg-reg.h"
 
 #define FULL_SOC_RAW		255
 #define CAPACITY_DELTA_DECIPCT	500
@@ -301,6 +303,22 @@
 	return 0;
 }
 
+static int read_cycle_count(void)
+{
+	u16 count[BUCKET_COUNT];
+	int id, rc;
+	int64_t temp = 0;
+
+	rc = qg_sdam_multibyte_read(QG_SDAM_CYCLE_COUNT_OFFSET, (u8 *)count,
+				    sizeof(count));
+	if (rc < 0)
+		return -EINVAL;
+	for (id = 0; id < BUCKET_COUNT; id++)
+		temp += count[id];
+
+	return (temp / 100);
+}
+
 /* Capacity learning algorithm APIs */
 
 /**
@@ -338,13 +356,29 @@
 	else
 		cl->learned_cap_uah = cl->final_cap_uah;
 
+	if (cl->dt.cap_degrade > 0) {
+		int count = read_cycle_count();
+
+		if (count >= 0) {
+			min_dec_val = (int64_t)cl->nom_cap_uah *
+				      (1000 - (cl->dt.cap_degrade *
+					       ((count / 100) + 1)));
+			min_dec_val = div64_u64(min_dec_val, 1000);
+			if (cl->learned_cap_uah < min_dec_val) {
+				pr_err("capacity %lld below degrade %lld\n",
+				       cl->learned_cap_uah, min_dec_val);
+				cl->learned_cap_uah = min_dec_val;
+			}
+		}
+	}
+
 	if (cl->dt.max_cap_limit >= 0) {
 		max_inc_val = (int64_t)cl->nom_cap_uah * (1000 +
 				cl->dt.max_cap_limit);
 		max_inc_val = div64_u64(max_inc_val, 1000);
-		if (cl->final_cap_uah > max_inc_val) {
+		if (cl->learned_cap_uah > max_inc_val) {
 			pr_debug("learning capacity %lld goes above max limit %lld\n",
-				cl->final_cap_uah, max_inc_val);
+				cl->learned_cap_uah, max_inc_val);
 			cl->learned_cap_uah = max_inc_val;
 		}
 	}
@@ -353,9 +387,9 @@
 		min_dec_val = (int64_t)cl->nom_cap_uah * (1000 -
 				cl->dt.min_cap_limit);
 		min_dec_val = div64_u64(min_dec_val, 1000);
-		if (cl->final_cap_uah < min_dec_val) {
+		if (cl->learned_cap_uah < min_dec_val) {
 			pr_debug("learning capacity %lld goes below min limit %lld\n",
-				cl->final_cap_uah, min_dec_val);
+				cl->learned_cap_uah, min_dec_val);
 			cl->learned_cap_uah = min_dec_val;
 		}
 	}
diff --git a/drivers/power/supply/qcom/fg-alg.h b/drivers/power/supply/qcom/fg-alg.h
index 0bf466c..ba9589a 100644
--- a/drivers/power/supply/qcom/fg-alg.h
+++ b/drivers/power/supply/qcom/fg-alg.h
@@ -48,6 +48,7 @@
 	int	max_cap_dec;
 	int	max_cap_limit;
 	int	min_cap_limit;
+	int	cap_degrade;
 	int	skew_decipct;
 	int	min_delta_batt_soc;
 	int	ibat_flt_thr_ma;
diff --git a/drivers/power/supply/qcom/qpnp-qg.c b/drivers/power/supply/qcom/qpnp-qg.c
index 9d8f528..32ad614 100644
--- a/drivers/power/supply/qcom/qpnp-qg.c
+++ b/drivers/power/supply/qcom/qpnp-qg.c
@@ -4408,6 +4408,12 @@
 		else
 			chip->cl->dt.max_cap_limit = temp;
 
+		rc = of_property_read_u32(node, "google,cl-degrade", &temp);
+		if (rc < 0)
+			chip->cl->dt.cap_degrade = 0;
+		else
+			chip->cl->dt.cap_degrade = temp;
+
 		chip->cl->dt.min_delta_batt_soc = DEFAULT_CL_DELTA_BATT_SOC;
 		/* read from DT property and update, if value exists */
 		of_property_read_u32(node, "qcom,cl-min-delta-batt-soc",
diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c
index 63f0d6c..620ba58 100644
--- a/drivers/power/supply/qcom/smb5-lib.c
+++ b/drivers/power/supply/qcom/smb5-lib.c
@@ -2323,7 +2323,7 @@
 	if (stat & BAT_TEMP_STATUS_TOO_COLD_BIT)
 		val->intval = POWER_SUPPLY_HEALTH_COLD;
 	else if (stat & BAT_TEMP_STATUS_TOO_HOT_BIT)
-		val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
+		val->intval = POWER_SUPPLY_HEALTH_HOT;
 	else if (stat & BAT_TEMP_STATUS_COLD_SOFT_BIT)
 		val->intval = POWER_SUPPLY_HEALTH_COOL;
 	else if (stat & BAT_TEMP_STATUS_HOT_SOFT_BIT)
diff --git a/drivers/power/supply/qcom/smb5-reg.h b/drivers/power/supply/qcom/smb5-reg.h
index 3d7c506..42216be 100644
--- a/drivers/power/supply/qcom/smb5-reg.h
+++ b/drivers/power/supply/qcom/smb5-reg.h
@@ -119,6 +119,10 @@
 #define CHGR_JEITA_THRESHOLD_BASE_REG(i)	(CHGR_BASE + 0x94 + (i * 4))
 #define CHGR_JEITA_HOT_THRESHOLD_MSB_REG	CHGR_JEITA_THRESHOLD_BASE_REG(0)
 
+#define CHGR_SAFETY_TIMER_ENABLE_CFG_REG	(CHGR_BASE + 0xA0)
+#define PRE_CHARGE_SAFETY_TIMER_EN		BIT(1)
+#define FAST_CHARGE_SAFETY_TIMER_EN		BIT(0)
+
 #define CHGR_FAST_CHARGE_SAFETY_TIMER_CFG_REG	(CHGR_BASE + 0xA2)
 #define FAST_CHARGE_SAFETY_TIMER_192_MIN	0x0
 #define FAST_CHARGE_SAFETY_TIMER_384_MIN	0x1
diff --git a/drivers/soc/qcom/watchdog_v2.c b/drivers/soc/qcom/watchdog_v2.c
index 04fa7ca..797f2dd 100644
--- a/drivers/soc/qcom/watchdog_v2.c
+++ b/drivers/soc/qcom/watchdog_v2.c
@@ -161,6 +161,9 @@
 		return 0;
 	__raw_writel(1, wdog_dd->base + WDT0_RST);
 	if (wdog_dd->wakeup_irq_enable) {
+		u64 timeout = (wdog_dd->bark_time * WDT_HZ)/1000;
+
+		__raw_writel(timeout - WDT_HZ, wdog_dd->base + WDT0_BITE_TIME);
 		/* Make sure register write is complete before proceeding */
 		mb();
 		wdog_dd->last_pet = sched_clock();
@@ -181,7 +184,11 @@
 	if (!enable)
 		return 0;
 	if (wdog_dd->wakeup_irq_enable) {
+		u64 timeout = (wdog_dd->bark_time * WDT_HZ)/1000;
+
 		__raw_writel(1, wdog_dd->base + WDT0_RST);
+		__raw_writel(timeout + WDOG_BITE_OFFSET_IN_SECONDS*WDT_HZ,
+				wdog_dd->base + WDT0_BITE_TIME);
 		/* Make sure register write is complete before proceeding */
 		mb();
 		wdog_dd->last_pet = sched_clock();
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 3a772ee..6e6d7c6 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -345,6 +345,7 @@
 	struct device_node *dwc3_node;
 	struct property *num_gsi_eps;
 	bool			dual_port;
+	bool usb_data_enabled;
 };
 
 #define USB_HSPHY_3P3_VOL_MIN		3050000 /* uV */
@@ -3449,6 +3450,9 @@
 	if (!edev || !mdwc)
 		return NOTIFY_DONE;
 
+	if (!mdwc->usb_data_enabled)
+		return NOTIFY_DONE;
+
 	dwc = platform_get_drvdata(mdwc->dwc3);
 
 	dbg_event(0xFF, "extcon idx", enb->idx);
@@ -3508,6 +3512,9 @@
 	if (!edev || !mdwc)
 		return NOTIFY_DONE;
 
+	if (!mdwc->usb_data_enabled)
+		return NOTIFY_DONE;
+
 	dwc = platform_get_drvdata(mdwc->dwc3);
 
 	dbg_event(0xFF, "extcon idx", enb->idx);
@@ -3878,6 +3885,33 @@
 }
 static DEVICE_ATTR_RW(auto_vbus_src_sel_threshold);
 
+static ssize_t usb_data_enabled_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct dwc3_msm *mdwc = dev_get_drvdata(dev);
+
+	return sysfs_emit(buf, "%s\n",
+			  mdwc->usb_data_enabled ? "enabled" : "disabled");
+}
+
+static ssize_t usb_data_enabled_store(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t count)
+{
+	struct dwc3_msm *mdwc = dev_get_drvdata(dev);
+
+	if (kstrtobool(buf, &mdwc->usb_data_enabled))
+		return -EINVAL;
+
+	if (!mdwc->usb_data_enabled) {
+		mdwc->vbus_active = false;
+		mdwc->id_state = DWC3_ID_FLOAT;
+		dwc3_ext_event_notify(mdwc);
+	}
+
+	return count;
+}
+static DEVICE_ATTR_RW(usb_data_enabled);
 
 static int dwc3_msm_populate_gsi_params(struct dwc3_msm *mdwc)
 {
@@ -4337,11 +4371,14 @@
 		dwc3_ext_event_notify(mdwc);
 	}
 
+	/* set the initial value */
+	mdwc->usb_data_enabled = true;
 	device_create_file(&pdev->dev, &dev_attr_mode);
 	device_create_file(&pdev->dev, &dev_attr_speed);
 	device_create_file(&pdev->dev, &dev_attr_usb_compliance_mode);
 	device_create_file(&pdev->dev, &dev_attr_bus_vote);
 	device_create_file(&pdev->dev, &dev_attr_auto_vbus_src_sel_threshold);
+	device_create_file(&pdev->dev, &dev_attr_usb_data_enabled);
 
 	return 0;
 
@@ -4385,6 +4422,7 @@
 	}
 
 	device_remove_file(&pdev->dev, &dev_attr_auto_vbus_src_sel_threshold);
+	device_create_file(&pdev->dev, &dev_attr_usb_data_enabled);
 
 	if (mdwc->usb_psy)
 		power_supply_put(mdwc->usb_psy);
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 7c636a6..c44237d 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -2597,6 +2597,8 @@
 		return true;
 	if (f2fs_is_atomic_file(inode))
 		return true;
+	if (is_sbi_flag_set(sbi, SBI_NEED_FSCK))
+		return true;
 
 	/* swap file is migrating in aligned write mode */
 	if (is_inode_flag_set(inode, FI_ALIGNED_WRITE))
@@ -3959,6 +3961,8 @@
 		get_page(newpage);
 	}
 
+	/* guarantee to start from no stale private field */
+	set_page_private(newpage, 0);
 	if (PagePrivate(page)) {
 		set_page_private(newpage, page_private(page));
 		SetPagePrivate(newpage);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index d15667b4..3c7d4a1 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1333,7 +1333,8 @@
 #define PAGE_PRIVATE_GET_FUNC(name, flagname) \
 static inline bool page_private_##name(struct page *page) \
 { \
-	return test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \
+	return PagePrivate(page) && \
+		test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \
 		test_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
 }
 
@@ -1343,6 +1344,7 @@
 	if (!PagePrivate(page)) { \
 		get_page(page); \
 		SetPagePrivate(page); \
+		set_page_private(page, 0); \
 	} \
 	set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \
 	set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
@@ -1401,6 +1403,7 @@
 	if (!PagePrivate(page)) {
 		get_page(page);
 		SetPagePrivate(page);
+		set_page_private(page, 0);
 	}
 	set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page));
 	page_private(page) |= data << PAGE_PRIVATE_MAX;
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 5be0f1f..51aae16 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -552,7 +552,7 @@
 	int i;
 
 	ni->nid = nid;
-
+retry:
 	/* Check nat cache */
 	down_read(&nm_i->nat_tree_lock);
 	e = __lookup_nat_cache(nm_i, nid);
@@ -564,10 +564,19 @@
 		return 0;
 	}
 
-	memset(&ne, 0, sizeof(struct f2fs_nat_entry));
+	/*
+	 * Check current segment summary by trying to grab journal_rwsem first.
+	 * This sem is on the critical path on the checkpoint requiring the
+	 * above nat_tree_lock. Therefore, we should retry, if we failed to grab
+	 * here while not bothering checkpoint.
+	 */
+	if (!rwsem_is_locked(&sbi->cp_global_sem)) {
+		down_read(&curseg->journal_rwsem);
+	} else if (!down_read_trylock(&curseg->journal_rwsem)) {
+		up_read(&nm_i->nat_tree_lock);
+		goto retry;
+	}
 
-	/* Check current segment summary */
-	down_read(&curseg->journal_rwsem);
 	i = f2fs_lookup_journal_in_cursum(journal, NAT_JOURNAL, nid, 0);
 	if (i >= 0) {
 		ne = nat_in_journal(journal, i);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index c961aed..ad214ee 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3562,7 +3562,7 @@
 		goto drop_bio;
 	}
 
-	if (is_sbi_flag_set(sbi, SBI_NEED_FSCK) || f2fs_cp_error(sbi)) {
+	if (f2fs_cp_error(sbi)) {
 		err = -EIO;
 		goto drop_bio;
 	}
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 1b829dc..2353058 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -1445,6 +1445,9 @@
 	V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED = 1
 };
 
+#define V4L2_CID_MPEG_VIDC_VENC_COMPLEXITY \
+       (V4L2_CID_MPEG_MSM_VIDC_BASE + 167)
+
 /*  Camera class control IDs */
 
 #define V4L2_CID_CAMERA_CLASS_BASE 	(V4L2_CTRL_CLASS_CAMERA | 0x900)
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index efe094b..81fb69c 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -211,6 +211,16 @@
 	s2idle_state = S2IDLE_STATE_NONE;
 }
 
+static void cpu_show_backtrace(void *unused)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	pr_info("Show CPU%d call trace:\n", smp_processor_id());
+	dump_stack();
+	local_irq_restore(flags);
+}
+
 static void s2idle_enter(void)
 {
 	trace_suspend_resume(TPS("machine_suspend"), PM_SUSPEND_TO_IDLE, true);
@@ -232,8 +242,12 @@
 	/* Push all the CPUs into the idle loop. */
 	wake_up_all_idle_cpus();
 	/* Make the current CPU wait so it can enter the idle loop too. */
-	wait_event(s2idle_wait_head,
-		   s2idle_state == S2IDLE_STATE_WAKE);
+	while (!wait_event_timeout(s2idle_wait_head,
+			   s2idle_state == S2IDLE_STATE_WAKE,
+			   msecs_to_jiffies(2000))) {
+		pr_info("s2idle_wait_head timeout, dump cores\n");
+		smp_call_function(cpu_show_backtrace, NULL, 0);
+	}
 
 	cpuidle_pause();
 	put_online_cpus();