LTS: Merge android-4.14-stable (4.14.261) into android-msm-pixel-4.14

Merge android-4.14-stable common kernel (4.14.261) into C2F2/S5 master kernel.

Bug: 213962841
Test: Manual testing, SST, vts/vts-kernel, pts/base, pts/postsubmit-long
Signed-off-by: Lucas Wei <lucaswei@google.com>
Change-Id: I6164f22d3e4cc23d9a7b8d79c585c6cf458fdad1
diff --git a/arch/arm64/configs/floral_defconfig b/arch/arm64/configs/floral_defconfig
index ae47b44..d18a14a 100644
--- a/arch/arm64/configs/floral_defconfig
+++ b/arch/arm64/configs/floral_defconfig
@@ -493,6 +493,7 @@
 CONFIG_HID_STEAM=y
 CONFIG_HID_GREENASIA=y
 CONFIG_GREENASIA_FF=y
+CONFIG_HID_WACOM=y
 CONFIG_HID_WIIMOTE=y
 CONFIG_USB_HIDDEV=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
@@ -531,8 +532,6 @@
 CONFIG_TYPEC_TCPM=y
 CONFIG_USB_PD_ENGINE=y
 CONFIG_QPNP_USB_PDPHY=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_QPNP_FLASH_V2=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_TRANSIENT=y
diff --git a/arch/arm64/configs/sunfish_defconfig b/arch/arm64/configs/sunfish_defconfig
index 7d91361..06ed6b8 100644
--- a/arch/arm64/configs/sunfish_defconfig
+++ b/arch/arm64/configs/sunfish_defconfig
@@ -477,6 +477,7 @@
 CONFIG_SONY_FF=y
 CONFIG_HID_GREENASIA=y
 CONFIG_GREENASIA_FF=y
+CONFIG_HID_WACOM=y
 CONFIG_HID_WIIMOTE=y
 CONFIG_USB_HIDDEV=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
@@ -521,8 +522,6 @@
 CONFIG_TYPEC_TCPM=y
 CONFIG_USB_PD_ENGINE=y
 CONFIG_QPNP_USB_PDPHY=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_QPNP_FLASH_V2=y
 CONFIG_LEDS_QPNP_HAPTICS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c
index df601d4..a973454 100644
--- a/drivers/gpu/msm/adreno_a6xx.c
+++ b/drivers/gpu/msm/adreno_a6xx.c
@@ -1,4 +1,4 @@
-/* Copyright (c)2017-2020, The Linux Foundation. All rights reserved.
+/* Copyright (c)2017-2020,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
@@ -388,6 +388,7 @@
 	{ 0x8D0, 0x23, 0 },
 	{ 0x980, 0x4, 0 },
 	{ 0xA630, 0x0, 1 },
+	{ 0x1b400, 0x1fff, 1 },
 };
 
 /* IFPC & Preemption static powerup restore list */
diff --git a/drivers/media/platform/msm/ais/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/ais/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
index 1a99564..27fcef9 100644
--- a/drivers/media/platform/msm/ais/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
+++ b/drivers/media/platform/msm/ais/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019,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
@@ -750,10 +750,12 @@
 	}
 
 	if ((packet->num_cmd_buf > 5) || !packet->num_patches ||
-		!packet->num_io_configs) {
-		CAM_ERR(CAM_JPEG, "wrong number of cmd/patch info: %u %u",
-			packet->num_cmd_buf,
-			packet->num_patches);
+	    !packet->num_io_configs ||
+	    (packet->num_io_configs > CAM_JPEG_IMAGE_MAX)) {
+		CAM_ERR(CAM_JPEG,
+			"wrong number of cmd/patch/io_configs info: %u %u %u",
+			packet->num_cmd_buf, packet->num_patches,
+			packet->num_io_configs);
 		return -EINVAL;
 	}
 
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
index 1a99564..27fcef9 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019,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
@@ -750,10 +750,12 @@
 	}
 
 	if ((packet->num_cmd_buf > 5) || !packet->num_patches ||
-		!packet->num_io_configs) {
-		CAM_ERR(CAM_JPEG, "wrong number of cmd/patch info: %u %u",
-			packet->num_cmd_buf,
-			packet->num_patches);
+	    !packet->num_io_configs ||
+	    (packet->num_io_configs > CAM_JPEG_IMAGE_MAX)) {
+		CAM_ERR(CAM_JPEG,
+			"wrong number of cmd/patch/io_configs info: %u %u %u",
+			packet->num_cmd_buf, packet->num_patches,
+			packet->num_io_configs);
 		return -EINVAL;
 	}
 
diff --git a/drivers/media/platform/msm/camera_floral/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/camera_floral/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
index 9ea8e3f..ceaa1f6 100644
--- a/drivers/media/platform/msm/camera_floral/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
+++ b/drivers/media/platform/msm/camera_floral/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019,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
@@ -745,10 +745,12 @@
 	}
 
 	if ((packet->num_cmd_buf > 5) || !packet->num_patches ||
-		!packet->num_io_configs) {
-		CAM_ERR(CAM_JPEG, "wrong number of cmd/patch info: %u %u",
-			packet->num_cmd_buf,
-			packet->num_patches);
+	    !packet->num_io_configs ||
+	    (packet->num_io_configs > CAM_JPEG_IMAGE_MAX)) {
+		CAM_ERR(CAM_JPEG,
+			"wrong number of cmd/patch/io_configs info: %u %u %u",
+			packet->num_cmd_buf, packet->num_patches,
+			packet->num_io_configs);
 		return -EINVAL;
 	}
 
diff --git a/drivers/mfd/adnc/iaxxx-btp.c b/drivers/mfd/adnc/iaxxx-btp.c
index d331e42..f727cdf 100644
--- a/drivers/mfd/adnc/iaxxx-btp.c
+++ b/drivers/mfd/adnc/iaxxx-btp.c
@@ -150,6 +150,10 @@
 	 * so calculate the offset and use it for first transaction
 	 */
 	addr_offset = phy_addr % IAXXX_MAC_WINDOW_SIZE;
