Merge "f2fs: fix unnecessary periodic wakeup of discard thread when dev is busy"
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt
index 83f964d..1e49e96 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt
@@ -308,6 +308,20 @@
 	Definition: Boolean property to support external-rsense based
 		    configuration.
 
+- qcom,shutdown-temp-diff
+	Usage:      optional
+	Value type: <u32>
+	Definition: The allowed battery temperature in deci-degree difference
+		    between shutdown and power-on to continue with the shutdown
+		    SOC. If not specified the default value is 6 degrees C (60).
+
+- qcom,shutdown-soc-threshold
+	Usage:      optional
+	Value type: <u32>
+	Definition: The SOC difference allowed between PON and SHUTDOWN SOC
+		    for the shutdown SOC to be used. If the difference is
+		    beyond this value the PON SOC is used.
+
 ==========================================================
 Second Level Nodes - Peripherals managed by QGAUGE driver
 ==========================================================
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-thermal.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-thermal.dtsi
index 65467f9..0f2fe90 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-thermal.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-thermal.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -339,6 +339,35 @@
 		};
 	};
 
+	mdm-core-step {
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		thermal-governor = "step_wise";
+		thermal-sensors = <&tsens0 4>;
+		trips {
+			mdm_step_trip0: mdm-step-trip-0 {
+				temperature = <95000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+			mdm_step_trip1: mdm-step-trip-1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+		cooling-maps {
+			modem_proc-lv11 {
+				trip = <&mdm_step_trip0>;
+				cooling-device = <&modem_proc 1 1>;
+			};
+			modem_proc_lvl3 {
+				trip = <&mdm_step_trip1>;
+				cooling-device = <&modem_proc 3 3>;
+			};
+		};
+	};
+
 	xo-therm-adc {
 		polling-delay-passive = <0>;
 		polling-delay = <0>;
diff --git a/arch/arm/configs/msm8937-perf_defconfig b/arch/arm/configs/msm8937-perf_defconfig
index df07ed8..447f3de 100644
--- a/arch/arm/configs/msm8937-perf_defconfig
+++ b/arch/arm/configs/msm8937-perf_defconfig
@@ -58,6 +58,7 @@
 CONFIG_ARCH_QCOM=y
 CONFIG_ARCH_MSM8937=y
 CONFIG_ARCH_MSM8917=y
+CONFIG_ARCH_QM215=y
 CONFIG_ARCH_SDM439=y
 CONFIG_ARCH_SDM429=y
 # CONFIG_VDSO is not set
diff --git a/arch/arm/configs/msm8937_defconfig b/arch/arm/configs/msm8937_defconfig
index abb8c6e..5ead5ea 100644
--- a/arch/arm/configs/msm8937_defconfig
+++ b/arch/arm/configs/msm8937_defconfig
@@ -60,6 +60,7 @@
 CONFIG_ARCH_QCOM=y
 CONFIG_ARCH_MSM8937=y
 CONFIG_ARCH_MSM8917=y
+CONFIG_ARCH_QM215=y
 CONFIG_ARCH_SDM439=y
 CONFIG_ARCH_SDM429=y
 # CONFIG_VDSO is not set
diff --git a/arch/arm/configs/msm8937go-perf_defconfig b/arch/arm/configs/msm8937go-perf_defconfig
index 3385173..5032365 100644
--- a/arch/arm/configs/msm8937go-perf_defconfig
+++ b/arch/arm/configs/msm8937go-perf_defconfig
@@ -59,6 +59,7 @@
 CONFIG_ARCH_QCOM=y
 CONFIG_ARCH_MSM8937=y
 CONFIG_ARCH_MSM8917=y
+CONFIG_ARCH_QM215=y
 CONFIG_ARCH_SDM439=y
 CONFIG_ARCH_SDM429=y
 # CONFIG_VDSO is not set
diff --git a/arch/arm/configs/msm8937go_defconfig b/arch/arm/configs/msm8937go_defconfig
index 74af908..35e56e7 100644
--- a/arch/arm/configs/msm8937go_defconfig
+++ b/arch/arm/configs/msm8937go_defconfig
@@ -61,6 +61,7 @@
 CONFIG_ARCH_QCOM=y
 CONFIG_ARCH_MSM8937=y
 CONFIG_ARCH_MSM8917=y
+CONFIG_ARCH_QM215=y
 CONFIG_ARCH_SDM439=y
 CONFIG_ARCH_SDM429=y
 # CONFIG_VDSO is not set
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
index 4e95a7b..a6338e5 100644
--- a/arch/arm/mach-qcom/Kconfig
+++ b/arch/arm/mach-qcom/Kconfig
@@ -126,6 +126,18 @@
 	select HAVE_CLK_PREPARE
 	select COMMON_CLK_MSM
 
+config ARCH_QM215
+	bool "Enable support for QM215"
+	select CPU_V7
+	select HAVE_ARM_ARCH_TIMER
+	select PINCTRL
+	select QCOM_SCM if SMP
+	select PM_DEVFREQ
+	select CLKDEV_LOOKUP
+	select HAVE_CLK
+	select HAVE_CLK_PREPARE
+	select COMMON_CLK_MSM
+
 config ARCH_SDM439
 	bool "Enable support for SDM439"
 	select CPU_V7
diff --git a/arch/arm/mach-qcom/Makefile b/arch/arm/mach-qcom/Makefile
index 3ef169f..7b49f4f 100644
--- a/arch/arm/mach-qcom/Makefile
+++ b/arch/arm/mach-qcom/Makefile
@@ -6,6 +6,7 @@
 obj-$(CONFIG_ARCH_MSM8937) += board-msm8937.o
 obj-$(CONFIG_ARCH_MSM8909) += board-msm8909.o
 obj-$(CONFIG_ARCH_MSM8917) += board-msm8917.o
+obj-$(CONFIG_ARCH_QM215) += board-qm215.o
 obj-$(CONFIG_ARCH_SDM429) += board-sdm429.o
 obj-$(CONFIG_ARCH_SDM439) += board-sdm439.o
 obj-$(CONFIG_ARCH_SDM450) += board-sdm450.o
diff --git a/arch/arm/mach-qcom/board-qm215.c b/arch/arm/mach-qcom/board-qm215.c
new file mode 100644
index 0000000..62f9175
--- /dev/null
+++ b/arch/arm/mach-qcom/board-qm215.c
@@ -0,0 +1,32 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include "board-dt.h"
+#include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+
+static const char *qm215_dt_match[] __initconst = {
+	"qcom,qm215",
+	NULL
+};
+
+static void __init qm215_init(void)
+{
+	board_dt_populate(NULL);
+}
+
+DT_MACHINE_START(QM215_DT,
+	"Qualcomm Technologies, Inc. QM215")
+	.init_machine		= qm215_init,
+	.dt_compat		= qm215_dt_match,
+MACHINE_END
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 4c013ad..a62e936 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -175,6 +175,15 @@
 	  This enables support for the MSM8917 chipset. If you do not
 	  wish to build a kernel that runs on this chipset, say 'N' here.
 
+config ARCH_QM215
+	bool "Enable Support for Qualcomm Technologies Inc. QM215"
+	depends on ARCH_QCOM
+	select CPU_FREQ_QCOM
+	select COMMON_CLK_MSM
+	help
+	  This enables support for the QM215 chipset. If you do not
+	  wish to build a kernel that runs on this chipset, say 'N' here.
+
 config ARCH_SDM450
 	bool "Enable Support for Qualcomm Technologies Inc. SDM450"
 	depends on ARCH_QCOM
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index aae4f68..8cadc32 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -344,8 +344,9 @@
 	msm8917-rcm-overlay.dtbo \
 	apq8017-mtp-overlay.dtbo \
 	apq8017-cdp-overlay.dtbo \
-	apq8017-cdp-wcd-rome-overlay.dtbo \
-	qm215-qrd-overlay.dtbo
+	apq8017-cdp-wcd-rome-overlay.dtbo
+
+dtbo-$(CONFIG_ARCH_QM215) +=qm215-qrd-overlay.dtbo
 
 dtbo-$(CONFIG_ARCH_MSM8953) += msm8953-mtp-overlay.dtbo \
 	msm8953-cdp-overlay.dtbo \
@@ -546,8 +547,9 @@
 	apq8017-pmi8937-cdp-wcd-rome.dtb \
 	msm8917-pmi8940-mtp.dtb \
 	msm8917-pmi8940-cdp.dtb \
-	msm8917-pmi8940-rcm.dtb \
-	qm215-qrd.dtb
+	msm8917-pmi8940-rcm.dtb
+
+dtb-$(CONFIG_ARCH_QM215) += qm215-qrd.dtb
 
 dtb-$(CONFIG_ARCH_MSM8909) += msm8909-pm8916-mtp.dtb \
 	sdw3100-msm8909w-wtp.dtb \
diff --git a/arch/arm64/boot/dts/qcom/qm215.dts b/arch/arm64/boot/dts/qcom/qm215.dts
index 3fd0064..3f0b68e 100644
--- a/arch/arm64/boot/dts/qcom/qm215.dts
+++ b/arch/arm64/boot/dts/qcom/qm215.dts
@@ -17,6 +17,7 @@
 #include "qm215-pm8916.dtsi"
 
 / {
-	model = "Qualcomm Technologies, Inc. QM215 QRD";
+	model = "Qualcomm Technologies, Inc. QM215";
 	compatible = "qcom,qm215";
+	qcom,pmic-name = "PM8916";
 };
diff --git a/arch/arm64/boot/dts/qcom/qm215.dtsi b/arch/arm64/boot/dts/qcom/qm215.dtsi
index dc7ad4c..981f5af 100644
--- a/arch/arm64/boot/dts/qcom/qm215.dtsi
+++ b/arch/arm64/boot/dts/qcom/qm215.dtsi
@@ -16,6 +16,7 @@
 	model = "Qualcomm Technologies, Inc. QM215";
 	compatible = "qcom,qm215";
 	qcom,msm-id = <386 0x0>;
+	qcom,msm-name = "QM215";
 };
 
 &soc {
diff --git a/arch/arm64/configs/msm8937-perf_defconfig b/arch/arm64/configs/msm8937-perf_defconfig
index 5348cb4..45b6643 100644
--- a/arch/arm64/configs/msm8937-perf_defconfig
+++ b/arch/arm64/configs/msm8937-perf_defconfig
@@ -57,6 +57,7 @@
 CONFIG_ARCH_QCOM=y
 CONFIG_ARCH_MSM8937=y
 CONFIG_ARCH_MSM8917=y
+CONFIG_ARCH_QM215=y
 CONFIG_ARCH_SDM429=y
 CONFIG_ARCH_SDM439=y
 # CONFIG_ARM64_ERRATUM_1024718 is not set
diff --git a/arch/arm64/configs/msm8937_defconfig b/arch/arm64/configs/msm8937_defconfig
index 0ff0ec1..f2ec3cc 100644
--- a/arch/arm64/configs/msm8937_defconfig
+++ b/arch/arm64/configs/msm8937_defconfig
@@ -58,6 +58,7 @@
 CONFIG_ARCH_QCOM=y
 CONFIG_ARCH_MSM8937=y
 CONFIG_ARCH_MSM8917=y
+CONFIG_ARCH_QM215=y
 CONFIG_ARCH_SDM429=y
 CONFIG_ARCH_SDM439=y
 # CONFIG_ARM64_ERRATUM_1024718 is not set
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
index 6196a8c..7a0a069 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
@@ -676,6 +676,10 @@
 		rc = 0;
 		break;
 	case MSM_ISP_BUFFER_STATE_QUEUED:
+		if (IS_ENABLED(CONFIG_MSM_ISP_V1)) {
+			rc = 0;
+			break;
+		}
 	case MSM_ISP_BUFFER_STATE_DIVERTED:
 	default:
 		WARN(1, "%s: bufq 0x%x, buf idx 0x%x, incorrect state = %d",
diff --git a/drivers/power/supply/qcom/qg-core.h b/drivers/power/supply/qcom/qg-core.h
index b0ff18c..4f0773b 100644
--- a/drivers/power/supply/qcom/qg-core.h
+++ b/drivers/power/supply/qcom/qg-core.h
@@ -50,11 +50,13 @@
 	int			delta_soc;
 	int			rbat_conn_mohm;
 	int			ignore_shutdown_soc_secs;
+	int			shutdown_temp_diff;
 	int			cold_temp_threshold;
 	int			esr_qual_i_ua;
 	int			esr_qual_v_uv;
 	int			esr_disable_soc;
 	int			esr_min_ibat_ua;
+	int			shutdown_soc_threshold;
 	bool			hold_soc_while_full;
 	bool			linearize_soc;
 	bool			cl_disable;
diff --git a/drivers/power/supply/qcom/qpnp-qg.c b/drivers/power/supply/qcom/qpnp-qg.c
index 855e31d..97256be 100644
--- a/drivers/power/supply/qcom/qpnp-qg.c
+++ b/drivers/power/supply/qcom/qpnp-qg.c
@@ -2514,7 +2514,6 @@
 	return 0;
 }
 
-
 static struct ocv_all ocv[] = {
 	[S7_PON_OCV] = { 0, 0, "S7_PON_OCV"},
 	[S3_GOOD_OCV] = { 0, 0, "S3_GOOD_OCV"},
@@ -2528,7 +2527,7 @@
 	int rc = 0, batt_temp = 0, i;
 	bool use_pon_ocv = true;
 	unsigned long rtc_sec = 0;
-	u32 ocv_uv = 0, soc = 0, shutdown[SDAM_MAX] = {0};
+	u32 ocv_uv = 0, soc = 0, pon_soc = 0, shutdown[SDAM_MAX] = {0};
 	char ocv_type[20] = "NONE";
 
 	if (!chip->profile_loaded) {
@@ -2536,6 +2535,24 @@
 		return 0;
 	}
 
+	/* read all OCVs */
+	for (i = S7_PON_OCV; i < PON_OCV_MAX; i++) {
+		rc = qg_read_ocv(chip, &ocv[i].ocv_uv,
+					&ocv[i].ocv_raw, i);
+		if (rc < 0)
+			pr_err("Failed to read %s OCV rc=%d\n",
+					ocv[i].ocv_type, rc);
+		else
+			qg_dbg(chip, QG_DEBUG_PON, "%s OCV=%d\n",
+					ocv[i].ocv_type, ocv[i].ocv_uv);
+	}
+
+	rc = qg_get_battery_temp(chip, &batt_temp);
+	if (rc) {
+		pr_err("Failed to read BATT_TEMP at PON rc=%d\n", rc);
+		goto done;
+	}
+
 	rc = get_rtc_time(&rtc_sec);
 	if (rc < 0) {
 		pr_err("Failed to read RTC time rc=%d\n", rc);
@@ -2548,47 +2565,50 @@
 		goto use_pon_ocv;
 	}
 
-	qg_dbg(chip, QG_DEBUG_PON, "Shutdown: Valid=%d SOC=%d OCV=%duV time=%dsecs, time_now=%ldsecs\n",
+	rc = lookup_soc_ocv(&pon_soc, ocv[S7_PON_OCV].ocv_uv, batt_temp, false);
+	if (rc < 0) {
+		pr_err("Failed to lookup S7_PON SOC rc=%d\n", rc);
+		goto done;
+	}
+
+	qg_dbg(chip, QG_DEBUG_PON, "Shutdown: Valid=%d SOC=%d OCV=%duV time=%dsecs temp=%d, time_now=%ldsecs temp_now=%d S7_soc=%d\n",
 			shutdown[SDAM_VALID],
 			shutdown[SDAM_SOC],
 			shutdown[SDAM_OCV_UV],
 			shutdown[SDAM_TIME_SEC],
-			rtc_sec);
+			shutdown[SDAM_TEMP],
+			rtc_sec, batt_temp,
+			pon_soc);
 	/*
 	 * Use the shutdown SOC if
-	 * 1. The device was powered off for < ignore_shutdown_time
-	 * 2. SDAM read is a success & SDAM data is valid
+	 * 1. SDAM read is a success & SDAM data is valid
+	 * 2. The device was powered off for < ignore_shutdown_time
+	 * 2. Batt temp has not changed more than shutdown_temp_diff
 	 */
-	if (shutdown[SDAM_VALID] && is_between(0,
-			chip->dt.ignore_shutdown_soc_secs,
-			(rtc_sec - shutdown[SDAM_TIME_SEC]))) {
-		use_pon_ocv = false;
-		ocv_uv = shutdown[SDAM_OCV_UV];
-		soc = shutdown[SDAM_SOC];
-		strlcpy(ocv_type, "SHUTDOWN_SOC", 20);
-		qg_dbg(chip, QG_DEBUG_PON, "Using SHUTDOWN_SOC @ PON\n");
-	}
+	if (!shutdown[SDAM_VALID])
+		goto use_pon_ocv;
+
+	if (!is_between(0, chip->dt.ignore_shutdown_soc_secs,
+			(rtc_sec - shutdown[SDAM_TIME_SEC])))
+		goto use_pon_ocv;
+
+	if (!is_between(0, chip->dt.shutdown_temp_diff,
+			abs(shutdown[SDAM_TEMP] -  batt_temp)))
+		goto use_pon_ocv;
+
+	if ((chip->dt.shutdown_soc_threshold != -EINVAL) &&
+			!is_between(0, chip->dt.shutdown_soc_threshold,
+			abs(pon_soc - shutdown[SDAM_SOC])))
+		goto use_pon_ocv;
+
+	use_pon_ocv = false;
+	ocv_uv = shutdown[SDAM_OCV_UV];
+	soc = shutdown[SDAM_SOC];
+	strlcpy(ocv_type, "SHUTDOWN_SOC", 20);
+	qg_dbg(chip, QG_DEBUG_PON, "Using SHUTDOWN_SOC @ PON\n");
 
 use_pon_ocv:
 	if (use_pon_ocv == true) {
-		rc = qg_get_battery_temp(chip, &batt_temp);
-		if (rc) {
-			pr_err("Failed to read BATT_TEMP at PON rc=%d\n", rc);
-			goto done;
-		}
-
-		/* read all OCVs */
-		for (i = S7_PON_OCV; i < PON_OCV_MAX; i++) {
-			rc = qg_read_ocv(chip, &ocv[i].ocv_uv,
-						&ocv[i].ocv_raw, i);
-			if (rc < 0)
-				pr_err("Failed to read %s OCV rc=%d\n",
-						ocv[i].ocv_type, rc);
-			else
-				qg_dbg(chip, QG_DEBUG_PON, "%s OCV=%d\n",
-					ocv[i].ocv_type, ocv[i].ocv_uv);
-		}
-
 		if (ocv[S3_LAST_OCV].ocv_raw == FIFO_V_RESET_VAL) {
 			if (!ocv[SDAM_PON_OCV].ocv_uv) {
 				strlcpy(ocv_type, "S7_PON_SOC", 20);
@@ -3074,6 +3094,7 @@
 #define DEFAULT_CL_MAX_DEC_DECIPERC	20
 #define DEFAULT_CL_MIN_LIM_DECIPERC	500
 #define DEFAULT_CL_MAX_LIM_DECIPERC	100
+#define DEFAULT_SHUTDOWN_TEMP_DIFF	60	/* 6 degC */
 #define DEFAULT_ESR_QUAL_CURRENT_UA	130000
 #define DEFAULT_ESR_QUAL_VBAT_UV	7000
 #define DEFAULT_ESR_DISABLE_SOC		1000
@@ -3259,6 +3280,12 @@
 	else
 		chip->dt.ignore_shutdown_soc_secs = temp;
 
+	rc = of_property_read_u32(node, "qcom,shutdown-temp-diff", &temp);
+	if (rc < 0)
+		chip->dt.shutdown_temp_diff = DEFAULT_SHUTDOWN_TEMP_DIFF;
+	else
+		chip->dt.shutdown_temp_diff = temp;
+
 	chip->dt.hold_soc_while_full = of_property_read_bool(node,
 					"qcom,hold-soc-while-full");
 
@@ -3302,6 +3329,12 @@
 	else
 		chip->dt.esr_min_ibat_ua = (int)temp;
 
+	rc = of_property_read_u32(node, "qcom,shutdown_soc_threshold", &temp);
+	if (rc < 0)
+		chip->dt.shutdown_soc_threshold = -EINVAL;
+	else
+		chip->dt.shutdown_soc_threshold = temp;
+
 	chip->dt.qg_ext_sense = of_property_read_bool(node, "qcom,qg-ext-sns");
 
 	/* Capacity learning params*/