Merge android-msm-bluecross-4.9-pi-dr1 into -pi-qpr1

Change-Id: Ic7e616a620bdefd72ca69233e3008f9607a998b8
Signed-off-by: Petri Gynther <pgynther@google.com>
diff --git a/arch/arm64/boot/dts/google/sdm845-b1c1-battery.dtsi b/arch/arm64/boot/dts/google/sdm845-b1c1-battery.dtsi
index 714e791..a4ff13a 100644
--- a/arch/arm64/boot/dts/google/sdm845-b1c1-battery.dtsi
+++ b/arch/arm64/boot/dts/google/sdm845-b1c1-battery.dtsi
@@ -108,6 +108,7 @@
 	google_overheat_mitigation: google,overheat_mitigation {
 		compatible = "google,overheat_mitigation";
 		google,port-overheat-work-interval = <1000>;
+		google,accessory-monitoring-period = <150>;
 		/* Must maintain < 1/15 duty cycle */
 		google,polling-freq = <3>;
 	};
diff --git a/arch/arm64/boot/dts/google/sdm845-b1c1-thermal.dtsi b/arch/arm64/boot/dts/google/sdm845-b1c1-thermal.dtsi
index b35cad4..568bdd4 100644
--- a/arch/arm64/boot/dts/google/sdm845-b1c1-thermal.dtsi
+++ b/arch/arm64/boot/dts/google/sdm845-b1c1-thermal.dtsi
@@ -149,15 +149,27 @@
 	};
 };
 