+	if ((addr_offset >> 2) > btp_size) {
+		ret = -EINVAL;
+		goto exit;
+	}
 
 	while (words) {
 		/* Size of each transfer cannot exceed chunk size */
@@ -230,6 +234,10 @@
 	 * so calculate the offset and use it for first transaction
 	 */
 	addr_offset = phy_addr % IAXXX_MAC_WINDOW_SIZE;
+	if ((addr_offset >> 2) > btp_size) {
+		ret = -EINVAL;
+		goto exit;
+	}
 
 	while (words) {
 		/* Size of each transfer cannot exceed chunk size */
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
index dc2e030..55281f0 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
@@ -3433,18 +3433,22 @@
 	list_for_each_entry(tbl, &set->head_rt_tbl_list, link) {
 		i = 0;
 		list_for_each_entry(entry, &tbl->head_rt_rule_list, link) {
-			if (entry->proc_ctx) {
+			if (entry->proc_ctx && entry->proc_ctx->offset_entry) {
 				ofst = entry->proc_ctx->offset_entry->offset;
 				ofst_words =
 					(ofst +
 					ipa3_ctx->hdr_proc_ctx_tbl.start_offset)
 					>> 5;
 
-				nbytes += scnprintf(msg_buff + nbytes,
-					max_buff_len - nbytes,
-					"tbl_idx:%d tbl_name:%s tbl_ref:%u\n",
-					entry->tbl->idx, entry->tbl->name,
-					entry->tbl->ref_cnt);
+				if (entry->tbl) {
+					nbytes += scnprintf(
+						msg_buff + nbytes,
+						max_buff_len - nbytes,
+						"tbl_idx:%d tbl_name:%s tbl_ref:%u\n",
+						entry->tbl->idx,
+						entry->tbl->name,
+						entry->tbl->ref_cnt);
+				}
 				nbytes += scnprintf(msg_buff + nbytes,
 					max_buff_len - nbytes,
 					"rule_idx:%d dst:%d ep:%d S:%u\n",
@@ -3472,16 +3476,20 @@
 					entry->rule.hashable,
 					entry->rule.retain_hdr);
 			} else {
-				if (entry->hdr)
+				if (entry->hdr && entry->hdr->offset_entry)
 					ofst = entry->hdr->offset_entry->offset;
 				else
 					ofst = 0;
 
-				nbytes += scnprintf(msg_buff + nbytes,
-					max_buff_len - nbytes,
-					"tbl_idx:%d tbl_name:%s tbl_ref:%u\n",
-					entry->tbl->idx, entry->tbl->name,
-					entry->tbl->ref_cnt);
+				if (entry->tbl) {
+					nbytes += scnprintf(
+						msg_buff + nbytes,
+						max_buff_len - nbytes,
+						"tbl_idx:%d tbl_name:%s tbl_ref:%u\n",
+						entry->tbl->idx,
+						entry->tbl->name,
+						entry->tbl->ref_cnt);
+				}
 				nbytes += scnprintf(msg_buff + nbytes,
 					max_buff_len - nbytes,
 					"rule_idx:%d dst:%d ep:%d S:%u\n",
diff --git a/drivers/power/supply/google/google_battery.c b/drivers/power/supply/google/google_battery.c
index 62aba54..47ff65b 100644
--- a/drivers/power/supply/google/google_battery.c
+++ b/drivers/power/supply/google/google_battery.c
@@ -58,6 +58,11 @@
 #define MSC_ERROR_UPDATE_INTERVAL		5000
 #define MSC_DEFAULT_UPDATE_INTERVAL		30000
 
+
+/* AACR default slope is disabled by default */
+#define AACR_START_CYCLE_DEFAULT	100
+#define AACR_MAX_CYCLE_DEFAULT		0 /* disabled */
+
 /* qual time is 0 minutes of charge or 0% increase in SOC */
 #define DEFAULT_CHG_STATS_MIN_QUAL_TIME		0
 #define DEFAULT_CHG_STATS_MIN_DELTA_SOC		0
@@ -75,10 +80,16 @@
 #define HCC_WRITE_AGAIN	0xF0F0
 #define HCC_DEFAULT_DELTA_CYCLE_CNT	25
 
-/* Interval value used when health is settings disabled when not running */
-#define CHG_DEADLINE_SETTING -1
-/* Internal value used when health is settings disabled while running */
-#define CHG_DEADLINE_SETTING_STOP -2
+enum batt_health_ui {
+	/* Internal value used when health is cleared via dialog */
+	CHG_DEADLINE_DIALOG = -3,
+	/* Internal value used when health is settings disabled while running */
+	CHG_DEADLINE_SETTING_STOP = -2,
+	/* Internal value used when health is settings disabled */
+	CHG_DEADLINE_SETTING = -1,
+	/* Internal value used when health is cleared via alarms/re-plug */
+	CHG_DEADLINE_CLEARED = 0,
+};
 
 #undef MODULE_PARAM_PREFIX
 #define MODULE_PARAM_PREFIX     "androidboot."
@@ -230,6 +241,15 @@
 	u16 checksum;	// 0x1A
 };
 
+enum batt_aacr_state {
+	BATT_AACR_UNKNOWN = -3,
+	BATT_AACR_INVALID_CAP = -2,
+	BATT_AACR_UNDER_CYCLES = -1,
+	BATT_AACR_DISABLED = 0,
+	BATT_AACR_ENABLED = 1,
+	BATT_AACR_MAX,
+};
+
 /* battery driver state */
 struct batt_drv {
 	struct device *device;
@@ -288,7 +308,7 @@
 	struct batt_chg_health chg_health;
 
 	/* MSC charging */
-	u32 battery_capacity;
+	u32 battery_capacity;	/* in mAh */
 	struct gbms_chg_profile chg_profile;
 	union gbms_charger_state chg_state;
 
@@ -345,6 +365,11 @@
 	/* Battery pack info for Suez*/
 	char batt_pack_info[GBMS_MINF_LEN];
 	bool pack_info_ready;
+
+	/* AACR: Aged Adjusted Charging Rate */
+	enum batt_aacr_state aacr_state;
+	int aacr_cycle_grace;
+	int aacr_cycle_max;
 };
 
 static int batt_chg_tier_stats_cstr(char *buff, int size,
@@ -1134,8 +1159,7 @@
 	cev_stats_init(ce_data, &batt_drv->chg_profile);
 	batt_drv->ce_data.adapter_details.v = ad.v;
 
-	vin = GPSY_GET_PROP(batt_drv->fg_psy,
-				POWER_SUPPLY_PROP_VOLTAGE_NOW);
+	vin = GPSY_GET_PROP(batt_drv->fg_psy, POWER_SUPPLY_PROP_VOLTAGE_NOW);
 	ce_data->charging_stats.voltage_in = (vin < 0) ? -1 : vin / 1000;
 	ce_data->charging_stats.ssoc_in =
 				ssoc_get_capacity(&batt_drv->ssoc_state);
@@ -1421,6 +1445,8 @@
 			tier_idx = GBMS_STATS_AC_TI_DISABLE_SETTING;
 		else if (rest_deadline == CHG_DEADLINE_SETTING_STOP)
 			tier_idx = GBMS_STATS_AC_TI_DISABLE_SETTING_STOP;
+		else if (rest_deadline == CHG_DEADLINE_DIALOG)
+			tier_idx = GBMS_STATS_AC_TI_DISABLE_DIALOG;
 		else
 			tier_idx = GBMS_STATS_AC_TI_DISABLE_MISC;
 		break;
@@ -1586,7 +1612,7 @@
 			ce_data->adapter_details.ad_voltage * 100,
 			ce_data->adapter_details.ad_amperage * 100);
 
-	logbuffer_log(log, "S: %hu,%hu, %hu,%hu %hu,%hu %ld,%ld",
+	logbuffer_log(log, "S: %hu,%hu, %hu,%hu %hu,%hu %ld,%ld, %u",
 			ce_data->charging_stats.ssoc_in,
 			ce_data->charging_stats.voltage_in,
 			ce_data->charging_stats.ssoc_out,
@@ -1594,7 +1620,8 @@
 			ce_data->charging_stats.cc_in,
 			ce_data->charging_stats.cc_out,
 			ce_data->first_update,
-			ce_data->last_update);
+			ce_data->last_update,
+			ce_data->chg_profile->capacity_ma);
 
 	for (i = 0; i < GBMS_STATS_TIER_COUNT; i++) {
 		const int soc_next = batt_chg_stats_soc_next(ce_data, i);
@@ -1972,8 +1999,12 @@
 	chg_health->rest_cc_max = -1;
 	chg_health->rest_fv_uv = -1;
 
-	/* keep negative deadlines (they mean USER disabled) */
-	if (chg_health->rest_deadline < 0) {
+	/* Keep negative deadlines (they mean user has disabled via settings)
+	 * NOTE: CHG_DEADLINE_DIALOG needs to be applied only for the current
+	 * session. Therefore, it should be cleared on disconnect.
+	 */
+	if (chg_health->rest_deadline < 0 &&
+	    chg_health->rest_deadline != CHG_DEADLINE_DIALOG) {
 		chg_health->rest_state = CHG_HEALTH_USER_DISABLED;
 	} else {
 		chg_health->rest_state = CHG_HEALTH_INACTIVE;
@@ -1981,6 +2012,7 @@
 	}
 
 	chg_health->dry_run_deadline = 0;
+	chg_health->active_time = 0;
 }
 
 /* should not reset rl state */
@@ -2225,13 +2257,14 @@
 
 #define HEALTH_PAUSE_DEBOUNCE 180
 #define HEALTH_PAUSE_MAX_SSOC 95
+#define HEALTH_PAUSE_TIME 3
 static bool msc_health_pause(struct batt_drv *batt_drv, const ktime_t ttf,
 			      const ktime_t now,
 			      const enum chg_health_state rest_state)
 {
 	const struct gbms_charging_event *ce_data = &batt_drv->ce_data;
 	const struct gbms_ce_tier_stats	*h = &ce_data->health_stats;
-	const struct batt_chg_health *rest = &batt_drv->chg_health;
+	struct batt_chg_health *rest = &batt_drv->chg_health;
 	const ktime_t deadline = rest->rest_deadline;
 	const ktime_t safety_margin = (ktime_t)batt_drv->health_safety_margin;
 	/* Note: We only capture ACTIVE time in health stats */
@@ -2256,17 +2289,31 @@
 		return false;
 
 	/*
-	 * elap_h: running active for a while wait status and current stable
 	 * ssoc: transfer in high soc impact charge full condition, disable
 	 * pause behavior in high soc
 	 */
-	if (elap_h < HEALTH_PAUSE_DEBOUNCE || ssoc > HEALTH_PAUSE_MAX_SSOC)
+	if (ssoc > HEALTH_PAUSE_MAX_SSOC)
+		return false;
+
+	/*
+	 * elap_h: running active for a while wait status and current stable
+	 * need to re-check before re-enter pause, so we need to minus previous
+	 * health active time (rest->active_time) for next HEALTH_PAUSE_DEBOUNCE
+	 */
+	if (elap_h - rest->active_time < HEALTH_PAUSE_DEBOUNCE)
+		return false;
+
+	/* prevent enter <---> leave PAUSE too many times */
+	if (rest->active_time > (HEALTH_PAUSE_TIME * HEALTH_PAUSE_DEBOUNCE))
 		return false;
 
 	/* check if time meets the PAUSE condition or not */
 	if (ttf > 0 && deadline > now + ttf + safety_margin)
 		return true;
 
+	/* record time for next pause check */
+	rest->active_time = elap_h;
+
 	return false;
 }
 
@@ -2290,7 +2337,12 @@
 		new_deadline = chg_health->rest_deadline != deadline_s;
 		chg_health->rest_state = CHG_HEALTH_USER_DISABLED;
 
-		if (chg_health->rest_deadline > 0) /* was active */
+		/* disabled with notification; assumes that the dialog exists
+		 * only if there is a >0 deadline.
+		 */
+		if (deadline_s == CHG_DEADLINE_DIALOG)
+			chg_health->rest_deadline = CHG_DEADLINE_DIALOG;
+		else if (chg_health->rest_deadline > 0) /* was active */
 			chg_health->rest_deadline = CHG_DEADLINE_SETTING_STOP;
 		else
 			chg_health->rest_deadline = CHG_DEADLINE_SETTING;
@@ -2304,8 +2356,7 @@
 		if (chg_health->rest_state != CHG_HEALTH_DONE)
 			chg_health->rest_state = CHG_HEALTH_USER_DISABLED;
 
-		/* enabled from any previous state */
-	} else {
+	} else { /* enabled from any previous state */
 		const time_t rest_deadline = get_boot_sec() + deadline_s;
 
 		/* ->always_on SOC overrides the deadline */
@@ -2452,13 +2503,17 @@
 	if (!changed)
 		return false;
 
-	pr_info("MSC_HEALTH: now=%d deadline=%d aon_soc=%d ttf=%ld state=%d->%d fv_uv=%d, cc_max=%d\n",
+	pr_info("MSC_HEALTH: now=%d deadline=%d aon_soc=%d ttf=%ld state=%d->%d fv_uv=%d, cc_max=%d"
+		" safety_margin=%d active_time:%d\n",
 		now, rest->rest_deadline, rest->always_on_soc,
-		ttf, rest->rest_state, rest_state, fv_uv, cc_max);
+		ttf, rest->rest_state, rest_state, fv_uv, cc_max,
+		batt_drv->health_safety_margin, rest->active_time);
 	logbuffer_log(batt_drv->ttf_stats.ttf_log,
-		      "MSC_HEALTH: now=%d deadline=%d aon_soc=%d ttf=%ld state=%d->%d fv_uv=%d, cc_max=%d\n",
+		      "MSC_HEALTH: now=%d deadline=%d aon_soc=%d ttf=%ld state=%d->%d fv_uv=%d, cc_max=%d"
+			  " safety_margin=%d active_time:%d\n",
 		      now, rest->rest_deadline, rest->always_on_soc,
-		      ttf, rest->rest_state, rest_state, fv_uv, cc_max);
+		      ttf, rest->rest_state, rest_state, fv_uv, cc_max,
+			  batt_drv->health_safety_margin, rest->active_time);
 
 	rest->rest_state = rest_state;
 	memcpy(&batt_drv->ce_data.ce_health, &batt_drv->chg_health,
@@ -2517,6 +2572,101 @@
 	return cc_max;
 }
 
+/* same as design when under the grace period */
+static u32 aacr_get_reference_capacity(const struct batt_drv *batt_drv,
+				       int cycle_count)
+{
+	const int design_capacity = batt_drv->battery_capacity;
+	const int aacr_cycle_grace = batt_drv->aacr_cycle_grace;
+	const int aacr_cycle_max = batt_drv->aacr_cycle_max;
+	int fade10;
+
+	fade10 = gbms_aacr_fade10(&batt_drv->chg_profile, cycle_count);
+	if (fade10 >= 0) {
+		/* use interpolation between known points */
+	} else if (aacr_cycle_max && (cycle_count > aacr_cycle_grace)) {
+		/* or use slope from ->aacr_cycle_grace for 20% @
+		 * ->aacr_cycle_max
+		 */
+		fade10 = (200 * (cycle_count -  aacr_cycle_grace)) /
+			 (aacr_cycle_max - aacr_cycle_grace);
+
+		pr_debug("%s: aacr_cycle_max=%d, cycle_count=%d fade10=%d\n",
+			 __func__, aacr_cycle_max, cycle_count, fade10);
+	} else {
+		fade10 = 0;
+	}
+
+	return design_capacity - (design_capacity * fade10 / 1000);
+}
+
+/* 80% of design_capacity min, design_capacity in grace, aacr or negative */
+static int aacr_get_capacity_at_cycle(const struct batt_drv *batt_drv,
+				      int cycle_count)
+{
+	const int design_capacity = batt_drv->battery_capacity; /* mAh */
+	const int min_capacity = (batt_drv->battery_capacity * 80) / 100;
+	int reference_capacity, full_cap_nom, full_capacity;
+	struct power_supply *fg_psy = batt_drv->fg_psy;
+	int aacr_capacity;
+
+	/* batt_drv->cycle_count might be negative */
+	if (cycle_count <= batt_drv->aacr_cycle_grace)
+		return design_capacity;
+
+	/* peg at 80% of design when over limit (if set) */
+	if (batt_drv->aacr_cycle_max &&
+	    (cycle_count >= batt_drv->aacr_cycle_max))
+		return min_capacity;
+
+	reference_capacity = aacr_get_reference_capacity(batt_drv, cycle_count);
+	if (reference_capacity <= 0)
+		return design_capacity;
+
+	/* full_cap_nom in uAh, need to scale to mAh */
+	full_cap_nom = GPSY_GET_PROP(fg_psy, POWER_SUPPLY_PROP_CHARGE_FULL);
+	if (full_cap_nom < 0)
+		return full_cap_nom;
+
+	full_capacity = min(min(full_cap_nom / 1000, design_capacity),
+			    reference_capacity);
+	aacr_capacity = max(full_capacity, min_capacity);
+	aacr_capacity = (aacr_capacity / 50) * 50; /* 50mAh, ~1% capacity */
+
+	pr_debug("%s: design=%d reference=%d full_cap_nom=%d, full=%d aacr=%d\n",
+		 __func__, design_capacity, reference_capacity, full_cap_nom,
+		 full_capacity, aacr_capacity);
+
+	return aacr_capacity;
+}
+
+/* design_capacity when not enabled, never a negative value */
+static u32 aacr_get_capacity(struct batt_drv *batt_drv)
+{
+	int capacity = batt_drv->battery_capacity;
+
+	if (batt_drv->aacr_state == BATT_AACR_DISABLED)
+		goto exit_done;
+
+	if (batt_drv->cycle_count <= batt_drv->aacr_cycle_grace) {
+		batt_drv->aacr_state = BATT_AACR_UNDER_CYCLES;
+	} else {
+		int aacr_capacity;
+
+		aacr_capacity = aacr_get_capacity_at_cycle(batt_drv,
+						batt_drv->cycle_count);
+		if (aacr_capacity < 0) {
+			batt_drv->aacr_state = BATT_AACR_INVALID_CAP;
+		} else {
+			batt_drv->aacr_state = BATT_AACR_ENABLED;
+			capacity = aacr_capacity;
+		}
+	}
+
+exit_done:
+	return (u32)capacity;
+}
+
 /* TODO: factor msc_logic_irdop from the logic about tier switch */
 static int msc_logic(struct batt_drv *batt_drv)
 {
@@ -2568,7 +2718,9 @@
 
 		msc_state = MSC_SEED;
 
-		/* seed voltage only on connect, book 0 time */
+		/* seed voltage and charging table only on connect,
+		 * book 0 time
+		 */
 		if (batt_drv->vbatt_idx == -1)
 			vbatt_idx = gbms_msc_voltage_idx(profile, vbatt);
 
@@ -2783,6 +2935,18 @@
 	ce_data->bd_clear_trickle = true;
 }
 
+static void google_battery_dump_profile(const struct gbms_chg_profile *profile)
+{
+	char *buff;
+
+	buff = kzalloc(GBMS_CHG_ALG_BUF, GFP_KERNEL);
+	if (buff) {
+		gbms_dump_chg_profile(buff, GBMS_CHG_ALG_BUF, profile);
+		pr_info("%s", buff);
+		kfree(buff);
+	}
+}
+
 /* called holding chg_lock */
 static int batt_chg_logic(struct batt_drv *batt_drv)
 {
@@ -2841,7 +3005,9 @@
 
 	/* here when connected to power supply */
 	if (batt_drv->ssoc_state.buck_enabled <= 0) {
+		struct device_node *node = batt_drv->device->of_node;
 		const qnum_t ssoc_delta = ssoc_get_delta(batt_drv);
+		u32 capacity;
 
 		/*
 		 * FIX: BatteryDefenderUI needs use a different curve because
@@ -2856,6 +3022,13 @@
 		if (batt_drv->res_state.estimate_filter)
 			batt_res_state_set(&batt_drv->res_state, true);
 
+		capacity = aacr_get_capacity(batt_drv);
+		if (capacity != batt_drv->chg_profile.capacity_ma) {
+			gbms_init_chg_table(&batt_drv->chg_profile, node,
+					    capacity);
+			google_battery_dump_profile(&batt_drv->chg_profile);
+		}
+
 		batt_chg_stats_start(batt_drv);
 		err = GPSY_SET_PROP(batt_drv->fg_psy,
 				    POWER_SUPPLY_PROP_BATT_CE_CTRL,
@@ -3010,8 +3183,8 @@
 /* charge profile not in battery */
 static int batt_init_chg_profile(struct batt_drv *batt_drv)
 {
-	struct device_node *node = batt_drv->device->of_node;
 	struct gbms_chg_profile *profile = &batt_drv->chg_profile;
+	struct device_node *node = batt_drv->device->of_node;
 	int ret = 0;
 
 	/* handle retry */
@@ -3021,6 +3194,7 @@
 			return -EINVAL;
 	}
 
+	/* this is in mAh */
 	ret = of_property_read_u32(node, "google,chg-battery-capacity",
 				   &batt_drv->battery_capacity);
 	if (ret < 0)
@@ -3036,7 +3210,7 @@
 
 		if (batt_drv->batt_present) {
 			fc = GPSY_GET_PROP(fg_psy,
-					POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN);
+				POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN);
 			if (fc == -EAGAIN)
 				return -EPROBE_DEFER;
 			if (fc > 0) {
@@ -3056,12 +3230,17 @@
 			if (ret < 0)
 				pr_warn("battery not present, no default capacity, zero charge table\n");
 			else
-				pr_warn("battery not present, using default capacity:\n");
+				pr_warn("battery not present, using default capacity\n");
 		}
 	}
 
+	/* aacr tables enable AACR by default UNLESS explicitly disabled */
+	ret = of_property_read_bool(node, "google,aacr-disable");
+	if (!ret && profile->aacr_nb_limits)
+		batt_drv->aacr_state = BATT_AACR_ENABLED;
+
 	/* NOTE: with NG charger tolerance is applied from "charger" */
-	gbms_init_chg_table(&batt_drv->chg_profile, batt_drv->battery_capacity);
+	gbms_init_chg_table(profile, node, aacr_get_capacity(batt_drv));
 
 	return 0;
 }
@@ -3481,6 +3660,77 @@
 			debug_chg_health_set_stage, "%u\n");
 #endif
 
+/* debug variable */
+static int raw_profile_cycles;
+
+static ssize_t debug_get_chg_raw_profile(struct file *filp,
+					 char __user *buf,
+					 size_t count, loff_t *ppos)
+{
+	struct batt_drv *batt_drv = (struct batt_drv *)filp->private_data;
+	char *tmp;
+	int len;
+
+	tmp = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!tmp)
+		return -ENOMEM;
+
+	if (raw_profile_cycles) {
+		struct gbms_chg_profile profile;
+		int count;
+
+		len = gbms_init_chg_profile(&profile,
+					    batt_drv->device->of_node);
+		if (len < 0)
+			goto exit_done;
+
+		/* len is the capacity */
+		len = aacr_get_capacity_at_cycle(batt_drv, raw_profile_cycles);
+		if (len <= 0) {
+			gbms_free_chg_profile(&profile);
+			goto exit_done;
+		}
+
+		count = scnprintf(tmp, PAGE_SIZE, "AACR Profile at %d cycles\n",
+				  raw_profile_cycles);
+		gbms_init_chg_table(&profile, batt_drv->device->of_node, len);
+		gbms_dump_chg_profile(&tmp[count], PAGE_SIZE - count, &profile);
+		gbms_free_chg_profile(&profile);
+	} else {
+		gbms_dump_chg_profile(tmp, PAGE_SIZE, &batt_drv->chg_profile);
+	}
+
+	len = simple_read_from_buffer(buf, count, ppos, tmp, strlen(tmp));
+
+exit_done:
+	kfree(tmp);
+	return len;
+}
+
+static ssize_t debug_set_chg_raw_profile(struct file *filp,
+					 const char __user *user_buf,
+					 size_t count, loff_t *ppos)
+{
+	int ret = 0, val;
+	char buf[8];
+
+	ret = simple_write_to_buffer(buf, sizeof(buf), ppos, user_buf, count);
+	if (!ret)
+		return -EFAULT;
+
+	buf[ret] = '\0';
+	ret = kstrtoint(buf, 0, &val);
+	if (ret < 0)
+		return ret;
+
+	raw_profile_cycles = val;
+	return count;
+}
+
+BATTERY_DEBUG_ATTRIBUTE(debug_chg_raw_profile_fops,
+			debug_get_chg_raw_profile,
+			debug_set_chg_raw_profile);
+
 /* ------------------------------------------------------------------------- */
 static ssize_t charge_stats_actual_store(struct device *dev,
 					 struct device_attribute *attr,
@@ -4250,6 +4500,93 @@
 
 static DEVICE_ATTR_RW(health_safety_margin);
 
+static ssize_t aacr_state_show(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct power_supply *psy = container_of(dev, struct power_supply, dev);
+	struct batt_drv *batt_drv = power_supply_get_drvdata(psy);
+
+	return scnprintf(buf, PAGE_SIZE, "%d\n", batt_drv->aacr_state);
+}
+
+static ssize_t aacr_state_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 state, ret = 0;
+
+	ret = kstrtoint(buf, 0, &state);
+	if (ret < 0)
+		return ret;
+
+	if ((state != BATT_AACR_DISABLED) && (state != BATT_AACR_ENABLED))
+		return -ERANGE;
+
+	if (batt_drv->aacr_state == state)
+		return count;
+
+	batt_drv->aacr_state = state;
+	return count;
+}
+
+static DEVICE_ATTR_RW(aacr_state);
+
+static ssize_t aacr_cycle_grace_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct power_supply *psy = container_of(dev, struct power_supply, dev);
+	struct batt_drv *batt_drv = power_supply_get_drvdata(psy);
+
+	return scnprintf(buf, PAGE_SIZE, "%d\n", batt_drv->aacr_cycle_grace);
+}
+
+static ssize_t aacr_cycle_grace_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 value, ret = 0;
+
+	ret = kstrtoint(buf, 0, &value);
+	if (ret < 0)
+		return ret;
+
+	batt_drv->aacr_cycle_grace = value;
+	return count;
+}
+
+static DEVICE_ATTR_RW(aacr_cycle_grace);
+
+static ssize_t aacr_cycle_max_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct power_supply *psy = container_of(dev, struct power_supply, dev);
+	struct batt_drv *batt_drv = power_supply_get_drvdata(psy);
+
+	return scnprintf(buf, PAGE_SIZE, "%d\n", batt_drv->aacr_cycle_max);
+}
+
+static ssize_t aacr_cycle_max_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 value, ret = 0;
+
+	ret = kstrtoint(buf, 0, &value);
+	if (ret < 0)
+		return ret;
+
+	batt_drv->aacr_cycle_max = value;
+	return count;
+}
+
+static DEVICE_ATTR_RW(aacr_cycle_max);
+
 static struct attribute *batt_attrs[] = {
 	&dev_attr_charge_stats.attr,
 	&dev_attr_charge_stats_actual.attr,
@@ -4270,6 +4607,9 @@
 	&dev_attr_bd_trickle_reset_sec.attr,
 	&dev_attr_bd_clear.attr,
 	&dev_attr_health_safety_margin.attr,
+	&dev_attr_aacr_state.attr,
+	&dev_attr_aacr_cycle_grace.attr,
+	&dev_attr_aacr_cycle_max.attr,
 	NULL,
 };
 