+&low_vbat {
+	temperature = <3200>;
+	hysteresis = <100>;
+	type = "passive";
+};
+
+&low_soc {
+	temperature = <10>;
+	hysteresis = <0>;
+	type = "passive";
+};
+
+&ibat_high {
+	temperature = <5000>;
+	hysteresis = <200>;
+	type = "passive";
+};
+
 &thermal_zones {
 	vbat {
-		trips {
-			low_vbat {
-				temperature = <3200>;
-				hysteresis = <100>;
-				type = "passive";
-			};
-		};
+		polling-delay-passive = <100>;
 		cooling-maps {
 			vbat_cpu4 {
 				trip = <&low_vbat>;
@@ -182,19 +194,12 @@
 			mnh_thermal {
 				trip = <&low_vbat>;
 				cooling-device =
-					<&mnh_thermal 0 0>;
+					<&mnh_thermal 3 3>;
 			};
 		};
 	};
 	soc {
 		polling-delay-passive = <0>;
-		trips {
-			low_soc {
-				temperature = <10>;
-				hysteresis = <0>;
-				type = "passive";
-			};
-		};
 		cooling-maps {
 			soc_cpu4 {
 				trip = <&low_soc>;
@@ -216,21 +221,10 @@
 				cooling-device =
 					<&CPU7 18 18>;
 			};
-			mnh_thermal {
-				trip = <&low_soc>;
-				cooling-device =
-					<&mnh_thermal 0 0>;
-			};
 		};
 	};
 	ibat-high {
-		trips {
-			ibat_high {
-				temperature = <5000>;
-				hysteresis = <200>;
-				type = "passive";
-			};
-		};
+		polling-delay-passive = <100>;
 		cooling-maps {
 			ibat_cpu4 {
 				trip = <&ibat_high>;
@@ -252,11 +246,6 @@
 				cooling-device =
 					<&CPU7 18 18>;
 			};
-			mnh_thermal {
-				trip = <&ibat_high>;
-				cooling-device =
-					<&mnh_thermal 0 0>;
-			};
 		};
 	};
 
diff --git a/drivers/iio/adc/qcom-rradc.c b/drivers/iio/adc/qcom-rradc.c
index 03b0d92..313aa0c 100644
--- a/drivers/iio/adc/qcom-rradc.c
+++ b/drivers/iio/adc/qcom-rradc.c
@@ -62,7 +62,7 @@
 #define FG_ADC_RR_AUX_THERM_CTRL		0x80
 #define FG_ADC_RR_AUX_THERM_TRIGGER		0x81
 #define FG_ADC_RR_AUX_THERM_EVERY_CYCLE_MASK	0x80
-#define FG_ADC_RR_AUX_THERM_EVERY_CYCLE 	BIT(7)
+#define FG_ADC_RR_AUX_THERM_EVERY_CYCLE		BIT(7)
 #define FG_ADC_RR_AUX_THERM_STS			0x82
 #define FG_ADC_RR_AUX_THERM_CFG			0x83
 #define FG_ADC_RR_AUX_THERM_LSB			0x84
@@ -226,11 +226,6 @@
 	RR_ADC_MAX
 };
 
-struct rradc_cache {
-	u16 value;
-	struct timespec ts;
-};
-
 struct rradc_chip {
 	struct device			*dev;
 	struct mutex			lock;
@@ -243,7 +238,6 @@
 	struct pmic_revid_data		*pmic_fab_id;
 	int volt;
 	struct power_supply		*usb_trig;
-	struct rradc_cache              usbin_v;
 };
 
 struct rradc_channels {
@@ -903,31 +897,6 @@
 	return ret;
 }
 
-static void rradc_update_cache(struct rradc_cache *cache, u16 value)
-{
-	cache->value = value;
-	getboottime(&cache->ts);
-}
-
-static int rradc_check_cache(struct rradc_cache *cache, u16 *value)
-{
-	struct timespec ts, diff;
-	s64 delay;
-
-	if (cache->ts.tv_sec == 0 && cache->ts.tv_nsec == 0)
-		return -ENODATA;
-
-	getboottime(&ts);
-	diff = timespec_sub(ts, cache->ts);
-	delay = timespec_to_ns(&diff);
-	if (delay < NSEC_PER_SEC*2) {
-		*value = cache->value;
-		return 0;
-	}
-
-	return -ENODATA;
-}
-
 static int rradc_do_conversion(struct rradc_chip *chip,
 			struct rradc_chan_prop *prop, u16 *data)
 {
@@ -948,14 +917,11 @@
 		break;
 	case RR_ADC_USBIN_V:
 		/* Don't waste time reporting V BUS on boot */
-		if (ktime_get_seconds() <= 3) {
+		if (ktime_get_seconds() <= 10) {
 			rc = -EAGAIN;
 			goto fail;
 		}
-		if (rradc_check_cache(&chip->usbin_v, data) == 0) {
-			rc = 0;
-			goto fail;
-		}
+
 		/* Force conversion every cycle */
 		rc = rradc_masked_write(chip, FG_ADC_RR_USB_IN_V_TRIGGER,
 				FG_ADC_RR_USB_IN_V_EVERY_CYCLE_MASK,
@@ -1052,10 +1018,6 @@
 	} else {
 		*data = (buf[1] << 8) | buf[0];
 	}
-
-	if (prop->channel == RR_ADC_USBIN_V)
-		rradc_update_cache(&chip->usbin_v, *data);
-
 fail:
 	mutex_unlock(&chip->lock);
 
@@ -1228,9 +1190,6 @@
 	indio_dev->channels = chip->iio_chans;
 	indio_dev->num_channels = chip->nchannels;
 
-	chip->usbin_v.ts.tv_sec = 0;
-	chip->usbin_v.ts.tv_nsec = 0;
-
 	chip->usb_trig = power_supply_get_by_name("usb");
 	if (!chip->usb_trig)
 		pr_debug("Error obtaining usb power supply\n");
diff --git a/drivers/input/touchscreen/sec_ts/sec_ts.c b/drivers/input/touchscreen/sec_ts/sec_ts.c
index b4faa07..2f76de3 100644
--- a/drivers/input/touchscreen/sec_ts/sec_ts.c
+++ b/drivers/input/touchscreen/sec_ts/sec_ts.c
@@ -2796,6 +2796,8 @@
 
 	ts->power_status = SEC_TS_STATE_SUSPEND;
 
+	sec_ts_pinctrl_configure(ts, false);
+
 	sec_set_switch_gpio(ts, SEC_SWITCH_GPIO_VALUE_SLPI_MASTER);
 
 #ifdef CONFIG_TOUCHSCREEN_TBN
@@ -2823,6 +2825,8 @@
 
 	sec_set_switch_gpio(ts, SEC_SWITCH_GPIO_VALUE_AP_MASTER);
 
+	sec_ts_pinctrl_configure(ts, true);
+
 	if (ts->power_status == SEC_TS_STATE_POWER_ON) {
 		input_err(true, &ts->client->dev, "%s: already resumed.\n",
 			  __func__);
diff --git a/drivers/misc/google-easel-comm-dma.c b/drivers/misc/google-easel-comm-dma.c
index 242a1a7..35d81e2 100644
--- a/drivers/misc/google-easel-comm-dma.c
+++ b/drivers/misc/google-easel-comm-dma.c
@@ -493,7 +493,8 @@
 static int easelcomm_client_handle_dma_request(
 	struct easelcomm_service *service,
 	struct easelcomm_message_metadata *msg_metadata,
-	enum easelcomm_dma_direction dma_dir)
+	enum easelcomm_dma_direction dma_dir,
+	int timeout_ms)
 {
 	int ret, ret2;
 
@@ -508,9 +509,18 @@
 		return 0;
 
 	/* Wait for server to return the DMA request info */
-	ret = wait_for_completion_interruptible(
-		&msg_metadata->dma_xfer.xfer_ready);
-	if (ret || msg_metadata->dma_xfer.aborting)
+	ret = wait_for_completion_interruptible_timeout(
+		&msg_metadata->dma_xfer.xfer_ready,
+		msecs_to_jiffies(timeout_ms));
+	if (ret == -ERESTARTSYS) {
+		dev_info(easelcomm_miscdev.this_device,
+				"Wait for DMA_XFER from server interrupted\n");
+		goto abort;
+	} else if (ret == 0) {
+		dev_err(easelcomm_miscdev.this_device,
+			"Wait for DMA_XFER from server timed out\n");
+		goto abort;
+	} else if (msg_metadata->dma_xfer.aborting)
 		goto abort;
 
 	/*
@@ -566,9 +576,10 @@
 	int ret = 0;
 
 	dev_dbg(easelcomm_miscdev.this_device,
-			"RECVDMA msg %u:r%llu buf_type=%d buf_size=%u dma_buf_fd=%d dma_buf_off=%u dma_buf_width=%u dma_buf_stride=%u\n",
+			"RECVDMA msg %u:r%llu buf_type=%d buf_size=%u timeout_ms=%d dma_buf_fd=%d dma_buf_off=%u dma_buf_width=%u dma_buf_stride=%u\n",
 			service->service_id, buf_desc->message_id,
 			buf_desc->buf_type, buf_desc->buf_size,
+			buf_desc->wait.timeout_ms,
 			buf_desc->dma_buf_fd,
 			buf_desc->dma_buf_off,
 			buf_desc->dma_buf_width,
@@ -631,7 +642,8 @@
 
 	if (easelcomm_is_client())
 		ret = easelcomm_client_handle_dma_request(
-			service, msg_metadata, dma_dir);
+			service, msg_metadata, dma_dir,
+			buf_desc->wait.timeout_ms);
 	else
 		ret = easelcomm_server_handle_dma_request(
 			service, msg_metadata, dma_dir);
@@ -659,9 +671,10 @@
 	int ret = 0;
 
 	dev_dbg(easelcomm_miscdev.this_device,
-			"SENDDMA msg %u:l%llu buf_type=%d buf_size=%u dma_buf_fd=%d dma_buf_off=%u dma_buf_width=%u dma_buf_stride=%u\n",
+			"SENDDMA msg %u:l%llu buf_type=%d buf_size=%u timeout_ms=%d dma_buf_fd=%d dma_buf_off=%u dma_buf_width=%u dma_buf_stride=%u\n",
 			service->service_id, buf_desc->message_id,
 			buf_desc->buf_type, buf_desc->buf_size,
+			buf_desc->wait.timeout_ms,
 			buf_desc->dma_buf_fd, buf_desc->dma_buf_off,
 			buf_desc->dma_buf_width, buf_desc->dma_buf_stride);
 
@@ -717,7 +730,8 @@
 	if (msg_metadata->msg->desc.dma_buf_size) {
 		if (easelcomm_is_client())
 			ret = easelcomm_client_handle_dma_request(
-				service, msg_metadata, dma_dir);
+				service, msg_metadata, dma_dir,
+				buf_desc->wait.timeout_ms);
 		else
 			ret = easelcomm_server_handle_dma_request(
 				service, msg_metadata, dma_dir);
diff --git a/drivers/misc/google-easel-comm.c b/drivers/misc/google-easel-comm.c
index ff639e8..44b103f 100644
--- a/drivers/misc/google-easel-comm.c
+++ b/drivers/misc/google-easel-comm.c
@@ -1932,6 +1932,7 @@
 		kbuf_desc.buf = compat_ptr(compat_kbuf_desc.buf);
 		kbuf_desc.buf_size = compat_kbuf_desc.buf_size;
 		kbuf_desc.buf_type = compat_kbuf_desc.buf_type;
+		kbuf_desc.wait.timeout_ms = -1;
 		kbuf_desc.dma_buf_fd = compat_kbuf_desc.dma_buf_fd;
 		kbuf_desc.dma_buf_off = compat_kbuf_desc.dma_buf_off;
 		kbuf_desc.dma_buf_width = compat_kbuf_desc.dma_buf_width;
@@ -1971,6 +1972,7 @@
 		kbuf_desc.buf = compat_ptr(compat_kbuf_desc_legacy.buf);
 		kbuf_desc.buf_size = compat_kbuf_desc_legacy.buf_size;
 		kbuf_desc.buf_type = compat_kbuf_desc_legacy.buf_type;
+		kbuf_desc.wait.timeout_ms = -1;
 		kbuf_desc.dma_buf_fd = compat_kbuf_desc_legacy.dma_buf_fd;
 		kbuf_desc.dma_buf_width = compat_kbuf_desc_legacy.buf_size;
 		kbuf_desc.dma_buf_stride = compat_kbuf_desc_legacy.buf_size;
@@ -1988,6 +1990,7 @@
 		kbuf_desc.buf = kbuf_desc_legacy.buf;
 		kbuf_desc.buf_size = kbuf_desc_legacy.buf_size;
 		kbuf_desc.buf_type = kbuf_desc_legacy.buf_type;
+		kbuf_desc.wait.timeout_ms = kbuf_desc_legacy.wait.timeout_ms;
 		kbuf_desc.dma_buf_fd = kbuf_desc_legacy.dma_buf_fd;
 		kbuf_desc.dma_buf_width = kbuf_desc_legacy.buf_size;
 		kbuf_desc.dma_buf_stride = kbuf_desc_legacy.buf_size;
diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c
index 5ba8de3..b87b06c 100644
--- a/drivers/power/reset/msm-poweroff.c
+++ b/drivers/power/reset/msm-poweroff.c
@@ -349,7 +349,11 @@
 	if (in_panic) {
 		qpnp_pon_set_restart_reason(PON_RESTART_REASON_PANIC);
 	} else if (cmd != NULL) {
-		if (!strncmp(cmd, "bootloader", 10)) {
+		if (!strncmp(cmd, "packout", strlen("packout"))) {
+			qpnp_pon_set_restart_reason(
+				PON_RESTART_REASON_OEM_PACKOUT);
+			__raw_writel(0x77665500, restart_reason);
+		} else if (!strncmp(cmd, "bootloader", 10)) {
 			qpnp_pon_set_restart_reason(
 				PON_RESTART_REASON_BOOTLOADER);
 			__raw_writel(0x77665500, restart_reason);
diff --git a/drivers/power/supply/max1720x_battery.c b/drivers/power/supply/max1720x_battery.c
index 7ad5001..0f69a5b 100644
--- a/drivers/power/supply/max1720x_battery.c
+++ b/drivers/power/supply/max1720x_battery.c
@@ -28,6 +28,12 @@
 #include <linux/slab.h>
 #include <linux/time.h>
 
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/fs.h> /* register_chrdev, unregister_chrdev */
+#include <linux/module.h>
+#include <linux/seq_file.h> /* seq_read, seq_lseek, single_release */
+
 #ifdef CONFIG_DEBUG_FS
 #include <linux/debugfs.h>
 #endif
@@ -40,8 +46,7 @@
 #define MAX1720X_DELAY_INIT_MS 1000
 #define FULLCAPNOM_STABILIZE_CYCLES 5
 
-/* workaround for b/111835845 */
-#define MAXFG_HISTORY_PAGE_ENT_COUNT (PAGE_SIZE / (16*5 + 1))
+#define HISTORY_DEVICENAME "maxfg_history"
 
 enum max1720x_register {
 	/* ModelGauge m5 Register */
@@ -290,6 +295,14 @@
 	int prev_soc;
 };
 
+
+struct max1720x_history {
+	loff_t history_index;
+	int history_count;
+	bool *page_status;
+	u16 *history;
+};
+
 struct max1720x_chip {
 	struct device *dev;
 	struct regmap *regmap;
@@ -302,6 +315,15 @@
 	struct device_node *batt_node;
 	struct iio_channel *iio_ch;
 	struct max1720x_cyc_ctr_data cyc_ctr;
+
+	/* history */
+	struct mutex history_lock;
+	int hcmajor;
+	struct cdev hcdev;
+	struct class *hcclass;
+	bool history_available;
+	bool history_added;
+
 	u16 RSense;
 	u16 RConfig;
 	bool init_complete;
@@ -544,13 +566,6 @@
 	kfree(write_status);
 	kfree(valid_status);
 
-	/* workaround for b/111835845 */
-	if (valid_history_entry_count > MAXFG_HISTORY_PAGE_ENT_COUNT) {
-		dev_info(chip->dev, " support only one page (%d available)\n",
-			valid_history_entry_count);
-		valid_history_entry_count = MAXFG_HISTORY_PAGE_ENT_COUNT;
-	}
-
 	return valid_history_entry_count;
 }
 
@@ -576,105 +591,68 @@
 	}
 }
 
-static ssize_t max1720x_history_count_show(struct device *dev,
-					   struct device_attribute *attr,
-					   char *buf)
+static int format_battery_history_entry(char *temp, int size, u16 *line)
 {
+	int length = 0, i;
 
-	struct power_supply *psy;
-	struct max1720x_chip *chip;
-	int length, ret;
-	bool *page_status;
-
-	psy = container_of(dev, struct power_supply, dev);
-	chip = power_supply_get_drvdata(psy);
-
-	page_status = kcalloc(MAX1720X_N_OF_HISTORY_PAGES,
-			      sizeof(bool), GFP_KERNEL);
-	if (!page_status)
-		return -ENOMEM;
-
-	ret = get_battery_history_status(chip, page_status);
-	if (ret < 0) {
-		kfree(page_status);
-		return ret;
+	for (i = 0; i < MAX1720X_HISTORY_PAGE_SIZE; i++) {
+		length += scnprintf(temp + length,
+			size - length, "%04x ",
+			line[i]);
 	}
 
-	length = scnprintf(buf, PAGE_SIZE, "%i\n", ret);
-	kfree(page_status);
+	if (length > 0)
+		temp[--length] = 0;
 	return length;
 }
 
-static const DEVICE_ATTR(history_count, 0444,
-			 max1720x_history_count_show, NULL);
-
-static ssize_t max1720x_history_show(struct device *dev,
-				     struct device_attribute *attr, char *buf)
+/* @return number of valid entries */
+static int max1720x_history_read(struct max1720x_chip *chip,
+				 struct max1720x_history *hi)
 {
-	struct power_supply *psy;
-	struct max1720x_chip *chip;
-	int i;
-	int length = 0;
-	bool *page_status = NULL;
-	int history_index, history_count;
-	u16 *history;
+	memset(hi, 0, sizeof(*hi));
 
-	psy = container_of(dev, struct power_supply, dev);
-	chip = power_supply_get_drvdata(psy);
-
-	/*
-	 * Total history size can be up to 6.7KB, which is greater than
-	 * PAGE_SIZE, which is 4K. Complete history may need to be queried
-	 * in two calls (only one supported now)
-	 */
-	page_status = kcalloc(MAX1720X_N_OF_HISTORY_PAGES,
+	hi->page_status = kcalloc(MAX1720X_N_OF_HISTORY_PAGES,
 				sizeof(bool), GFP_KERNEL);
-	if (!page_status)
+	if (!hi->page_status)
 		return -ENOMEM;
 
-	history_count = get_battery_history_status(chip, page_status);
-	if (history_count <= 0) {
-		kfree(page_status);
-		if (!history_count)
-			dev_info(chip->dev,
-				"No battery history has been recorded\n");
-		return history_count;
-	}
+	mutex_lock(&chip->history_lock);
 
-	history = kmalloc_array(MAX1720X_N_OF_HISTORY_PAGES *
-				MAX1720X_HISTORY_PAGE_SIZE,
-				sizeof(u16), GFP_KERNEL);
-	if (!history) {
-		kfree(page_status);
-		return -ENOMEM;
-	}
+	hi->history_count = get_battery_history_status(chip, hi->page_status);
+	if (hi->history_count < 0) {
+		goto error_exit;
+	} else if (hi->history_count != 0) {
+		const int size = hi->history_count * MAX1720X_HISTORY_PAGE_SIZE;
 
-	get_battery_history(chip, page_status, history);
-
-	/*
-	 * The 81 in the next line is arrived with 16*5: one history log
-	 * is 16 of u16. We print each u16 to 4 chars and we leave one space
-	 * between the hex data in the buffer. And lastly we need a new line
-	 * for every history log. (16x4 + 16x1 + 1) = 81.
-	 */
-	for (history_index = 0; (history_index < history_count)
-	     && (length < (PAGE_SIZE - 81)); history_index++) {
-		for (i = 0; i < MAX1720X_HISTORY_PAGE_SIZE; i++) {
-			length += scnprintf(buf + length,
-				PAGE_SIZE - length, "%04x ",
-				history[history_index *
-					MAX1720X_HISTORY_PAGE_SIZE + i]);
+		hi->history = kmalloc_array(size, sizeof(u16), GFP_KERNEL);
+		if (!hi->history) {
+			hi->history_count = -ENOMEM;
+			goto error_exit;
 		}
-		length += scnprintf(buf + length, PAGE_SIZE - length, "\n");
+
+		get_battery_history(chip, hi->page_status, hi->history);
 	}
 
-	kfree(history);
-	kfree(page_status);
+	mutex_unlock(&chip->history_lock);
+	return hi->history_count;
 
-	return length;
+error_exit:
+	mutex_unlock(&chip->history_lock);
+	kfree(hi->page_status);
+	hi->page_status = NULL;
+	return hi->history_count;
+
 }
 
-static const DEVICE_ATTR(history, 0444, max1720x_history_show, NULL);
+static void max1720x_history_free(struct max1720x_history *hi)
+{
+	kfree(hi->page_status);
+	kfree(hi->history);
+
+	hi->history = NULL;
+	hi->page_status = NULL;
+}
 
 static enum power_supply_property max1720x_battery_props[] = {
 	POWER_SUPPLY_PROP_STATUS,
@@ -1842,6 +1820,146 @@
 	.num_properties = ARRAY_SIZE(max1720x_battery_props),
 };
 
+
+static void *ct_seq_start(struct seq_file *s, loff_t *pos)
+{
+	struct max1720x_history *hi =
+		(struct max1720x_history *)s->private;
+
+	if (*pos >= hi->history_count)
+		return NULL;
+	hi->history_index = *pos;
+
+	return &hi->history_index;
+}
+
+static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+	loff_t *spos = (loff_t *)v;
+	struct max1720x_history *hi =
+		(struct max1720x_history *)s->private;
+
+	*pos = ++*spos;
+	if (*pos >= hi->history_count)
+		return NULL;
+
+	return spos;
+}
+
+static void ct_seq_stop(struct seq_file *s, void *v)
+{
+	/* iterator in hi, no need to free */
+}
+
+static int ct_seq_show(struct seq_file *s, void *v)
+{
+	char temp[96];
+	loff_t *spos = (loff_t *)v;
+	struct max1720x_history *hi =
+		(struct max1720x_history *)s->private;
+	const size_t offset = *spos * MAX1720X_HISTORY_PAGE_SIZE;
+
+	format_battery_history_entry(temp, sizeof(temp), &hi->history[offset]);
+	seq_printf(s, "%s\n", temp);
+
+	return 0;
+}
+
+static const struct seq_operations ct_seq_ops = {
+	.start = ct_seq_start,
+	.next  = ct_seq_next,
+	.stop  = ct_seq_stop,
+	.show  = ct_seq_show
+};
+
+static int history_dev_open(struct inode *inode, struct file *file)
+{
+	struct max1720x_chip *chip =
+		container_of(inode->i_cdev, struct max1720x_chip, hcdev);
+	struct max1720x_history *hi;
+	int history_count;
+
+	hi = __seq_open_private(file, &ct_seq_ops, sizeof(*hi));
+	if (!hi)
+		return -ENOMEM;
+
+	history_count = max1720x_history_read(chip, hi);
+	if (history_count < 0) {
+		return history_count;
+	} else if (history_count == 0) {
+		dev_info(chip->dev,
+			"No battery history has been recorded\n");
+	}
+
+	return 0;
+}
+
+static int history_dev_release(struct inode *inode, struct file *file)
+{
+	struct max1720x_history *hi =
+		((struct seq_file *)file->private_data)->private;
+
+	if (hi) {
+		max1720x_history_free(hi);
+		seq_release_private(inode, file);
+	}
+
+	return 0;
+}
+
+static const struct file_operations hdev_fops = {
+	.open = history_dev_open,
+	.owner = THIS_MODULE,
+	.read = seq_read,
+	.release = history_dev_release,
+};
+
+static void max1720x_cleanup_history(struct max1720x_chip *chip)
+{
+	if (chip->history_added)
+		cdev_del(&chip->hcdev);
+	if (chip->history_available)
+		device_destroy(chip->hcclass, chip->hcmajor);
+	if (chip->hcclass)
+		class_destroy(chip->hcclass);
+	if (chip->hcmajor != -1)
+		unregister_chrdev_region(chip->hcmajor, 1);
+}
+
+static int max1720x_init_history(struct max1720x_chip *chip)
+{
+	struct device *hcdev;
+
+	mutex_init(&chip->history_lock);
+
+	chip->hcmajor = -1;
+
+	/* cat /proc/devices */
+	if (alloc_chrdev_region(&chip->hcmajor, 0, 1, HISTORY_DEVICENAME) < 0)
+		goto no_history;
+	/* ls /sys/class */
+	chip->hcclass = class_create(THIS_MODULE, HISTORY_DEVICENAME);
+	if (chip->hcclass == NULL)
+		goto no_history;
+	/* ls /dev/ */
+	hcdev = device_create(chip->hcclass, NULL, chip->hcmajor, NULL,
+		HISTORY_DEVICENAME);
+	if (hcdev == NULL)
+		goto no_history;
+
+	chip->history_available = true;
+	cdev_init(&chip->hcdev, &hdev_fops);
+	if (cdev_add(&chip->hcdev, chip->hcmajor, 1) == -1)
+		goto no_history;
+
+	chip->history_added = true;
+	return 0;
+
+no_history:
+	max1720x_cleanup_history(chip);
+	return -ENODEV;
+}
+
 static void max1720x_init_work(struct work_struct *work)
 {
 	struct max1720x_chip *chip = container_of(work, struct max1720x_chip,
@@ -1853,6 +1971,8 @@
 				      msecs_to_jiffies(MAX1720X_DELAY_INIT_MS));
 		return;
 	}
+
+	(void)max1720x_init_history(chip);
 }
 
 static int max1720x_probe(struct i2c_client *client,
@@ -1919,18 +2039,6 @@
 		goto irq_unregister;
 	}
 
-	ret = device_create_file(&chip->psy->dev, &dev_attr_history_count);
-	if (ret) {
-		dev_err(dev, "Failed to create history_count attribute\n");
-		goto psy_unregister;
-	}
-
-	ret = device_create_file(&chip->psy->dev, &dev_attr_history);
-	if (ret) {
-		dev_err(dev, "Failed to create history attribute\n");
-		goto psy_unregister;
-	}
-
 	ret = device_create_file(&chip->psy->dev, &dev_attr_cycle_counts_bins);
 	if (ret) {
 		dev_err(dev, "Failed to create cycle_counts_bins attribute\n");
@@ -1966,6 +2074,7 @@
 {
 	struct max1720x_chip *chip = i2c_get_clientdata(client);
 
+	max1720x_cleanup_history(chip);
 	cancel_delayed_work(&chip->init_work);
 	iio_channel_release(chip->iio_ch);
 	if (chip->primary->irq)
diff --git a/drivers/power/supply/overheat_mitigation.c b/drivers/power/supply/overheat_mitigation.c
index da68d8d..8cbbc42 100644
--- a/drivers/power/supply/overheat_mitigation.c
+++ b/drivers/power/supply/overheat_mitigation.c
@@ -45,6 +45,7 @@
 	struct wakeup_source	   overheat_ws;
 
 	bool usb_connected;
+	bool accessory_connected;
 	bool usb_replug;
 	bool overheat_mitigation;
 	bool overheat_work_running;
@@ -53,6 +54,8 @@
 	int clear_temp;
 	int overheat_work_delay_ms;
 	int polling_freq;
+	int monitor_accessory_s;
+	time_t accessory_connect_time;
 	int check_status;
 };
 
@@ -117,6 +120,15 @@
 		return ret;
 	}
 
+	ret = of_property_read_u32(node, "google,accessory-monitoring-period",
+				   &ovh_info->monitor_accessory_s);
+	if (ret < 0) {
+		dev_err(ovh_info->dev,
+			"cannot read accessory-monitoring-period, ret=%d\n",
+			ret);
+		ovh_info->monitor_accessory_s = 5;
+	}
+
 	return 0;
 }
 
@@ -177,13 +189,25 @@
 	return ret;
 }
 
+static inline time_t get_seconds_since_boot(void)
+{
+	struct timespec boot;
+
+	getboottime(&boot);
+	return get_seconds() - boot.tv_sec;
+}
+
 /*
- * Updated usb_connected and usb_replug status in overheat_info struct
+ * Update usb_connected, accessory_connected, and usb_replug status in
+ * overheat_info struct.
  */
 static int update_usb_status(struct overheat_info *ovh_info)
 {
 	int ret;
-	bool prev_state = ovh_info->usb_connected;
+	bool prev_state = ovh_info->usb_connected ||
+		ovh_info->accessory_connected;
+	bool prev_accessory_state = ovh_info->accessory_connected;
+	bool curr_state;
 	int *check_status = &ovh_info->check_status;
 
 	if (ovh_info->overheat_mitigation) {
@@ -208,6 +232,16 @@
 		return ret;
 	ovh_info->usb_connected = ret;
 
+	ret = PSY_GET_PROP(ovh_info->usb_psy, POWER_SUPPLY_PROP_TYPEC_MODE);
+	if (ret < 0)
+		return ret;
+	ovh_info->accessory_connected = (ret == POWER_SUPPLY_TYPEC_SINK) ||
+			(ret == POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE);
+
+	if (!prev_accessory_state && ovh_info->accessory_connected)
+		ovh_info->accessory_connect_time = get_seconds_since_boot();
+	curr_state = ovh_info->usb_connected || ovh_info->accessory_connected;
+
 	if (ovh_info->overheat_mitigation) {
 		ret = vote(ovh_info->disable_power_role_switch,
 			   USB_OVERHEAT_MITIGATION_VOTER, true, 0);
@@ -219,14 +253,13 @@
 		}
 	}
 
-	if (ovh_info->usb_connected != prev_state)
+	if (curr_state != prev_state)
 		dev_info(ovh_info->dev,
 			 "USB is %sconnected",
-			 ovh_info->usb_connected ? "" : "dis");
+			 curr_state ? "" : "dis");
 
 	// USB should be disconnected for two cycles before replug is acked
-	if(ovh_info->overheat_mitigation && !ovh_info->usb_connected &&
-	   !prev_state)
+	if (ovh_info->overheat_mitigation && !curr_state && !prev_state)
 		ovh_info->usb_replug = true;
 
 	return 0;
@@ -267,6 +300,24 @@
 	return NOTIFY_OK;
 }
 
+static bool should_check_accessory(struct overheat_info *ovh_info)
+{
+	time_t connected;
+	bool ret;
+
+	if (!ovh_info->accessory_connected)
+		return false;
+
+	connected =
+		get_seconds_since_boot() - ovh_info->accessory_connect_time;
+	ret = (connected < ovh_info->monitor_accessory_s);
+	if (!ret)
+		dev_info(ovh_info->dev,
+			 "Stop monitoring: %d sec since USB accessory connected",
+			 (int) connected);
+	return ret;
+}
+
 static void port_overheat_work(struct work_struct *work)
 {
 	struct overheat_info *ovh_info =
@@ -304,7 +355,8 @@
 		goto rerun;
 	}
 
-	if (ovh_info->overheat_mitigation || ovh_info->usb_connected)
+	if (ovh_info->overheat_mitigation || ovh_info->usb_connected ||
+	    should_check_accessory(ovh_info))
 		goto rerun;
 	// Do not run again, USB port isn't overheated or connected to something
 	ovh_info->overheat_work_running = false;
diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c
index 9f99a54..8318603 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -338,6 +338,7 @@
 	POWER_SUPPLY_ATTR(enable_jeita_detection),
 	POWER_SUPPLY_ATTR(otg_fastroleswap),
 	POWER_SUPPLY_ATTR(charge_disable),
+	POWER_SUPPLY_ATTR(in_explicit_contract),
 	/* Local extensions of type int64_t */
 	POWER_SUPPLY_ATTR(charge_counter_ext),
 	/* Properties of type `const char *' */
diff --git a/drivers/power/supply/qcom/p9221_charger.c b/drivers/power/supply/qcom/p9221_charger.c
index 49d3937..944f9d9 100644
--- a/drivers/power/supply/qcom/p9221_charger.c
+++ b/drivers/power/supply/qcom/p9221_charger.c
@@ -36,6 +36,11 @@
 #define P9221R5_ILIM_MAX_UA		(1600 * 1000)
 #define P9221R5_OVER_CHECK_NUM		3
 
+#define OVC_LIMIT			1
+#define OVC_THRESHOLD			1400000
+#define OVC_BACKOFF_LIMIT		900000
+#define OVC_BACKOFF_AMOUNT		100000
+
 static const u32 p9221_ov_set_lut[] = {
 	17000000, 20000000, 15000000, 13000000,
 	11000000, 11000000, 11000000, 11000000};
@@ -733,7 +738,6 @@
 struct p9221_prop_reg_map_entry p9221_prop_reg_map[] = {
 	/* property			register			g, s */
 	{POWER_SUPPLY_PROP_CURRENT_NOW,	P9221_RX_IOUT_REG,		1, 0},
-	{POWER_SUPPLY_PROP_CURRENT_MAX,	P9221_ILIM_SET_REG,		1, 1},
 	{POWER_SUPPLY_PROP_VOLTAGE_NOW,	P9221_VOUT_ADC_REG,		1, 0},
 	{POWER_SUPPLY_PROP_VOLTAGE_MAX, P9221_VOUT_SET_REG,		1, 1},
 	{POWER_SUPPLY_PROP_TEMP,	P9221_DIE_TEMP_ADC_REG,		1, 0},
@@ -743,7 +747,6 @@
 struct p9221_prop_reg_map_entry p9221_prop_reg_map_r5[] = {
 	/* property			register			g, s */
 	{POWER_SUPPLY_PROP_CURRENT_NOW,	P9221R5_IOUT_REG,		1, 0},
-	{POWER_SUPPLY_PROP_CURRENT_MAX,	P9221R5_ILIM_SET_REG,		1, 1},
 	{POWER_SUPPLY_PROP_VOLTAGE_NOW,	P9221R5_VOUT_REG,		1, 0},
 	{POWER_SUPPLY_PROP_VOLTAGE_MAX, P9221R5_VOUT_SET_REG,		1, 1},
 	{POWER_SUPPLY_PROP_TEMP,	P9221R5_DIE_TEMP_ADC_REG,	1, 0},
@@ -836,10 +839,35 @@
 	sysfs_notify(&charger->dev->kobj, NULL, "rxdone");
 }
 
-static void p9221_set_offline(struct p9221_charger_data *charger)
+/*
+ * Put the default ICL back to BPP, reset OCP voter
+ * @pre charger && charger->dc_icl_votable && charger->client->dev
+ */
+static void p9221_vote_defaults(struct p9221_charger_data *charger)
 {
 	int ret;
 
+	if (!charger->dc_icl_votable) {
+		dev_err(&charger->client->dev,
+			"Could not vote DC_ICL - no votable\n");
+		return;
+	}
+
+	ret = vote(charger->dc_icl_votable, P9221_WLC_VOTER, true,
+			P9221_DC_ICL_BPP_UA);
+	if (ret)
+		dev_err(&charger->client->dev,
+			"Could not vote DC_ICL %d\n", ret);
+
+	ret = vote(charger->dc_icl_votable, P9221_OCP_VOTER, true,
+			P9221_DC_ICL_EPP_UA);
+	if (ret)
+		dev_err(&charger->client->dev,
+			"Could not reset OCP DC_ICL voter %d\n", ret);
+}
+
+static void p9221_set_offline(struct p9221_charger_data *charger)
+{
 	dev_info(&charger->client->dev, "Set offline\n");
 
 	charger->online = false;
@@ -851,14 +879,7 @@
 	cancel_delayed_work(&charger->dcin_work);
 	del_timer(&charger->vrect_timer);
 
-	/* Put the default ICL back to BPP */
-	if (charger->dc_icl_votable) {
-		ret = vote(charger->dc_icl_votable, P9221_WLC_VOTER, true,
-			   P9221_DC_ICL_BPP_UA);
-		if (ret)
-			dev_err(&charger->client->dev,
-				"Could not vote DC_ICL %d\n", ret);
-	}
+	p9221_vote_defaults(charger);
 }
 
 static void p9221_tx_work(struct work_struct *work)
@@ -965,6 +986,16 @@
 		else
 			val->intval = 0;
 		break;
+	case POWER_SUPPLY_PROP_CURRENT_MAX:
+		if (!charger->dc_icl_votable)
+			return -EAGAIN;
+
+		ret = get_effective_result(charger->dc_icl_votable);
+		if (ret < 0)
+			break;
+
+		val->intval = ret;
+		break;
 	default:
 		ret = p9221_get_property_reg(charger, prop, val);
 		break;
@@ -995,7 +1026,18 @@
 					"Could send csp: %d\n", ret);
 		}
 		break;