@@ -4322,6 +4662,10 @@
 				    batt_drv, &debug_chg_health_rest_rate_fops);
 		debugfs_create_file("chg_health_stage", 0600, de,
 				    batt_drv, &debug_chg_health_stage_fops);
+
+		/* charging table */
+		debugfs_create_file("chg_raw_profile", 0644, de,
+				    batt_drv, &debug_chg_raw_profile_fops);
 	}
 #endif
 
@@ -5477,6 +5821,7 @@
 
 	dump_ssoc_state(&batt_drv->ssoc_state, batt_drv->ssoc_log);
 
+	/* chg_profile will use cycle_count when aacr is enabled */
 	ret = batt_init_chg_profile(batt_drv);
 	if (ret == -EPROBE_DEFER)
 		goto retry_init_work;
@@ -5484,7 +5829,7 @@
 	if (ret < 0) {
 		pr_err("charging profile disabled, ret=%d\n", ret);
 	} else if (batt_drv->battery_capacity) {
-		gbms_dump_chg_profile(&batt_drv->chg_profile);
+		google_battery_dump_profile(&batt_drv->chg_profile);
 	}
 
 	cev_stats_init(&batt_drv->ce_data, &batt_drv->chg_profile);
@@ -5727,6 +6072,12 @@
 	} else {
 		thermal_zone_device_update(batt_drv->tz_dev, THERMAL_DEVICE_UP);
 	}