+	case POWER_SUPPLY_PROP_CURRENT_MAX:
+		if (val->intval < 0) {
+			ret = -EINVAL;
+			break;
+		}
 
+		if (!charger->dc_icl_votable)
+			return -EAGAIN;
+
+		ret = vote(charger->dc_icl_votable, P9221_USER_VOTER, true,
+			   val->intval);
+		break;
 	default:
 		ret = p9221_set_property_reg(charger, prop, val);
 		break;
@@ -1853,6 +1895,19 @@
 			"Failed to send EOP %d: %d\n", reason, ret);
 }
 
+static void print_current_samples(struct p9221_charger_data *charger,
+					u32 *iout_val, int count)
+{
+	int i;
+	char temp[P9221R5_OVER_CHECK_NUM * 9 + 1] = { 0 };
+
+	for (i = 0; i < count ; i++)
+		scnprintf(temp + i * 9, sizeof(temp) - i * 9,
+			  "%08x ", iout_val[i]);
+
+	dev_info(&charger->client->dev, "OVER IOUT_SAMPLES: %s\n", temp);
+}
+
 /*
  * Number of times to poll the status to see if the current limit condition
  * was transient or not.
@@ -1863,6 +1918,8 @@
 	u8 reason = 0;
 	int i;
 	int ret;
+	int ovc_count = 0;
+	u32 iout_val[P9221R5_OVER_CHECK_NUM] = { 0 };
 
 	dev_err(&charger->client->dev, "Received OVER INT: %02x\n", irq_src);
 
@@ -1879,7 +1936,26 @@
 	if ((irq_src & P9221R5_STAT_UV) && !(irq_src & P9221R5_STAT_OVC))
 		return;
 
-	/* Overcurrent, poll to absorb any transients */
+	/* Overcurrent, reduce ICL and poll to absorb any transients */
+
+	if (charger->dc_icl_votable) {
+		int icl;
+
+		icl = get_effective_result_locked(charger->dc_icl_votable);
+		if (icl < 0) {
+			dev_err(&charger->client->dev,
+				"Failed to read ICL (%d)\n", icl);
+		} else if (icl > OVC_BACKOFF_LIMIT) {
+			icl -= OVC_BACKOFF_AMOUNT;
+
+			ret = vote(charger->dc_icl_votable,
+				   P9221_OCP_VOTER, true,
+				   icl);
+			dev_err(&charger->client->dev,
+				"Reduced ICL to %d (%d)\n", icl, ret);
+		}
+	}
+
 	reason = P9221_EOP_OVER_CURRENT;
 	for (i = 0; i < P9221R5_OVER_CHECK_NUM; i++) {
 		ret = p9221_clear_interrupts(charger,
@@ -1888,6 +1964,16 @@
 		if (ret)
 			continue;
 
+		ret = p9221_reg_read_cooked(charger, P9221R5_IOUT_REG,
+			&iout_val[i]);
+		if (ret) {
+			dev_err(&charger->client->dev,
+				"Failed to read IOUT[%d]: %d\n", i, ret);
+			continue;
+		} else if (iout_val[i] > OVC_THRESHOLD) {
+			ovc_count++;
+		}
+
 		ret = p9221_reg_read_16(charger, P9221_STATUS_REG, &irq_src);
 		if (ret) {
 			dev_err(&charger->client->dev,
@@ -1896,15 +1982,26 @@
 		}
 
 		if ((irq_src & P9221R5_STAT_OVC) == 0) {
+			print_current_samples(charger, iout_val, i + 1);
 			dev_info(&charger->client->dev,
 				 "OVER condition %04x cleared after %d tries\n",
 				 irq_src, i);
 			return;
 		}
+
 		dev_err(&charger->client->dev,
 			"OVER status is still %04x, retry\n", irq_src);
 	}
 
+	if (ovc_count < OVC_LIMIT) {
+		print_current_samples(charger, iout_val,
+				      P9221R5_OVER_CHECK_NUM);
+		dev_info(&charger->client->dev,
+			 "ovc_threshold=%d, ovc_count=%d, ovc_limit=%d\n",
+			 OVC_THRESHOLD, ovc_count, OVC_LIMIT);
+		return;
+	}
+
 send_eop:
 	dev_err(&charger->client->dev,
 		"OVER is %04x, sending EOP %d\n", irq_src, reason);
@@ -2237,6 +2334,14 @@
 		return PTR_ERR(charger->wc_psy);
 	}
 
+	/*
+	 * Find the DC_ICL votable, we use this to limit the current that
+	 * is taken from the wireless charger.
+	 */
+	charger->dc_icl_votable = find_votable("DC_ICL");
+	if (!charger->dc_icl_votable)
+		dev_warn(&charger->client->dev, "Could not find DC_ICL votable\n");
+
 	/* Test to see if the charger is online */
 	ret = p9221_reg_read_16(charger, P9221_CHIP_ID_REG, &chip_id);
 	if (ret == 0 && chip_id == P9221_CHIP_ID) {
@@ -2244,19 +2349,8 @@
 		/* set charger->online=true, will ignore first VRECTON IRQ */
 		p9221_set_online(charger);
 	} else {
-		/* disconnected, vote for BPP */
-		charger->dc_icl_votable = find_votable("DC_ICL");
-		if (!charger->dc_icl_votable) {
-			ret = -ENODEV;
-		} else {
-			ret = vote(charger->dc_icl_votable,
-				P9221_WLC_VOTER, true,
-				P9221_DC_ICL_BPP_UA);
-		}
-		if (ret)
-			dev_err(&charger->client->dev,
-				"Could not vote for default DC_ICL votable=%d %d\n",
-					charger->dc_icl_votable != 0, ret);
+		/* disconnected, (likely err!=0) vote for BPP */
+		p9221_vote_defaults(charger);
 	}
 
 	ret = devm_request_threaded_irq(
@@ -2268,7 +2362,11 @@
 		return ret;
 	}
 	device_init_wakeup(charger->dev, true);
-	/* NOTE: will get a VRECTON when booting on a pad */
+
+	/*
+	 * We will receive a VRECTON after enabling IRQ if the device is
+	 * if the device is already in-field when the driver is probed.
+	 */
 	enable_irq_wake(charger->pdata->irq_int);
 
 	if (gpio_is_valid(charger->pdata->irq_det_gpio)) {
diff --git a/drivers/power/supply/qcom/p9221_charger.h b/drivers/power/supply/qcom/p9221_charger.h
index fe24807..514560c 100644
--- a/drivers/power/supply/qcom/p9221_charger.h
+++ b/drivers/power/supply/qcom/p9221_charger.h
@@ -16,6 +16,8 @@
 #define __P9221_CHARGER_H__
 
 #define P9221_WLC_VOTER				"WLC_VOTER"
+#define P9221_USER_VOTER			"WLC_USER_VOTER"
+#define P9221_OCP_VOTER				"OCP_VOTER"
 #define P9221_DC_ICL_BPP_UA			700000
 #define P9221_DC_ICL_EPP_UA			1100000
 #define P9221_EPP_THRESHOLD_UV			7000000
diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c
index 5eef7d6..a90f3b07 100644
--- a/drivers/power/supply/qcom/qpnp-smb2.c
+++ b/drivers/power/supply/qcom/qpnp-smb2.c
@@ -404,6 +404,7 @@
 	POWER_SUPPLY_PROP_CONNECTOR_TYPE,
 	POWER_SUPPLY_PROP_OTG_FASTROLESWAP,
 	POWER_SUPPLY_PROP_MOISTURE_DETECTED,
+	POWER_SUPPLY_PROP_PD_IN_EXPLICIT_CONTRACT,
 };
 
 static int smb2_usb_get_prop(struct power_supply *psy,
@@ -415,6 +416,9 @@
 	int rc = 0;
 
 	switch (psp) {
+	case POWER_SUPPLY_PROP_PD_IN_EXPLICIT_CONTRACT:
+		val->intval = chg->in_explicit_contract;
+		break;
 	case POWER_SUPPLY_PROP_PRESENT:
 		if (chip->bad_part)
 			val->intval = 1;
@@ -564,17 +568,25 @@
 		case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
 			rc = smblib_set_prop_typec_power_role(chg, val);
 			break;
+		case POWER_SUPPLY_PROP_PD_IN_EXPLICIT_CONTRACT:
+			chg->in_explicit_contract = val->intval;
+			power_supply_changed(chg->usb_psy);
+			break;
 		default:
 			rc = -EINVAL;
 			break;
 		}
-
 		goto unlock;
 	}
 
 	switch (psp) {
+	case POWER_SUPPLY_PROP_PD_IN_EXPLICIT_CONTRACT:
+		chg->in_explicit_contract = val->intval;
+		power_supply_changed(chg->usb_psy);
+		break;
 	case POWER_SUPPLY_PROP_PD_CURRENT_MAX:
 		rc = smblib_set_prop_pd_current_max(chg, val);
+		power_supply_changed(chg->usb_psy);
 		break;
 	case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
 		rc = smblib_set_prop_typec_power_role(chg, val);
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index 3c72829..505490b 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -3445,7 +3445,7 @@
 	bool non_compliant;
 	u8 stat5;
 
-	if (chg->pd_active) {
+	if (chg->in_explicit_contract) {
 		*total_current_ua =
 			get_client_vote_locked(chg->usb_icl_votable, PD_VOTER);
 		return rc;
diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h
index efa476c1..314a10a 100644
--- a/drivers/power/supply/qcom/smb-lib.h
+++ b/drivers/power/supply/qcom/smb-lib.h
@@ -360,6 +360,7 @@
 	bool			otg_present;
 	bool			is_audio_adapter;
 	bool			hvdcp_disable;
+	u8			in_explicit_contract;
 
 	/* workaround flag */
 	u32			wa_flags;
diff --git a/drivers/usb/pd/pd_engine.c b/drivers/usb/pd/pd_engine.c
index 2ce347e..c0c87cb 100644
--- a/drivers/usb/pd/pd_engine.c
+++ b/drivers/usb/pd/pd_engine.c
@@ -116,6 +116,7 @@
 
 	bool apsd_done;
 	bool wireless_online;
+	bool in_explicit_contract;
 };
 
 /*
@@ -1428,6 +1429,37 @@
 	return ret;
 }
 
+static int tcpm_in_pd_contract(struct tcpc_dev *dev,
+			       bool status)
+{
+	union power_supply_propval val = {0};
+	struct usbpd *pd = container_of(dev, struct usbpd, tcpc_dev);
+	int ret = 0;
+
+	mutex_lock(&pd->lock);
+
+	if (status == pd->in_explicit_contract)
+		goto unlock;
+
+	/* Attempt once */
+	val.intval = status ? 1 : 0;
+	pd_engine_log(pd, "pd contract %d", status ? 1 : 0);
+	ret = power_supply_set_property(pd->usb_psy,
+				POWER_SUPPLY_PROP_PD_IN_EXPLICIT_CONTRACT,
+				&val);
+	if (ret < 0) {
+		pd_engine_log(pd,
+			      "unable to set pd contract to %d, ret=%d",
+			      status ? 1 : 0, ret);
+	} else {
+		pd->in_explicit_contract = status;
+	}
+
+unlock:
+	mutex_unlock(&pd->lock);
+	return ret;
+}
+
 static int tcpm_set_suspend_supported(struct tcpc_dev *dev,
 				      bool suspend_supported)
 {
@@ -1971,6 +2003,7 @@
 	pd_tcpc_dev->set_in_hard_reset = set_in_hard_reset;
 	pd_tcpc_dev->log_rtc = log_rtc;
 	pd_tcpc_dev->set_suspend_supported = tcpm_set_suspend_supported;
+	pd_tcpc_dev->in_pd_contract = tcpm_in_pd_contract;
 	pd_tcpc_dev->mux = NULL;
 	return 0;
 }
diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c
index 622ed63..c73c1b2 100644
--- a/drivers/usb/typec/tcpm.c
+++ b/drivers/usb/typec/tcpm.c
@@ -2173,12 +2173,21 @@
 	memset(modep, 0, sizeof(*modep));
 }
 
+static void update_pd_contract_status(struct tcpm_port *port,
+				      bool in_explicit_contract)
+{
+	if (port->tcpc->in_pd_contract)
+		port->tcpc->in_pd_contract(port->tcpc, in_explicit_contract);
+}
+
+
 static void tcpm_reset_port(struct tcpm_port *port)
 {
 	tcpm_unregister_altmodes(port);
 	tcpm_typec_disconnect(port);
 	port->attached = false;
 	tcpm_set_pd_capable(port, false);
+	update_pd_contract_status(port, false);
 	port->usb_comm_capable = false;
 
 	/*
@@ -2472,6 +2481,7 @@
 			/* port->hard_reset_count = 0; */
 			port->caps_count = 0;
 			tcpm_set_pd_capable(port, true);
+			update_pd_contract_status(port, false);
 			tcpm_set_state_cond(port, hard_reset_state(port),
 					    PD_T_SEND_SOURCE_CAP);
 		}
@@ -2518,6 +2528,9 @@
 				== TYPEC_CC_RP_DEF)
 			tcpm_set_cc(port, TYPEC_CC_RP_1_5);
 		tcpm_check_send_discover(port);