+
+	/* AACR server side */
+	batt_drv->aacr_cycle_grace = AACR_START_CYCLE_DEFAULT;
+	batt_drv->aacr_cycle_max = AACR_MAX_CYCLE_DEFAULT;
+	batt_drv->aacr_state = BATT_AACR_DISABLED;
+
 	/* give time to fg driver to start */
 	schedule_delayed_work(&batt_drv->init_work,
 					msecs_to_jiffies(BATT_DELAY_INIT_MS));
diff --git a/drivers/power/supply/google/google_bms.c b/drivers/power/supply/google/google_bms.c
index 57de959..4e6fdfc 100644
--- a/drivers/power/supply/google/google_bms.c
+++ b/drivers/power/supply/google/google_bms.c
@@ -82,14 +82,23 @@
  * NOTE: the call covert C rates to chanrge currents IN PLACE, ie you cannot
  * call this twice.
  */
-void gbms_init_chg_table(struct gbms_chg_profile *profile, u32 capacity_ma)
+void gbms_init_chg_table(struct gbms_chg_profile *profile,
+			 struct device_node *node, u32 capacity_ma)
 {
 	u32 ccm;
-	int vi, ti;
+	int vi, ti, ret;
 	const int fv_uv_step = profile->fv_uv_resolution;
+	u32 cccm_array_size = (profile->temp_nb_limits - 1)
+			       * profile->volt_nb_limits;
 
 	profile->capacity_ma = capacity_ma;
 
+	ret = of_property_read_u32_array(node, "google,chg-cc-limits",
+					 (u32 *)profile->cccm_limits,
+					 cccm_array_size);
+	if (ret < 0)
+		pr_warn("unable to get default cccm_limits.\n");
+
 	/* chg-battery-capacity is in mAh, chg-cc-limits relative to 100 */
 	for (ti = 0; ti < profile->temp_nb_limits - 1; ti++) {
 		for (vi = 0; vi < profile->volt_nb_limits; vi++) {
@@ -159,6 +168,85 @@
 	return 0;
 }
 
+static int gbms_read_aacr_limits(struct gbms_chg_profile *profile,
+				 struct device_node *node)
+{
+	int ret = 0, cycle_nb_limits = 0, fade10_nb_limits = 0;
+
+	ret = of_property_count_elems_of_size(node,
+					      "google,aacr-ref-cycles",
+					      sizeof(u32));
+	if (ret < 0)
+		goto no_data;
+
+	cycle_nb_limits = ret;
+
+	ret = of_property_count_elems_of_size(node,
+					      "google,aacr-ref-fade10",
+					      sizeof(u32));
+	if (ret < 0)
+		goto no_data;
+
+	fade10_nb_limits = ret;
+
+	if (cycle_nb_limits != fade10_nb_limits ||
+	    cycle_nb_limits > GBMS_AACR_DATA_MAX ||
+	    cycle_nb_limits == 0) {
+		gbms_warn(profile,
+			  "aacr not enable, cycle_nb:%d, fade10_nb:%d, max:%d",
+			  cycle_nb_limits, fade10_nb_limits,
+			  GBMS_AACR_DATA_MAX);
+		profile->aacr_nb_limits = 0;
+		return -ERANGE;
+	}
+
+	ret = of_property_read_u32_array(node, "google,aacr-ref-cycles",
+					 (u32 *)profile->reference_cycles,
+					 cycle_nb_limits);
+	if (ret < 0)
+		return ret;
+
+	ret = of_property_read_u32_array(node, "google,aacr-ref-fade10",
+					 (u32 *)profile->reference_fade10,
+					 fade10_nb_limits);
+	if (ret < 0)
+		return ret;
+
+	profile->aacr_nb_limits = cycle_nb_limits;
+
+	return 0;
+
+no_data:
+	profile->aacr_nb_limits = 0;
+	return ret;
+}
+
+/* return pct amount of capacity fade at cycles or negative if not enabled */
+int gbms_aacr_fade10(const struct gbms_chg_profile *profile, int cycles)
+{
+	int cycle_s = 0, fade_s = 0;
+	int idx, cycle_f, fade_f;
+
+	if (profile->aacr_nb_limits == 0 || cycles < 0)
+		return -EINVAL;
+
+	for (idx = 0; idx < profile->aacr_nb_limits; idx++)
+		if (cycles < profile->reference_cycles[idx])
+			break;
+
+	/* Interpolation */
+	cycle_f = profile->reference_cycles[idx];
+	fade_f = profile->reference_fade10[idx];
+	if (idx > 0) {
+		cycle_s = profile->reference_cycles[idx - 1];
+		fade_s = profile->reference_fade10[idx - 1];
+	}
+
+	return (cycles - cycle_s) * (fade_f - fade_s) / (cycle_f - cycle_s)
+		+ fade_s;
+}
+EXPORT_SYMBOL_GPL(gbms_aacr_fade10);
+
 int gbms_init_chg_profile_internal(struct gbms_chg_profile *profile,
 			  struct device_node *node,
 			  const char *owner_name)
@@ -172,6 +260,11 @@
 	if (ret < 0)
 		return ret;
 
+	/* TODO: dump the AACR table if supported */
+	ret = gbms_read_aacr_limits(profile, node);
+	if (ret == 0)
+		gbms_info(profile, "AACR: supported\n");
+
 	cccm_array_size = (profile->temp_nb_limits - 1)
 			  * profile->volt_nb_limits;
 	mem_size = sizeof(s32) * cccm_array_size;
@@ -276,23 +369,22 @@
 }
 
 /* NOTE: I should really pass the scale */
-void gbms_dump_raw_profile(const struct gbms_chg_profile *profile, int scale)
+void gbms_dump_raw_profile(char *buff, size_t len,
+			   const struct gbms_chg_profile *profile, int scale)
 {
 	const int tscale = (scale == 1) ? 1 : 10;
-	/* with scale == 1 voltage takes 7 bytes, add 7 bytes of temperature */
-	char buff[GBMS_CHG_VOLT_NB_LIMITS_MAX * 9 + 7];
-	int ti, vi, count, len = sizeof(buff);
+	int ti, vi, count = 0;
 
-	gbms_info(profile, "Profile constant charge limits:\n");
-	count = 0;
+	count += scnprintf(buff + count, len - count,
+			   "Profile constant charge limits:\n");
+	count += scnprintf(buff + count, len - count, "|T \\ V");
 	for (vi = 0; vi < profile->volt_nb_limits; vi++) {
 		count += scnprintf(buff + count, len - count, "  %4d",
 				   profile->volt_limits[vi] / scale);
 	}
-	gbms_info(profile, "|T \\ V%s\n", buff);
+	count += scnprintf(buff + count, len - count, "\n");
 
 	for (ti = 0; ti < profile->temp_nb_limits - 1; ti++) {
-		count = 0;
 		count += scnprintf(buff + count, len - count, "|%2d:%2d",
 				   profile->temp_limits[ti] / tscale,
 				   profile->temp_limits[ti + 1] / tscale);
@@ -301,7 +393,7 @@
 					   GBMS_CCCM_LIMITS(profile, ti, vi)
 					   / scale);
 		}
-		gbms_info(profile, "%s\n", buff);
+		count += scnprintf(buff + count, len - count, "\n");
 	}
 }
 
diff --git a/drivers/power/supply/google/google_bms.h b/drivers/power/supply/google/google_bms.h
index 0551395..477641f 100644
--- a/drivers/power/supply/google/google_bms.h
+++ b/drivers/power/supply/google/google_bms.h
@@ -17,6 +17,7 @@
 #ifndef __GOOGLE_BMS_H_
 #define __GOOGLE_BMS_H_
 
+#include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/power_supply.h>
 #include "qmath.h"
@@ -26,6 +27,8 @@
 
 #define GBMS_CHG_TEMP_NB_LIMITS_MAX 10
 #define GBMS_CHG_VOLT_NB_LIMITS_MAX 6
+#define GBMS_CHG_ALG_BUF 500
+#define GBMS_AACR_DATA_MAX 10
 
 struct gbms_chg_profile {
 	const char *owner_name;
@@ -53,6 +56,11 @@
 	u32 fv_uv_resolution;
 	/* experimental */
 	u32 cv_otv_margin;
+
+	/* AACR feature */
+	u32 reference_cycles[GBMS_AACR_DATA_MAX];
+	u32 reference_fade10[GBMS_AACR_DATA_MAX];
+	u32 aacr_nb_limits;
 };
 
 #define WLC_BPP_THRESHOLD_UV	700000
@@ -241,6 +249,7 @@
 
 /* tier index used to log the session */
 enum gbms_stats_tier_idx_t {
+	GBMS_STATS_AC_TI_DISABLE_DIALOG = -6,
 	GBMS_STATS_AC_TI_DEFENDER = -5,
 	GBMS_STATS_AC_TI_DISABLE_SETTING_STOP = -4,
 	GBMS_STATS_AC_TI_DISABLE_MISC = -3,
@@ -284,6 +293,7 @@
 	enum chg_health_state rest_state;
 	int rest_cc_max;
 	int rest_fv_uv;
+	ktime_t active_time;
 };
 
 #define CHG_HEALTH_REST_IS_ACTIVE(rest) \