+		update_pd_contract_status(port, port->pd_capable
+					  ? true : false);
+
 		/*
 		 * 6.3.5
 		 * Sending ping messages is not necessary if
@@ -2691,6 +2704,8 @@
 		break;
 	case SNK_NEGOTIATE_CAPABILITIES:
 		tcpm_set_pd_capable(port, true);
+		update_pd_contract_status(port, false);
+
 		port->usb_comm_capable = port->source_caps[0] &
 					 PDO_FIXED_USB_COMM;
 		/* Notify TCPC of usb_comm_capable. */
@@ -2730,6 +2745,8 @@
 		tcpm_swap_complete(port, 0);
 		tcpm_typec_connect(port);
 		tcpm_check_send_discover(port);
+		update_pd_contract_status(port, port->pd_capable
+					  ? true : false);
 		break;
 
 	/* Accessory states */
@@ -2754,6 +2771,7 @@
 		break;
 	case HARD_RESET_START:
 		tcpm_port_in_hard_reset(port, true);
+		update_pd_contract_status(port, false);
 		port->hard_reset_count++;
 		port->tcpc->set_pd_rx(port->tcpc, false);
 		tcpm_unregister_altmodes(port);
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index f2cba44..d7d0188 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -606,9 +606,6 @@
 		ctx->bio = bio;
 		ctx->enabled_steps = post_read_steps;
 		bio->bi_private = ctx;
-
-		/* wait the page to be moved by cleaning */
-		f2fs_wait_on_block_writeback(sbi, blkaddr);
 	}
 
 	return bio;
@@ -626,6 +623,9 @@
 	if (f2fs_may_encrypt_bio(inode, NULL))
 		fscrypt_set_ice_dun(inode, bio, PG_DUN(inode, page));
 
+	/* wait for GCed page writeback via META_MAPPING */
+	f2fs_wait_on_block_writeback(inode, blkaddr);
+
 	if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
 		bio_put(bio);
 		return -EFAULT;
@@ -1587,6 +1587,12 @@
 				fscrypt_set_ice_dun(inode, bio, dun);
 		}
 
+		/*
+		 * If the page is under writeback, we need to wait for
+		 * its completion to see the correct decrypted data.
+		 */
+		f2fs_wait_on_block_writeback(inode, block_nr);
+
 		if (bio_add_page(bio, page, blocksize, 0) < blocksize)
 			goto submit_and_realloc;
 
@@ -1653,7 +1659,7 @@
 		return 0;
 
 	/* wait for GCed page writeback via META_MAPPING */
-	f2fs_wait_on_block_writeback(fio->sbi, fio->old_blkaddr);
+	f2fs_wait_on_block_writeback(inode, fio->old_blkaddr);
 
 retry_encrypt:
 	if (fscrypt_using_hardware_encryption(inode))