@@ -358,12 +368,15 @@
 #define gbms_init_chg_profile(p, n) \
 	gbms_init_chg_profile_internal(p, n, KBUILD_MODNAME)
 
-void gbms_init_chg_table(struct gbms_chg_profile *profile, u32 capacity);
+void gbms_init_chg_table(struct gbms_chg_profile *profile,
+			 struct device_node *node, u32 capacity);
 
 void gbms_free_chg_profile(struct gbms_chg_profile *profile);
 
-void gbms_dump_raw_profile(const struct gbms_chg_profile *profile, int scale);
-#define gbms_dump_chg_profile(profile) gbms_dump_raw_profile(profile, 1000)
+void gbms_dump_raw_profile(char *buff, size_t len,
+			   const struct gbms_chg_profile *profile, int scale);
+#define gbms_dump_chg_profile(buff, len, profile) \
+	gbms_dump_raw_profile(buff, len, profile, 1000)
 
 /* newgen charging: charge profile */
 int gbms_msc_temp_idx(const struct gbms_chg_profile *profile, int temp);
@@ -378,6 +391,9 @@
 			    struct power_supply *chg_psy,
 			    struct power_supply *wlc_psy);
 
+/* calculate aacr reference capacity */
+int gbms_aacr_fade10(const struct gbms_chg_profile *profile, int cycles);
+
 /* debug/print */
 const char *gbms_chg_type_s(int chg_type);
 const char *gbms_chg_status_s(int chg_status);