@@ -2382,10 +2388,6 @@
 
 	f2fs_wait_on_page_writeback(page, DATA, false);
 
-	/* wait for GCed page writeback via META_MAPPING */
-	if (f2fs_post_read_required(inode))
-		f2fs_wait_on_block_writeback(sbi, blkaddr);
-
 	if (len == PAGE_SIZE || PageUptodate(page))
 		return 0;
 
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index dc89bae06..702aa18 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -2839,7 +2839,7 @@
 			struct f2fs_io_info *fio, bool add_list);
 void f2fs_wait_on_page_writeback(struct page *page,
 			enum page_type type, bool ordered);
-void f2fs_wait_on_block_writeback(struct f2fs_sb_info *sbi, block_t blkaddr);
+void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr);
 void write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
 void write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
 int lookup_journal_in_cursum(struct f2fs_journal *journal, int type,
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 5a39adf..e62fb40 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -113,8 +113,7 @@
 	f2fs_wait_on_page_writeback(page, DATA, false);
 
 	/* wait for GCed page writeback via META_MAPPING */
-	if (f2fs_post_read_required(inode))
-		f2fs_wait_on_block_writeback(sbi, dn.data_blkaddr);
+	f2fs_wait_on_block_writeback(inode, dn.data_blkaddr);
 
 out_sem:
 	up_read(&F2FS_I(inode)->i_mmap_sem);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 4fa2efa..5062c02 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2946,10 +2946,14 @@
 	}
 }
 
-void f2fs_wait_on_block_writeback(struct f2fs_sb_info *sbi, block_t blkaddr)
+void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr)
 {
+	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
 	struct page *cpage;
 
+	if (!f2fs_post_read_required(inode))
+		return;
+
 	if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR)
 		return;
 
diff --git a/fs/sdcardfs/file.c b/fs/sdcardfs/file.c
index 1461254..271c4c4 100644
--- a/fs/sdcardfs/file.c
+++ b/fs/sdcardfs/file.c
@@ -118,7 +118,11 @@
 		goto out;
 
 	/* save current_cred and override it */
-	OVERRIDE_CRED(sbi, saved_cred, SDCARDFS_I(file_inode(file)));
+	saved_cred = override_fsids(sbi, SDCARDFS_I(file_inode(file))->data);
+	if (!saved_cred) {
+		err = -ENOMEM;
+		goto out;
+	}
 
 	if (lower_file->f_op->unlocked_ioctl)
 		err = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg);
@@ -127,7 +131,7 @@
 	if (!err)
 		sdcardfs_copy_and_fix_attrs(file_inode(file),
 				      file_inode(lower_file));
-	REVERT_CRED(saved_cred);
+	revert_fsids(saved_cred);
 out:
 	return err;
 }
@@ -149,12 +153,16 @@
 		goto out;
 
 	/* save current_cred and override it */
-	OVERRIDE_CRED(sbi, saved_cred, SDCARDFS_I(file_inode(file)));
+	saved_cred = override_fsids(sbi, SDCARDFS_I(file_inode(file))->data);
+	if (!saved_cred) {
+		err = -ENOMEM;
+		goto out;
+	}
 
 	if (lower_file->f_op->compat_ioctl)
 		err = lower_file->f_op->compat_ioctl(lower_file, cmd, arg);
 
-	REVERT_CRED(saved_cred);
+	revert_fsids(saved_cred);
 out:
 	return err;
 }
@@ -241,7 +249,11 @@
 	}
 
 	/* save current_cred and override it */
-	OVERRIDE_CRED(sbi, saved_cred, SDCARDFS_I(inode));
+	saved_cred = override_fsids(sbi, SDCARDFS_I(inode)->data);
+	if (!saved_cred) {
+		err = -ENOMEM;
+		goto out_err;
+	}
 
 	file->private_data =
 		kzalloc(sizeof(struct sdcardfs_file_info), GFP_KERNEL);
@@ -271,7 +283,7 @@
 		sdcardfs_copy_and_fix_attrs(inode, sdcardfs_lower_inode(inode));
 
 out_revert_cred:
-	REVERT_CRED(saved_cred);
+	revert_fsids(saved_cred);
 out_err:
 	dput(parent);
 	return err;
diff --git a/fs/sdcardfs/inode.c b/fs/sdcardfs/inode.c
index fafc09c4..de34561 100644
--- a/fs/sdcardfs/inode.c
+++ b/fs/sdcardfs/inode.c
@@ -22,7 +22,6 @@
 #include <linux/fs_struct.h>
 #include <linux/ratelimit.h>
 
-/* Do not directly use this function. Use OVERRIDE_CRED() instead. */
 const struct cred *override_fsids(struct sdcardfs_sb_info *sbi,
 		struct sdcardfs_inode_data *data)
 {
@@ -50,7 +49,6 @@
 	return old_cred;
 }
 
-/* Do not directly use this function, use REVERT_CRED() instead. */
 void revert_fsids(const struct cred *old_cred)
 {
 	const struct cred *cur_cred;
@@ -78,7 +76,10 @@
 	}
 
 	/* save current_cred and override it */
-	OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir));
+	saved_cred = override_fsids(SDCARDFS_SB(dir->i_sb),
+					SDCARDFS_I(dir)->data);
+	if (!saved_cred)
+		return -ENOMEM;
 
 	sdcardfs_get_lower_path(dentry, &lower_path);
 	lower_dentry = lower_path.dentry;