diff --git a/drivers/power/supply/google/sm7150_bms.c b/drivers/power/supply/google/sm7150_bms.c
index 909a657..aecf04d 100644
--- a/drivers/power/supply/google/sm7150_bms.c
+++ b/drivers/power/supply/google/sm7150_bms.c
@@ -630,8 +630,6 @@
 	case SM7150_TAPER_CHARGE:
 		ret = POWER_SUPPLY_STATUS_CHARGING;
 		break;
-	/* pause on FCC=0, JEITA, USB/DC suspend or on INPUT UV/OV */
-	case SM7150_PAUSE_CHARGE:
 	case SM7150_INHIBIT_CHARGE:
 	case SM7150_TERMINATE_CHARGE:
 		/* flag full only at the correct voltage */
@@ -643,6 +641,8 @@
 		else
 			ret = POWER_SUPPLY_STATUS_FULL;
 		break;
+	/* pause on JEITA, USB/DC suspend or on INPUT UV/OV */
+	case SM7150_PAUSE_CHARGE:
 	/* disabled disconnect */
 	case SM7150_DISABLE_CHARGE:
 		ret = POWER_SUPPLY_STATUS_NOT_CHARGING;
diff --git a/drivers/power/supply/google/sm8150_bms.c b/drivers/power/supply/google/sm8150_bms.c
index 0652684..37ef7b0f 100644
--- a/drivers/power/supply/google/sm8150_bms.c
+++ b/drivers/power/supply/google/sm8150_bms.c
@@ -660,8 +660,6 @@
 	case SM8150_TAPER_CHARGE:
 		ret = POWER_SUPPLY_STATUS_CHARGING;
 		break;