@@ -95,8 +96,11 @@
 		err = -ENOMEM;
 		goto out_unlock;
 	}
+	copied_fs->umask = 0;
+	task_lock(current);
 	current->fs = copied_fs;
-	current->fs->umask = 0;
+	task_unlock(current);
+
 	err = vfs_create2(lower_dentry_mnt, d_inode(lower_parent_dentry), lower_dentry, mode, want_excl);
 	if (err)
 		goto out;
@@ -110,58 +114,18 @@
 	fixup_lower_ownership(dentry, dentry->d_name.name);
 
 out:
+	task_lock(current);
 	current->fs = saved_fs;
+	task_unlock(current);
 	free_fs_struct(copied_fs);
 out_unlock:
 	unlock_dir(lower_parent_dentry);
 	sdcardfs_put_lower_path(dentry, &lower_path);
-	REVERT_CRED(saved_cred);
+	revert_fsids(saved_cred);
 out_eacces:
 	return err;
 }
 
-#if 0
-static int sdcardfs_link(struct dentry *old_dentry, struct inode *dir,
-		       struct dentry *new_dentry)
-{
-	struct dentry *lower_old_dentry;
-	struct dentry *lower_new_dentry;
-	struct dentry *lower_dir_dentry;
-	u64 file_size_save;
-	int err;
-	struct path lower_old_path, lower_new_path;
-
-	OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb));
-
-	file_size_save = i_size_read(d_inode(old_dentry));
-	sdcardfs_get_lower_path(old_dentry, &lower_old_path);
-	sdcardfs_get_lower_path(new_dentry, &lower_new_path);
-	lower_old_dentry = lower_old_path.dentry;
-	lower_new_dentry = lower_new_path.dentry;
-	lower_dir_dentry = lock_parent(lower_new_dentry);
-
-	err = vfs_link(lower_old_dentry, d_inode(lower_dir_dentry),
-		       lower_new_dentry, NULL);
-	if (err || !d_inode(lower_new_dentry))
-		goto out;
-
-	err = sdcardfs_interpose(new_dentry, dir->i_sb, &lower_new_path);
-	if (err)
-		goto out;
-	fsstack_copy_attr_times(dir, d_inode(lower_new_dentry));
-	fsstack_copy_inode_size(dir, d_inode(lower_new_dentry));
-	set_nlink(d_inode(old_dentry),
-		  sdcardfs_lower_inode(d_inode(old_dentry))->i_nlink);
-	i_size_write(d_inode(new_dentry), file_size_save);
-out:
-	unlock_dir(lower_dir_dentry);
-	sdcardfs_put_lower_path(old_dentry, &lower_old_path);
-	sdcardfs_put_lower_path(new_dentry, &lower_new_path);
-	REVERT_CRED();
-	return err;
-}
-#endif
-
 static int sdcardfs_unlink(struct inode *dir, struct dentry *dentry)
 {
 	int err;
@@ -178,7 +142,10 @@
 	}
 
 	/* save current_cred and override it */
-	OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir));
+	saved_cred = override_fsids(SDCARDFS_SB(dir->i_sb),
+						SDCARDFS_I(dir)->data);
+	if (!saved_cred)
+		return -ENOMEM;
 
 	sdcardfs_get_lower_path(dentry, &lower_path);
 	lower_dentry = lower_path.dentry;
@@ -209,43 +176,11 @@
 	unlock_dir(lower_dir_dentry);
 	dput(lower_dentry);
 	sdcardfs_put_lower_path(dentry, &lower_path);
-	REVERT_CRED(saved_cred);
+	revert_fsids(saved_cred);
 out_eacces:
 	return err;
 }
 
-#if 0
-static int sdcardfs_symlink(struct inode *dir, struct dentry *dentry,
-			  const char *symname)
-{
-	int err;
-	struct dentry *lower_dentry;
-	struct dentry *lower_parent_dentry = NULL;
-	struct path lower_path;
-
-	OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb));
-
-	sdcardfs_get_lower_path(dentry, &lower_path);
-	lower_dentry = lower_path.dentry;
-	lower_parent_dentry = lock_parent(lower_dentry);
-
-	err = vfs_symlink(d_inode(lower_parent_dentry), lower_dentry, symname);
-	if (err)
-		goto out;
-	err = sdcardfs_interpose(dentry, dir->i_sb, &lower_path);
-	if (err)
-		goto out;
-	fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir));
-	fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry));
-
-out:
-	unlock_dir(lower_parent_dentry);
-	sdcardfs_put_lower_path(dentry, &lower_path);
-	REVERT_CRED();
-	return err;
-}
-#endif
-
 static int touch(char *abs_path, mode_t mode)
 {
 	struct file *filp = filp_open(abs_path, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, mode);
@@ -286,7 +221,10 @@
 	}
 
 	/* save current_cred and override it */
-	OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir));
+	saved_cred = override_fsids(SDCARDFS_SB(dir->i_sb),
+						SDCARDFS_I(dir)->data);
+	if (!saved_cred)
+		return -ENOMEM;
 
 	/* check disk space */
 	if (!check_min_free_space(dentry, 0, 1)) {
@@ -312,8 +250,11 @@
 		unlock_dir(lower_parent_dentry);
 		goto out_unlock;
 	}
+	copied_fs->umask = 0;
+	task_lock(current);
 	current->fs = copied_fs;
-	current->fs->umask = 0;
+	task_unlock(current);
+
 	err = vfs_mkdir2(lower_mnt, d_inode(lower_parent_dentry), lower_dentry, mode);
 
 	if (err) {
@@ -362,23 +303,34 @@
 	if (make_nomedia_in_obb ||
 		((pd->perm == PERM_ANDROID)
 				&& (qstr_case_eq(&dentry->d_name, &q_data)))) {
-		REVERT_CRED(saved_cred);
-		OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(d_inode(dentry)));
+		revert_fsids(saved_cred);
+		saved_cred = override_fsids(sbi,
+					SDCARDFS_I(d_inode(dentry))->data);
+		if (!saved_cred) {
+			pr_err("sdcardfs: failed to set up .nomedia in %s: %d\n",
+						lower_path.dentry->d_name.name,
+						-ENOMEM);
+			goto out;
+		}
 		set_fs_pwd(current->fs, &lower_path);
 		touch_err = touch(".nomedia", 0664);
 		if (touch_err) {
 			pr_err("sdcardfs: failed to create .nomedia in %s: %d\n",
-							lower_path.dentry->d_name.name, touch_err);
+						lower_path.dentry->d_name.name,
+						touch_err);
 			goto out;
 		}
 	}
 out:
+	task_lock(current);
 	current->fs = saved_fs;
+	task_unlock(current);
+
 	free_fs_struct(copied_fs);
 out_unlock:
 	sdcardfs_put_lower_path(dentry, &lower_path);
 out_revert:
-	REVERT_CRED(saved_cred);
+	revert_fsids(saved_cred);
 out_eacces:
 	return err;
 }
@@ -398,7 +350,10 @@
 	}
 
 	/* save current_cred and override it */
-	OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir));
+	saved_cred = override_fsids(SDCARDFS_SB(dir->i_sb),
+						SDCARDFS_I(dir)->data);
+	if (!saved_cred)
+		return -ENOMEM;
 
 	/* sdcardfs_get_real_lower(): in case of remove an user's obb dentry
 	 * the dentry on the original path should be deleted.
@@ -423,44 +378,11 @@
 out:
 	unlock_dir(lower_dir_dentry);
 	sdcardfs_put_real_lower(dentry, &lower_path);
-	REVERT_CRED(saved_cred);
+	revert_fsids(saved_cred);
 out_eacces:
 	return err;
 }
 
-#if 0
-static int sdcardfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
-			dev_t dev)
-{
-	int err;
-	struct dentry *lower_dentry;
-	struct dentry *lower_parent_dentry = NULL;
-	struct path lower_path;
-
-	OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb));
-
-	sdcardfs_get_lower_path(dentry, &lower_path);
-	lower_dentry = lower_path.dentry;
-	lower_parent_dentry = lock_parent(lower_dentry);
-
-	err = vfs_mknod(d_inode(lower_parent_dentry), lower_dentry, mode, dev);
-	if (err)
-		goto out;
-
-	err = sdcardfs_interpose(dentry, dir->i_sb, &lower_path);
-	if (err)
-		goto out;
-	fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir));
-	fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry));
-
-out:
-	unlock_dir(lower_parent_dentry);
-	sdcardfs_put_lower_path(dentry, &lower_path);
-	REVERT_CRED();
-	return err;
-}
-#endif
-
 /*
  * The locking rules in sdcardfs_rename are complex.  We could use a simpler
  * superblock-level name-space lock for renames and copy-ups.
@@ -489,7 +411,10 @@
 	}
 
 	/* save current_cred and override it */
-	OVERRIDE_CRED(SDCARDFS_SB(old_dir->i_sb), saved_cred, SDCARDFS_I(new_dir));
+	saved_cred = override_fsids(SDCARDFS_SB(old_dir->i_sb),
+						SDCARDFS_I(new_dir)->data);
+	if (!saved_cred)
+		return -ENOMEM;
 
 	sdcardfs_get_real_lower(old_dentry, &lower_old_path);
 	sdcardfs_get_lower_path(new_dentry, &lower_new_path);
@@ -536,7 +461,7 @@
 	dput(lower_new_dir_dentry);
 	sdcardfs_put_real_lower(old_dentry, &lower_old_path);
 	sdcardfs_put_lower_path(new_dentry, &lower_new_path);
-	REVERT_CRED(saved_cred);
+	revert_fsids(saved_cred);
 out_eacces:
 	return err;
 }
@@ -655,33 +580,7 @@
 	if (IS_POSIXACL(inode))
 		pr_warn("%s: This may be undefined behavior...\n", __func__);
 	err = generic_permission(&tmp, mask);
-	/* XXX
-	 * Original sdcardfs code calls inode_permission(lower_inode,.. )
-	 * for checking inode permission. But doing such things here seems
-	 * duplicated work, because the functions called after this func,
-	 * such as vfs_create, vfs_unlink, vfs_rename, and etc,
-	 * does exactly same thing, i.e., they calls inode_permission().
-	 * So we just let they do the things.
-	 * If there are any security hole, just uncomment following if block.
-	 */
-#if 0
-	if (!err) {
-		/*
-		 * Permission check on lower_inode(=EXT4).
-		 * we check it with AID_MEDIA_RW permission
-		 */
-		struct inode *lower_inode;
-
-		OVERRIDE_CRED(SDCARDFS_SB(inode->sb));
-
-		lower_inode = sdcardfs_lower_inode(inode);
-		err = inode_permission(lower_inode, mask);
-
-		REVERT_CRED();
-	}
-#endif
 	return err;
-
 }
 
 static int sdcardfs_setattr_wrn(struct dentry *dentry, struct iattr *ia)
@@ -759,7 +658,10 @@
 		goto out_err;
 
 	/* save current_cred and override it */
-	OVERRIDE_CRED(SDCARDFS_SB(dentry->d_sb), saved_cred, SDCARDFS_I(inode));
+	saved_cred = override_fsids(SDCARDFS_SB(dentry->d_sb),
+						SDCARDFS_I(inode)->data);
+	if (!saved_cred)
+		return -ENOMEM;
 
 	sdcardfs_get_lower_path(dentry, &lower_path);
 	lower_dentry = lower_path.dentry;
@@ -818,7 +720,7 @@
 
 out:
 	sdcardfs_put_lower_path(dentry, &lower_path);
-	REVERT_CRED(saved_cred);
+	revert_fsids(saved_cred);
 out_err:
 	return err;
 }
@@ -901,13 +803,6 @@
 	.setattr	= sdcardfs_setattr_wrn,
 	.setattr2	= sdcardfs_setattr,
 	.getattr	= sdcardfs_getattr,
-	/* XXX Following operations are implemented,
-	 *     but FUSE(sdcard) or FAT does not support them
-	 *     These methods are *NOT* perfectly tested.
-	.symlink	= sdcardfs_symlink,
-	.link		= sdcardfs_link,
-	.mknod		= sdcardfs_mknod,
-	 */
 };
 
 const struct inode_operations sdcardfs_main_iops = {
diff --git a/fs/sdcardfs/lookup.c b/fs/sdcardfs/lookup.c
index 8a4b054..a6e6615 100644
--- a/fs/sdcardfs/lookup.c
+++ b/fs/sdcardfs/lookup.c
@@ -437,7 +437,12 @@
 	}
 
 	/* save current_cred and override it */
-	OVERRIDE_CRED_PTR(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir));
+	saved_cred = override_fsids(SDCARDFS_SB(dir->i_sb),
+						SDCARDFS_I(dir)->data);
+	if (!saved_cred) {
+		ret = ERR_PTR(-ENOMEM);
+		goto out_err;
+	}
 
 	sdcardfs_get_lower_path(parent, &lower_parent_path);
 
@@ -468,7 +473,7 @@
 
 out:
 	sdcardfs_put_lower_path(parent, &lower_parent_path);
-	REVERT_CRED(saved_cred);
+	revert_fsids(saved_cred);
 out_err:
 	dput(parent);
 	return ret;
diff --git a/fs/sdcardfs/sdcardfs.h b/fs/sdcardfs/sdcardfs.h
index 826afb5..ec2290a 100644
--- a/fs/sdcardfs/sdcardfs.h
+++ b/fs/sdcardfs/sdcardfs.h
@@ -88,31 +88,6 @@
 		(x)->i_mode = ((x)->i_mode & S_IFMT) | 0775;\
 	} while (0)
 
-/* OVERRIDE_CRED() and REVERT_CRED()
- *	OVERRIDE_CRED()
- *		backup original task->cred
- *		and modifies task->cred->fsuid/fsgid to specified value.
- *	REVERT_CRED()
- *		restore original task->cred->fsuid/fsgid.
- * These two macro should be used in pair, and OVERRIDE_CRED() should be
- * placed at the beginning of a function, right after variable declaration.
- */
-#define OVERRIDE_CRED(sdcardfs_sbi, saved_cred, info)		\
-	do {	\
-		saved_cred = override_fsids(sdcardfs_sbi, info->data);	\
-		if (!saved_cred)	\
-			return -ENOMEM;	\
-	} while (0)
-
-#define OVERRIDE_CRED_PTR(sdcardfs_sbi, saved_cred, info)	\
-	do {	\
-		saved_cred = override_fsids(sdcardfs_sbi, info->data);	\
-		if (!saved_cred)	\
-			return ERR_PTR(-ENOMEM);	\
-	} while (0)
-
-#define REVERT_CRED(saved_cred)	revert_fsids(saved_cred)
-
 /* Android 5.0 support */
 
 /* Permission mode for a specific node. Controls how file permissions
diff --git a/include/linux/input/qpnp-power-on.h b/include/linux/input/qpnp-power-on.h
index ab5de0a..ce3f0c7 100644
--- a/include/linux/input/qpnp-power-on.h
+++ b/include/linux/input/qpnp-power-on.h
@@ -65,6 +65,7 @@
 
 	/* 32 ~ 63 for OEMs/ODMs secific features */
 	PON_RESTART_REASON_OEM_MIN		= 0x20,
+	PON_RESTART_REASON_OEM_PACKOUT		= 0x21,
 	PON_RESTART_REASON_OEM_MAX		= 0x3f,
 };
 
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 329a5b5..30f8f08 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -295,6 +295,7 @@
 	POWER_SUPPLY_PROP_ENABLE_JEITA_DETECTION,
 	POWER_SUPPLY_PROP_OTG_FASTROLESWAP,
 	POWER_SUPPLY_PROP_CHARGE_DISABLE,
+	POWER_SUPPLY_PROP_PD_IN_EXPLICIT_CONTRACT,
 	/* Local extensions of type int64_t */
 	POWER_SUPPLY_PROP_CHARGE_COUNTER_EXT,
 	/* Properties of type `const char *' */
diff --git a/include/linux/usb/tcpm.h b/include/linux/usb/tcpm.h
index c95b4c2..ae00429 100644
--- a/include/linux/usb/tcpm.h
+++ b/include/linux/usb/tcpm.h
@@ -157,6 +157,8 @@
  *		detected.
  * @set_in_hard_reset:
  *		Optional; Called to notify that hard reset is in progress.
+ * @in_pd_contract:
+ *              Optional; Called to notify is when pd contract is established.
  * @mux:	Pointer to multiplexer data
  */
 struct tcpc_dev {
@@ -189,6 +191,7 @@
 	void (*log_rtc)(struct tcpc_dev *dev);
 	int (*set_suspend_supported)(struct tcpc_dev *dev,
 				     bool suspend_supported);
+	int (*in_pd_contract)(struct tcpc_dev *dev, bool status);
 	struct tcpc_mux_dev *mux;
 };
 
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 427e33d..5659b40 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1511,8 +1511,20 @@
 	ts->tv_nsec = 0;
 }
 
-/* Flag for if timekeeping_resume() has injected sleeptime */
-static bool sleeptime_injected;
+/*
+ * Flag reflecting whether timekeeping_resume() has injected sleeptime.
+ *
+ * The flag starts of false and is only set when a suspend reaches
+ * timekeeping_suspend(), timekeeping_resume() sets it to false when the
+ * timekeeper clocksource is not stopping across suspend and has been
+ * used to update sleep time. If the timekeeper clocksource has stopped
+ * then the flag stays true and is used by the RTC resume code to decide
+ * whether sleeptime must be injected and if so the flag gets false then.
+ *
+ * If a suspend fails before reaching timekeeping_resume() then the flag
+ * stays false and prevents erroneous sleeptime injection.
+ */
+static bool suspend_timing_needed;
 
 /* Flag for if there is a persistent clock on this platform */
 static bool persistent_clock_exists;
@@ -1611,7 +1623,7 @@
  */
 bool timekeeping_rtc_skipresume(void)
 {
-	return sleeptime_injected;
+	return !suspend_timing_needed;
 }
 
 /**
@@ -1647,6 +1659,8 @@
 	raw_spin_lock_irqsave(&timekeeper_lock, flags);
 	write_seqcount_begin(&tk_core.seq);
 
+	suspend_timing_needed = false;
+
 	timekeeping_forward_now(tk);
 
 	__timekeeping_inject_sleeptime(tk, delta);
@@ -1671,8 +1685,8 @@
 	unsigned long flags;
 	struct timespec64 ts_new, ts_delta;
 	cycle_t cycle_now, cycle_delta;
+	bool inject_sleeptime = false;
 
-	sleeptime_injected = false;
 	read_persistent_clock64(&ts_new);
 
 	clockevents_resume();
@@ -1718,14 +1732,16 @@
 		nsec += ((u64) cycle_delta * mult) >> shift;
 
 		ts_delta = ns_to_timespec64(nsec);
-		sleeptime_injected = true;
+		inject_sleeptime = true;
 	} else if (timespec64_compare(&ts_new, &timekeeping_suspend_time) > 0) {
 		ts_delta = timespec64_sub(ts_new, timekeeping_suspend_time);
-		sleeptime_injected = true;
+		inject_sleeptime = true;
 	}
 
-	if (sleeptime_injected)
+	if (inject_sleeptime) {
+		suspend_timing_needed = false;
 		__timekeeping_inject_sleeptime(tk, &ts_delta);
+	}
 
 	/* Re-base the last cycle value */
 	tk->tkr_mono.cycle_last = cycle_now;
@@ -1760,6 +1776,8 @@
 	if (timekeeping_suspend_time.tv_sec || timekeeping_suspend_time.tv_nsec)
 		persistent_clock_exists = true;
 
+	suspend_timing_needed = true;
+
 	raw_spin_lock_irqsave(&timekeeper_lock, flags);
 	write_seqcount_begin(&tk_core.seq);
 	timekeeping_forward_now(tk);