-	/* pause on FCC=0, JEITA, USB/DC suspend or on INPUT UV/OV */
-	case SM8150_PAUSE_CHARGE:
 	case SM8150_INHIBIT_CHARGE:
 	case SM8150_TERMINATE_CHARGE:
 		/* flag full only at the correct voltage */
@@ -673,6 +671,8 @@
 		else
 			ret = POWER_SUPPLY_STATUS_FULL;
 		break;
+	/* pause on JEITA, USB/DC suspend or on INPUT UV/OV */
+	case SM8150_PAUSE_CHARGE:
 	/* disabled disconnect */
 	case SM8150_DISABLE_CHARGE:
 		ret = POWER_SUPPLY_STATUS_NOT_CHARGING;
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 0243779..b6bfc24 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1802,11 +1802,13 @@
 	if (atomic_dec_and_test(&ffs->opened)) {
 		if (ffs->no_disconnect) {
 			ffs->state = FFS_DEACTIVATED;
+			mutex_lock(&ffs->mutex);
 			if (ffs->epfiles) {
 				ffs_epfiles_destroy(ffs->epfiles,
 						   ffs->eps_count);
 				ffs->epfiles = NULL;
 			}
+			mutex_unlock(&ffs->mutex);
 			if (ffs->setup_state == FFS_SETUP_PENDING)
 				__ffs_ep0_stall(ffs);
 		} else {
@@ -1878,10 +1880,12 @@
 
 	BUG_ON(ffs->gadget);
 
+	mutex_lock(&ffs->mutex);
 	if (ffs->epfiles) {
 		ffs_epfiles_destroy(ffs->epfiles, ffs->eps_count);
 		ffs->epfiles = NULL;
 	}
+	mutex_unlock(&ffs->mutex);
 
 	if (ffs->ffs_eventfd) {
 		eventfd_ctx_put(ffs->ffs_eventfd);
diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
index 16dc063..d908717 100644
--- a/fs/tracefs/inode.c
+++ b/fs/tracefs/inode.c
@@ -501,8 +501,7 @@
 	if (unlikely(!inode))
 		return failed_creating(dentry);
 
-	/* Do not set bits for OTH */
-	inode->i_mode = S_IFDIR | S_IRWXU | S_IRUSR| S_IRGRP | S_IXUSR | S_IXGRP;
+	inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
 	inode->i_op = ops;
 	inode->i_fop = &simple_dir_operations;
 	inode->i_uid = d_inode(dentry->d_parent)->i_uid;