Merge "platform: qpnp-revid: Add subtype for PM8953"
diff --git a/Documentation/devicetree/bindings/arm/msm/proxy-client.txt b/Documentation/devicetree/bindings/arm/msm/proxy-client.txt
new file mode 100644
index 0000000..29cfaf9
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/proxy-client.txt
@@ -0,0 +1,34 @@
+Bus Proxy Client Bindings
+
+Bus proxy client provides means to cast proxy bandwidth votes during bootup
+which is removed at the end of boot. This feature can be used in situations
+where a shared resource can be scaled between several possible perfomance
+levels and hardware requires that it be at a high level at the beginning of
+boot before the client has probed and voted for required bandwidth.
+
+Required properties:
+- compatible:			Must be "qcom,bus-proxy-client".
+
+Optional properties:
+- qcom,msm-bus,name:		String representing the client-name.
+- qcom,msm-bus,num-cases:	Total number of usecases.
+- qcom,msm-bus,active-only:	Boolean context flag for requests in active or
+				dual (active & sleep) contex.
+- qcom,msm-bus,num-paths:	Total number of master-slave pairs.
+- qcom,msm-bus,vectors-KBps:	Arrays of unsigned integers representing:
+				master-id, slave-id, arbitrated bandwidth
+				in KBps, instantaneous bandwidth in KBps.
+
+Example:
+
+	qcom,proxy-client {
+		compatible = "qcom,bus-proxy-client";
+		qcom,msm-bus,name = "proxy_client";
+		qcom,msm-bus,num-cases = <3>;
+		qcom,msm-bus,num-paths = <2>;
+		qcom,msm-bus,active-only;
+		qcom,msm-bus,vectors-KBps =
+			<22 512 0 0>, <23 512 0 0>,
+			<22 512 0 6400000>, <23 512 0 6400000>,
+			<22 512 0 6400000>, <23 512 0 6400000>;
+	};
diff --git a/Documentation/devicetree/bindings/usb/msm-phy.txt b/Documentation/devicetree/bindings/usb/msm-phy.txt
index c0a260f..b880890 100644
--- a/Documentation/devicetree/bindings/usb/msm-phy.txt
+++ b/Documentation/devicetree/bindings/usb/msm-phy.txt
@@ -24,6 +24,9 @@
  - reset-names: reset signal name strings sorted in the same order as the resets
    property.
 
+Optional properties:
+ - qcom,param-override-seq: parameter override sequence with value, reg offset pair.
+
 Example:
 	hsphy@f9200000 {
 		compatible = "qcom,usb-hsphy-snps-femto";
@@ -32,6 +35,7 @@
 		vdda18-supply = <&pm8941_l6>;
 		vdda33-supply = <&pm8941_l24>;
 		qcom,vdd-voltage-level = <0 872000 872000>;
+		qcom,param-override-seq = <0x43 0x70>;
 	};
 
 SSUSB-QMP PHY
diff --git a/arch/arm/boot/dts/qcom/pm8950.dtsi b/arch/arm/boot/dts/qcom/pm8950.dtsi
deleted file mode 100644
index f47872a..0000000
--- a/arch/arm/boot/dts/qcom/pm8950.dtsi
+++ /dev/null
@@ -1,388 +0,0 @@
-/* Copyright (c) 2015-2017, 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.
- */
-
-&spmi_bus {
-	qcom,pm8950@0 {
-		compatible ="qcom,spmi-pmic";
-		reg = <0x0 SPMI_USID>;
-		#address-cells = <2>;
-		#size-cells = <0>;
-
-		pm8950_revid: qcom,revid@100 {
-			compatible = "qcom,qpnp-revid";
-			reg = <0x100 0x100>;
-		};
-
-		pm8950_temp_alarm: qcom,temp-alarm@2400 {
-			compatible = "qcom,qpnp-temp-alarm";
-			reg = <0x2400 0x100>;
-			interrupts = <0x0 0x24 0x0>;
-			label = "pm8950_tz";
-			qcom,channel-num = <8>;
-			qcom,threshold-set = <0>;
-			qcom,temp_alarm-vadc = <&pm8950_vadc>;
-		};
-
-		qcom,power-on@800 {
-			compatible = "qcom,qpnp-power-on";
-			reg = <0x800 0x100>;
-			interrupts = <0x0 0x8 0x0>,
-				<0x0 0x8 0x1>,
-				<0x0 0x8 0x4>,
-				<0x0 0x8 0x5>;
-			interrupt-names = "kpdpwr", "resin",
-				"resin-bark", "kpdpwr-resin-bark";
-			qcom,pon-dbc-delay = <15625>;
-			qcom,system-reset;
-
-			qcom,pon_1 {
-				qcom,pon-type = <0>;
-				qcom,pull-up = <1>;
-				linux,code = <116>;
-			};
-
-			qcom,pon_2 {
-				qcom,pon-type = <1>;
-				qcom,pull-up = <1>;
-				linux,code = <114>;
-			};
-		};
-
-		pm8950_coincell: qcom,coincell@2800 {
-			compatible = "qcom,qpnp-coincell";
-			reg = <0x2800 0x100>;
-		};
-
-		pm8950_mpps: mpps {
-			compatible = "qcom,qpnp-pin";
-			spmi-dev-container;
-			gpio-controller;
-			#gpio-cells = <2>;
-			#address-cells = <1>;
-			#size-cells = <1>;
-			label = "pm8950-mpp";
-
-			mpp@a000 {
-				reg = <0xa000 0x100>;
-				qcom,pin-num = <1>;
-				status = "disabled";
-			};
-
-			mpp@a100 {
-				/* MPP2 - PA_THERM config */
-				reg = <0xa100 0x100>;
-				qcom,pin-num = <2>;
-				qcom,mode = <4>; /* AIN input */
-				qcom,invert = <1>; /* Enable MPP */
-				qcom,ain-route = <1>; /* AMUX 6 */
-				qcom,master-en = <1>;
-				qcom,src-sel = <0>; /* Function constant */
-			};
-
-			mpp@a200 {
-				reg = <0xa200 0x100>;
-				qcom,pin-num = <3>;
-				status = "disabled";
-			};
-
-			mpp@a300 {
-				/* MPP4 - CASE_THERM config */
-				reg = <0xa300 0x100>;
-				qcom,pin-num = <4>;
-				qcom,mode = <4>; /* AIN input */
-				qcom,invert = <1>; /* Enable MPP */
-				qcom,ain-route = <3>; /* AMUX 8 */
-				qcom,master-en = <1>;
-				qcom,src-sel = <0>; /* Function constant */
-			};
-		};
-
-		pm8950_gpios: gpios {
-			spmi-dev-container;
-			compatible = "qcom,qpnp-pin";
-			gpio-controller;
-			#gpio-cells = <2>;
-			#address-cells = <1>;
-			#size-cells = <1>;
-			label = "pm8950-gpio";
-
-			gpio@c000 {
-				reg = <0xc000 0x100>;
-				qcom,pin-num = <1>;
-				status = "disabled";
-			};
-
-			gpio@c100 {
-				reg = <0xc100 0x100>;
-				qcom,pin-num = <2>;
-				status = "disabled";
-			};
-
-			gpio@c200 {
-				reg = <0xc200 0x100>;
-				qcom,pin-num = <3>;
-				status = "disabled";
-			};
-
-			gpio@c300 {
-				reg = <0xc300 0x100>;
-				qcom,pin-num = <4>;
-				status = "disabled";
-			};
-
-			gpio@c400 {
-				reg = <0xc400 0x100>;
-				qcom,pin-num = <5>;
-				status = "disabled";
-			};
-
-			gpio@c500 {
-				reg = <0xc500 0x100>;
-				qcom,pin-num = <6>;
-				status = "disabled";
-			};
-
-			gpio@c600 {
-				reg = <0xc600 0x100>;
-				qcom,pin-num = <7>;
-				status = "disabled";
-			};
-
-			gpio@c700 {
-				reg = <0xc700 0x100>;
-				qcom,pin-num = <8>;
-				status = "disabled";
-			};
-		};
-
-		pm8950_vadc: vadc@3100 {
-			compatible = "qcom,qpnp-vadc";
-			reg = <0x3100 0x100>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			interrupts = <0x0 0x31 0x0>;
-			interrupt-names = "eoc-int-en-set";
-			qcom,adc-bit-resolution = <15>;
-			qcom,adc-vdd-reference = <1800>;
-			qcom,vadc-poll-eoc;
-			qcom,pmic-revid = <&pm8950_revid>;
-
-			chan@5 {
-				label = "vcoin";
-				reg = <5>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <1>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@7 {
-				label = "vph_pwr";
-				reg = <7>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <1>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@8 {
-				label = "die_temp";
-				reg = <8>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <3>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@9 {
-				label = "ref_625mv";
-				reg = <9>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@a {
-				label = "ref_1250v";
-				reg = <0xa>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@c {
-				label = "ref_buf_625mv";
-				reg = <0xc>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@36 {
-				label = "pa_therm0";
-				reg = <0x36>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@11 {
-				label = "pa_therm1";
-				reg = <0x11>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <0>;
-				qcom,vadc-thermal-node;
-			};
-
-			chan@32 {
-				label = "xo_therm";
-				reg = <0x32>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <4>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <0>;
-				qcom,vadc-thermal-node;
-			};
-
-			chan@3c {
-				label = "xo_therm_buf";
-				reg = <0x3c>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <4>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <0>;
-				qcom,vadc-thermal-node;
-			};
-
-			chan@13 {
-				label = "case_therm";
-				reg = <0x13>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <0>;
-				qcom,vadc-thermal-node;
-			};
-		};
-
-		pm8950_adc_tm: vadc@3400 {
-			compatible = "qcom,qpnp-adc-tm";
-			reg = <0x3400 0x100>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			interrupts =	<0x0 0x34 0x0>,
-					<0x0 0x34 0x3>,
-					<0x0 0x34 0x4>;
-			interrupt-names =	"eoc-int-en-set",
-						"high-thr-en-set",
-						"low-thr-en-set";
-			qcom,adc-bit-resolution = <15>;
-			qcom,adc-vdd-reference = <1800>;
-			qcom,adc_tm-vadc = <&pm8950_vadc>;
-			qcom,pmic-revid = <&pm8950_revid>;
-
-			chan@36 {
-				label = "pa_therm0";
-				reg = <0x36>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <0>;
-				qcom,btm-channel-number = <0x48>;
-				qcom,thermal-node;
-			};
-
-			chan@7 {
-				label = "vph_pwr";
-				reg = <0x7>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <1>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-				qcom,btm-channel-number = <0x68>;
-			};
-		};
-
-		pm8950_rtc: qcom,pm8950_rtc {
-			spmi-dev-container;
-			compatible = "qcom,qpnp-rtc";
-			#address-cells = <1>;
-			#size-cells = <1>;
-			qcom,qpnp-rtc-write = <0>;
-			qcom,qpnp-rtc-alarm-pwrup = <0>;
-
-			qcom,pm8950_rtc_rw@6000 {
-				reg = <0x6000 0x100>;
-			};
-
-			qcom,pm8950_rtc_alarm@6100 {
-				reg = <0x6100 0x100>;
-				interrupts = <0x0 0x61 0x1>;
-			};
-		};
-
-		qcom,leds@a300 {
-			compatible = "qcom,leds-qpnp";
-			reg = <0xa300 0x100>;
-			label = "mpp";
-		};
-	};
-
-	pm8950_1: qcom,pm8950@1 {
-		compatible ="qcom,spmi-pmic";
-		reg = <0x1 SPMI_USID>;
-		#address-cells = <2>;
-		#size-cells = <0>;
-
-		pm8950_pwm: pwm@bc00 {
-			status = "disabled";
-			compatible = "qcom,qpnp-pwm";
-			reg = <0xbc00 0x100>;
-			reg-names = "qpnp-lpg-channel-base";
-			qcom,channel-id = <0>;
-			qcom,supported-sizes = <6>, <9>;
-			#pwm-cells = <2>;
-		};
-	};
-};
diff --git a/arch/arm/boot/dts/qcom/pmi8950.dtsi b/arch/arm/boot/dts/qcom/pmi8950.dtsi
deleted file mode 100644
index 0ec1f0b..0000000
--- a/arch/arm/boot/dts/qcom/pmi8950.dtsi
+++ /dev/null
@@ -1,641 +0,0 @@
-/* Copyright (c) 2015-2017, 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 <dt-bindings/msm/power-on.h>
-
-&spmi_bus {
-	qcom,pmi8950@2 {
-		compatible ="qcom,spmi-pmic";
-		reg = <0x2 SPMI_USID>;
-		#address-cells = <2>;
-		#size-cells = <0>;
-
-		pmi8950_revid: qcom,revid@100 {
-			compatible = "qcom,qpnp-revid";
-			reg = <0x100 0x100>;
-		};
-
-		qcom,power-on@800 {
-			compatible = "qcom,qpnp-power-on";
-			reg = <0x800 0x100>;
-			qcom,secondary-pon-reset;
-			qcom,hard-reset-poweroff-type =
-				<PON_POWER_OFF_SHUTDOWN>;
-
-			pon_perph_reg: qcom,pon_perph_reg {
-				regulator-name = "pon_spare_reg";
-				qcom,pon-spare-reg-addr = <0x8c>;
-				qcom,pon-spare-reg-bit = <1>;
-			};
-		};
-
-		pmi8950_vadc: vadc@3100 {
-			compatible = "qcom,qpnp-vadc";
-			reg = <0x3100 0x100>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			interrupts = <0x2 0x31 0x0>;
-			interrupt-names = "eoc-int-en-set";
-			qcom,adc-bit-resolution = <15>;
-			qcom,adc-vdd-reference = <1800>;
-			qcom,vadc-poll-eoc;
-
-			chan@0 {
-				label = "usbin";
-				reg = <0>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <4>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@1 {
-				label = "dcin";
-				reg = <1>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <4>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@3 {
-				label = "vchg_sns";
-				reg = <3>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <1>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@9 {
-				label = "ref_625mv";
-				reg = <9>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@a {
-				label = "ref_1250v";
-				reg = <0xa>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@d {
-				label = "chg_temp";
-				reg = <0xd>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <16>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-				qcom,vadc-thermal-node;
-			};
-
-			chan@43 {
-				label = "usb_dp";
-				reg = <0x43>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <1>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@44 {
-				label = "usb_dm";
-				reg = <0x44>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <1>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-		};
-
-		pmi8950_gpios: gpios {
-			spmi-dev-container;
-			compatible = "qcom,qpnp-pin";
-			gpio-controller;
-			#gpio-cells = <2>;
-			#address-cells = <1>;
-			#size-cells = <1>;
-			label = "pmi8950-gpio";
-
-			gpio@c000 {
-				reg = <0xc000 0x100>;
-				qcom,pin-num = <1>;
-				status = "disabled";
-			};
-
-			gpio@c100 {
-				reg = <0xc100 0x100>;
-				qcom,pin-num = <2>;
-				status = "disabled";
-			};
-		};
-
-		pmi8950_mpps: mpps {
-			spmi-dev-container;
-			compatible = "qcom,qpnp-pin";
-			gpio-controller;
-			#gpio-cells = <2>;
-			#address-cells = <1>;
-			#size-cells = <1>;
-			label = "pmi8950-mpp";
-
-			mpp@a000 {
-				reg = <0xa000 0x100>;
-				qcom,pin-num = <1>;
-				status = "disabled";
-			};
-
-			mpp@a100 {
-				reg = <0xa100 0x100>;
-				qcom,pin-num = <2>;
-				status = "disabled";
-			};
-
-			mpp@a200 {
-				reg = <0xa200 0x100>;
-				qcom,pin-num = <3>;
-				status = "disabled";
-			};
-
-			mpp@a300 {
-				reg = <0xa300 0x100>;
-				qcom,pin-num = <4>;
-				status = "disabled";
-			};
-		};
-
-		pmi8950_charger: qcom,qpnp-smbcharger {
-			spmi-dev-container;
-			compatible = "qcom,qpnp-smbcharger";
-			#address-cells = <1>;
-			#size-cells = <1>;
-
-			qcom,iterm-ma = <100>;
-			qcom,float-voltage-mv = <4200>;
-			qcom,resume-delta-mv = <200>;
-			qcom,chg-inhibit-fg;
-			qcom,rparasitic-uohm = <100000>;
-			qcom,bms-psy-name = "bms";
-			qcom,thermal-mitigation = <1500 700 600 0>;
-			qcom,parallel-usb-min-current-ma = <1400>;
-			qcom,parallel-usb-9v-min-current-ma = <900>;
-			qcom,parallel-allowed-lowering-ma = <500>;
-			qcom,pmic-revid = <&pmi8950_revid>;
-			qcom,force-aicl-rerun;
-			qcom,aicl-rerun-period-s = <180>;
-			qcom,autoadjust-vfloat;
-
-			qcom,chgr@1000 {
-				reg = <0x1000 0x100>;
-				interrupts =	<0x2 0x10 0x0>,
-						<0x2 0x10 0x1>,
-						<0x2 0x10 0x2>,
-						<0x2 0x10 0x3>,
-						<0x2 0x10 0x4>,
-						<0x2 0x10 0x5>,
-						<0x2 0x10 0x6>,
-						<0x2 0x10 0x7>;
-
-				interrupt-names =	"chg-error",
-							"chg-inhibit",
-							"chg-prechg-sft",
-							"chg-complete-chg-sft",
-							"chg-p2f-thr",
-							"chg-rechg-thr",
-							"chg-taper-thr",
-							"chg-tcc-thr";
-			};
-
-			qcom,otg@1100 {
-				reg = <0x1100 0x100>;
-				interrupts =	<0x2 0x11 0x0>,
-						<0x2 0x11 0x1>,
-						<0x2 0x11 0x3>;
-				interrupt-names =	"otg-fail",
-							"otg-oc",
-						"usbid-change";
-			};
-
-			qcom,bat-if@1200 {
-				reg = <0x1200 0x100>;
-				interrupts =	<0x2 0x12 0x0>,
-						<0x2 0x12 0x1>,
-						<0x2 0x12 0x2>,
-						<0x2 0x12 0x3>,
-					<0x2 0x12 0x4>,
-						<0x2 0x12 0x5>,
-						<0x2 0x12 0x6>,
-						<0x2 0x12 0x7>;
-
-				interrupt-names =	"batt-hot",
-							"batt-warm",
-							"batt-cold",
-							"batt-cool",
-						"batt-ov",
-							"batt-low",
-							"batt-missing",
-							"batt-term-missing";
-			};
-
-			qcom,usb-chgpth@1300 {
-				reg = <0x1300 0x100>;
-				interrupts =	<0x2 0x13 0x0>,
-						<0x2 0x13 0x1>,
-					<0x2 0x13 0x2>,
-						<0x2 0x13 0x5>;
-
-				interrupt-names =	"usbin-uv",
-						"usbin-ov",
-							"usbin-src-det",
-							"aicl-done";
-			};
-
-			qcom,dc-chgpth@1400 {
-				reg = <0x1400 0x100>;
-				interrupts =	<0x2 0x14 0x0>,
-						<0x2 0x14 0x1>;
-				interrupt-names =	"dcin-uv",
-							"dcin-ov";
-			};
-
-			qcom,chgr-misc@1600 {
-				reg = <0x1600 0x100>;
-				interrupts =	<0x2 0x16 0x0>,
-						<0x2 0x16 0x1>,
-						<0x2 0x16 0x2>,
-					<0x2 0x16 0x3>,
-						<0x2 0x16 0x4>,
-						<0x2 0x16 0x5>;
-
-				interrupt-names =	"power-ok",
-							"temp-shutdown",
-							"wdog-timeout",
-							"flash-fail",
-							"otst2",
-							"otst3";
-			};
-
-			smbcharger_charger_otg: qcom,smbcharger-boost-otg {
-				regulator-name = "smbcharger_charger_otg";
-			};
-		};
-
-		pmi8950_fg: qcom,fg {
-			spmi-dev-container;
-			compatible = "qcom,qpnp-fg";
-			#address-cells = <1>;
-			#size-cells = <1>;
-			qcom,resume-soc = <95>;
-			status = "okay";
-			qcom,bcl-lm-threshold-ma = <127>;
-			qcom,bcl-mh-threshold-ma = <405>;
-			qcom,fg-iterm-ma = <150>;
-			qcom,fg-chg-iterm-ma = <100>;
-			qcom,pmic-revid = <&pmi8950_revid>;
-			qcom,fg-cutoff-voltage-mv = <3500>;
-			qcom,cycle-counter-en;
-			qcom,capacity-learning-on;
-
-			qcom,fg-soc@4000 {
-			status = "okay";
-				reg = <0x4000 0x100>;
-				interrupts =	<0x2 0x40 0x0>,
-						<0x2 0x40 0x1>,
-						<0x2 0x40 0x2>,
-						<0x2 0x40 0x3>,
-						<0x2 0x40 0x4>,
-						<0x2 0x40 0x5>,
-						<0x2 0x40 0x6>;
-
-				interrupt-names =	"high-soc",
-							"low-soc",
-							"full-soc",
-							"empty-soc",
-							"delta-soc",
-							"first-est-done",
-							"update-soc";
-			};
-
-			qcom,fg-batt@4100 {
-				reg = <0x4100 0x100>;
-				interrupts =	<0x2 0x41 0x0>,
-						<0x2 0x41 0x1>,
-					<0x2 0x41 0x2>,
-						<0x2 0x41 0x3>,
-						<0x2 0x41 0x4>,
-						<0x2 0x41 0x5>,
-						<0x2 0x41 0x6>,
-						<0x2 0x41 0x7>;
-
-				interrupt-names =	"soft-cold",
-							"soft-hot",
-							"vbatt-low",
-							"batt-ided",
-							"batt-id-req",
-							"batt-unknown",
-							"batt-missing",
-							"batt-match";
-			};
-
-			qcom,revid-tp-rev@1f1 {
-				reg = <0x1f1 0x1>;
-			};
-
-			qcom,fg-memif@4400 {
-				status = "okay";
-				reg = <0x4400 0x100>;
-				interrupts =	<0x2 0x44 0x0>,
-						<0x2 0x44 0x2>;
-
-				interrupt-names =	"mem-avail",
-							"data-rcvry-sug";
-			};
-		};
-
-		bcl@4200 {
-			compatible = "qcom,msm-bcl";
-			reg = <0x4200 0xFF 0x88E 0x2>;
-			reg-names = "fg_user_adc", "pon_spare";
-			interrupts = <0x2 0x42 0x0>,
-					<0x2 0x42 0x1>;
-			interrupt-names = "bcl-high-ibat-int",
-					"bcl-low-vbat-int";
-			qcom,vbat-scaling-factor = <39000>;
-			qcom,vbat-gain-numerator = <1>;
-			qcom,vbat-gain-denominator = <128>;
-			qcom,vbat-polling-delay-ms = <100>;
-			qcom,ibat-scaling-factor = <39000>;
-			qcom,ibat-gain-numerator = <1>;
-			qcom,ibat-gain-denominator = <128>;
-			qcom,ibat-offset-numerator = <1200>;
-			qcom,ibat-offset-denominator = <1>;
-			qcom,ibat-polling-delay-ms = <100>;
-			qcom,inhibit-derating-ua = <550000>;
-		};
-
-		qcom,leds@a100 {
-			compatible = "qcom,leds-qpnp";
-			reg = <0xa100 0x100>;
-			label = "mpp";
-		};
-	};
-
-	qcom,pmi8950@3 {
-		compatible ="qcom,spmi-pmic";
-		reg = <0x3 SPMI_USID>;
-		#address-cells = <1>;
-		#size-cells = <1>;
-
-		pmi8950_pwm: pwm@b000 {
-			status = "disabled";
-			compatible = "qcom,qpnp-pwm";
-			reg = <0xb000 0x100>;
-			reg-names = "qpnp-lpg-channel-base";
-			qcom,channel-id = <0>;
-			qcom,supported-sizes = <6>, <9>;
-			#pwm-cells = <2>;
-		};
-
-		labibb: qpnp-labibb-regulator {
-			status = "disabled";
-			spmi-dev-container;
-			compatible = "qcom,qpnp-labibb-regulator";
-			#address-cells = <1>;
-			#size-cells = <1>;
-			qcom,pmic-revid = <&pmi8950_revid>;
-
-			ibb_regulator: qcom,ibb@dc00 {
-				reg = <0xdc00 0x100>;
-				reg-names = "ibb_reg";
-				regulator-name = "ibb_reg";
-
-				regulator-min-microvolt = <4600000>;
-				regulator-max-microvolt = <6000000>;
-
-				qcom,qpnp-ibb-min-voltage = <1400000>;
-				qcom,qpnp-ibb-step-size = <100000>;
-				qcom,qpnp-ibb-slew-rate = <2000000>;
-				qcom,qpnp-ibb-use-default-voltage;
-				qcom,qpnp-ibb-init-voltage = <5500000>;
-				qcom,qpnp-ibb-init-amoled-voltage = <4000000>;
-				qcom,qpnp-ibb-init-lcd-voltage = <5500000>;
-
-				qcom,qpnp-ibb-soft-start = <1000>;
-
-				qcom,qpnp-ibb-discharge-resistor = <32>;
-				qcom,qpnp-ibb-lab-pwrup-delay = <8000>;
-				qcom,qpnp-ibb-lab-pwrdn-delay = <8000>;
-				qcom,qpnp-ibb-en-discharge;
-
-				qcom,qpnp-ibb-full-pull-down;
-				qcom,qpnp-ibb-pull-down-enable;
-				qcom,qpnp-ibb-switching-clock-frequency =
-									<1480>;
-				qcom,qpnp-ibb-limit-maximum-current = <1550>;
-				qcom,qpnp-ibb-debounce-cycle = <16>;
-				qcom,qpnp-ibb-limit-max-current-enable;
-				qcom,qpnp-ibb-ps-enable;
-			};
-
-			lab_regulator: qcom,lab@de00 {
-				reg = <0xde00 0x100>;
-				reg-names = "lab";
-				regulator-name = "lab_reg";
-
-				regulator-min-microvolt = <4600000>;
-				regulator-max-microvolt = <6000000>;
-
-				qcom,qpnp-lab-min-voltage = <4600000>;
-				qcom,qpnp-lab-step-size = <100000>;
-				qcom,qpnp-lab-slew-rate = <5000>;
-				qcom,qpnp-lab-use-default-voltage;
-				qcom,qpnp-lab-init-voltage = <5500000>;
-				qcom,qpnp-lab-init-amoled-voltage = <4600000>;
-				qcom,qpnp-lab-init-lcd-voltage = <5500000>;
-
-				qcom,qpnp-lab-soft-start = <800>;
-
-				qcom,qpnp-lab-full-pull-down;
-				qcom,qpnp-lab-pull-down-enable;
-				qcom,qpnp-lab-switching-clock-frequency =
-									<1600>;
-				qcom,qpnp-lab-limit-maximum-current = <800>;
-				qcom,qpnp-lab-limit-max-current-enable;
-				qcom,qpnp-lab-ps-threshold = <40>;
-				qcom,qpnp-lab-ps-enable;
-				qcom,qpnp-lab-nfet-size = <100>;
-				qcom,qpnp-lab-pfet-size = <100>;
-				qcom,qpnp-lab-max-precharge-time = <500>;
-			};
-
-		};
-
-		wled: qcom,leds@d800 {
-			compatible = "qcom,qpnp-wled";
-			reg = <0xd800 0x100>,
-				<0xd900 0x100>,
-				<0xdc00 0x100>,
-				<0xde00 0x100>;
-			reg-names = "qpnp-wled-ctrl-base",
-					"qpnp-wled-sink-base",
-					"qpnp-wled-ibb-base",
-					"qpnp-wled-lab-base";
-			interrupts = <0x3 0xd8 0x2>;
-			interrupt-names = "sc-irq";
-			status = "okay";
-			linux,name = "wled";
-			linux,default-trigger = "bkl-trigger";
-			qcom,fdbk-output = "auto";
-			qcom,vref-mv = <350>;
-			qcom,switch-freq-khz = <800>;
-			qcom,ovp-mv = <29500>;
-			qcom,ilim-ma = <980>;
-			qcom,boost-duty-ns = <26>;
-			qcom,mod-freq-khz = <9600>;
-			qcom,dim-mode = "hybrid";
-			qcom,dim-method = "linear";
-			qcom,hyb-thres = <625>;
-			qcom,sync-dly-us = <800>;
-			qcom,fs-curr-ua = <20000>;
-			qcom,led-strings-list = [00 01];
-			qcom,en-ext-pfet-sc-pro;
-			qcom,cons-sync-write-delay-us = <1000>;
-		};
-
-		flash_led: qcom,leds@d300 {
-			compatible = "qcom,qpnp-flash-led";
-			status = "okay";
-			reg = <0xd300 0x100>;
-			label = "flash";
-			qcom,headroom = <500>;
-			qcom,startup-dly = <128>;
-			qcom,clamp-curr = <200>;
-			qcom,pmic-charger-support;
-			qcom,self-check-enabled;
-			qcom,thermal-derate-enabled;
-			qcom,thermal-derate-threshold = <100>;
-			qcom,thermal-derate-rate = "5_PERCENT";
-			qcom,current-ramp-enabled;
-			qcom,ramp_up_step = "6P7_US";
-			qcom,ramp_dn_step = "6P7_US";
-			qcom,vph-pwr-droop-enabled;
-			qcom,vph-pwr-droop-threshold = <3000>;
-			qcom,vph-pwr-droop-debounce-time = <10>;
-			qcom,headroom-sense-ch0-enabled;
-			qcom,headroom-sense-ch1-enabled;
-			qcom,pmic-revid = <&pmi8950_revid>;
-
-			pmi8950_flash0: qcom,flash_0 {
-				label = "flash";
-				qcom,led-name = "led:flash_0";
-				qcom,default-led-trigger =
-						"flash0_trigger";
-				qcom,max-current = <1000>;
-				qcom,duration = <1280>;
-				qcom,id = <0>;
-				qcom,current = <625>;
-			};
-
-			pmi8950_flash1: qcom,flash_1 {
-				label = "flash";
-				qcom,led-name = "led:flash_1";
-				qcom,default-led-trigger =
-						"flash1_trigger";
-				qcom,max-current = <1000>;
-				qcom,duration = <1280>;
-				qcom,id = <1>;
-				qcom,current = <625>;
-			};
-
-			pmi8950_torch0: qcom,torch_0 {
-				label = "torch";
-				qcom,led-name = "led:torch_0";
-				qcom,default-led-trigger =
-						"torch0_trigger";
-				qcom,max-current = <200>;
-				qcom,id = <0>;
-				qcom,current = <120>;
-			};
-
-			pmi8950_torch1: qcom,torch_1 {
-				label = "torch";
-				qcom,led-name = "led:torch_1";
-				qcom,default-led-trigger =
-						"torch1_trigger";
-				qcom,max-current = <200>;
-				qcom,id = <1>;
-				qcom,current = <120>;
-			};
-
-			pmi8950_switch: qcom,switch {
-				label = "switch";
-				qcom,led-name = "led:switch";
-				qcom,default-led-trigger =
-						"switch_trigger";
-				qcom,max-current = <1000>;
-				qcom,duration = <1280>;
-				qcom,id = <2>;
-				qcom,current = <625>;
-				reg0 {
-					regulator-name = "pon_spare_reg";
-				};
-			};
-		};
-
-		pmi_haptic: qcom,haptic@c000 {
-			compatible = "qcom,qpnp-haptic";
-			reg = <0xc000 0x100>;
-			interrupts = <0x3 0xc0 0x0>,
-					<0x3 0xc0 0x1>;
-			interrupt-names = "sc-irq", "play-irq";
-			qcom,pmic-revid = <&pmi8950_revid>;
-			vcc_pon-supply = <&pon_perph_reg>;
-			qcom,play-mode = "direct";
-			qcom,wave-play-rate-us = <5263>;
-			qcom,actuator-type = "erm";
-			qcom,wave-shape = "square";
-			qcom,vmax-mv = <2000>;
-			qcom,ilim-ma = <800>;
-			qcom,sc-deb-cycles = <8>;
-			qcom,int-pwm-freq-khz = <505>;
-			qcom,en-brake;
-			qcom,brake-pattern = [03 03 00 00];
-			qcom,use-play-irq;
-			qcom,use-sc-irq;
-			qcom,wave-samples = [3e 3e 3e 3e 3e 3e 3e 3e];
-			qcom,wave-rep-cnt = <1>;
-			qcom,wave-samp-rep-cnt = <1>;
-		};
-	};
-};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi
index 6c172c1..e3f49d0 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi
@@ -1465,6 +1465,64 @@
 				input-enable;
 			};
 		};
+
+		cnss_pins {
+			cnss_wlan_en_active: cnss_wlan_en_active {
+				mux {
+					pins = "gpio52";
+					function = "gpio";
+				};
+
+				config {
+					pins = "gpio52";
+					drive-strength = <16>;
+					output-high;
+					bias-pull-up;
+				};
+			};
+
+			cnss_wlan_en_sleep: cnss_wlan_en_sleep {
+				mux {
+					pins = "gpio52";
+					function = "gpio";
+				};
+
+				config {
+					pins = "gpio52";
+					drive-strength = <2>;
+					output-low;
+					bias-pull-down;
+				};
+			};
+
+			cnss_sdio_active: cnss_sdio_active {
+				mux {
+					pins = "gpio31";
+					function = "gpio";
+				};
+
+				config {
+					pins = "gpio31";
+					drive-strength = <16>;
+					output-high;
+					bias-pull-up;
+				};
+			};
+
+			cnss_sdio_sleep: cnss_sdio_sleep {
+				mux {
+					pins = "gpio31";
+					function = "gpio";
+				};
+
+				config {
+					pins = "gpio31";
+					drive-strength = <2>;
+					output-low;
+					bias-pull-down;
+				};
+			};
+		};
 	};
 };
 
@@ -1475,4 +1533,11 @@
 			bias-high-impedance;
 		};
 	};
+
+	vdd_wlan {
+		vdd_wlan_default: vdd_wlan_default {
+			pins = "gpio6";
+			bias-high-impedance;
+		};
+	};
 };
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-regulator.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-regulator.dtsi
index 162f0d9..7543f7c 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-regulator.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-regulator.dtsi
@@ -404,4 +404,12 @@
 		gpio = <&tlmm 83 GPIO_ACTIVE_HIGH>;
 		enable-active-high;
 	};
+
+	vreg_wlan: vreg_wlan {
+		compatible = "regulator-fixed";
+		regulator-name = "vreg_wlan";
+		startup-delay-us = <4000>;
+		enable-active-high;
+		gpio = <&pmxpoorwills_gpios 6 GPIO_ACTIVE_HIGH>;
+	};
 };
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-usb.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-usb.dtsi
index ec65472..3bccd8a 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-usb.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-usb.dtsi
@@ -126,6 +126,9 @@
 
 		resets = <&clock_gcc GCC_QUSB2PHY_BCR>;
 		reset-names = "phy_reset";
+
+		/* override parameters */
+		qcom,param-override-seq = <0x43 0x70>; /* override_x1 */
 	};
 
 	dbm_1p5: dbm@a6f8000 {
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
index aa79180..d9a84d9 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
@@ -61,6 +61,12 @@
 			reusable;
 			size = <0x400000>;
 		 };
+
+		dump_mem: mem_dump_region {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0 0x2400000>;
+		};
 	};
 
 	cpus {
@@ -727,6 +733,56 @@
 		reg = <0xc37000c 8>;
 	};
 
+	mem_dump {
+		compatible = "qcom,mem-dump";
+		memory-region = <&dump_mem>;
+
+		rpmh_dump {
+			qcom,dump-size = <0x2000000>;
+			qcom,dump-id = <0xec>;
+		};
+
+		fcm_dump {
+			qcom,dump-size = <0x8400>;
+			qcom,dump-id = <0xee>;
+		};
+
+		rpm_sw_dump {
+			qcom,dump-size = <0x28000>;
+			qcom,dump-id = <0xea>;
+		};
+
+		pmic_dump {
+			qcom,dump-size = <0x10000>;
+			qcom,dump-id = <0xe4>;
+		};
+
+		tmc_etf_dump {
+			qcom,dump-size = <0x10000>;
+			qcom,dump-id = <0xf0>;
+		};
+
+		tmc_etr_reg_dump {
+			qcom,dump-size = <0x1000>;
+			qcom,dump-id = <0x100>;
+		};
+
+		tmc_etf_reg_dump {
+			qcom,dump-size = <0x1000>;
+			qcom,dump-id = <0x101>;
+		};
+
+		misc_data_dump {
+			qcom,dump-size = <0x1000>;
+			qcom,dump-id = <0xe8>;
+		};
+
+		tpdm_swao_dump {
+			qcom,dump-size = <0x512>;
+			qcom,dump-id = <0xf2>;
+		};
+	};
+
 	qcom,msm_gsi {
 		compatible = "qcom,msm_gsi";
 	};
@@ -1014,6 +1070,46 @@
 		compatible = "qcom,msm-rtb";
 		qcom,rtb-size = <0x100000>;
 	};
+
+	cnss_pcie: qcom,cnss {
+		compatible = "qcom,cnss";
+		wlan-en-gpio = <&tlmm 52 0>;
+		vdd-wlan-supply = <&vreg_wlan>;
+		vdd-wlan-xtal-supply = <&pmxpoorwills_l6>;
+		vdd-wlan-io-supply = <&pmxpoorwills_l6>;
+		qcom,notify-modem-status;
+		pinctrl-names = "wlan_en_active", "wlan_en_sleep";
+		pinctrl-0 = <&cnss_wlan_en_active>;
+		pinctrl-1 = <&cnss_wlan_en_sleep>;
+		qcom,wlan-rc-num = <0>;
+		qcom,wlan-ramdump-dynamic = <0x200000>;
+
+		qcom,msm-bus,name = "msm-cnss";
+		qcom,msm-bus,num-cases = <4>;
+		qcom,msm-bus,num-paths = <2>;
+		qcom,msm-bus,vectors-KBps =
+				<45 512 0 0>, <1 512 0 0>,
+				/* Upto 200 Mbps */
+				<45 512 41421 655360>, <1 512 41421 655360>,
+				/* Upto 400 Mbps */
+				<45 512 98572 655360>, <1 512 98572 1600000>,
+				/* Upto 800 Mbps */
+				<45 512 207108 1146880>, <1 512 207108 3124992>;
+	};
+
+	cnss_sdio: qcom,cnss_sdio {
+		compatible = "qcom,cnss_sdio";
+		subsys-name = "AR6320_SDIO";
+		vdd-wlan-supply = <&vreg_wlan>;
+		vdd-wlan-xtal-supply = <&pmxpoorwills_l5>;
+		vdd-wlan-io-supply = <&pmxpoorwills_l6>;
+		qcom,wlan-ramdump-dynamic = <0x200000>;
+		pinctrl-names = "active", "sleep";
+		pinctrl-0 = <&cnss_sdio_active>;
+		pinctrl-1 = <&cnss_sdio_sleep>;
+		qcom,is-antenna-shared;
+		status = "disabled";
+	};
 };
 
 #include "pmxpoorwills.dtsi"
diff --git a/arch/arm/configs/msm8953-perf_defconfig b/arch/arm/configs/msm8953-perf_defconfig
index 396003d..b1d4015 100644
--- a/arch/arm/configs/msm8953-perf_defconfig
+++ b/arch/arm/configs/msm8953-perf_defconfig
@@ -458,6 +458,7 @@
 CONFIG_USB_BAM=y
 CONFIG_REMOTE_SPINLOCK_MSM=y
 CONFIG_MAILBOX=y
+CONFIG_QCOM_RUN_QUEUE_STATS=y
 CONFIG_MSM_SPM=y
 CONFIG_MSM_L2_SPM=y
 CONFIG_MSM_BOOT_STATS=y
@@ -484,6 +485,8 @@
 CONFIG_QTI_RPM_STATS_LOG=y
 CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
 CONFIG_MSM_BAM_DMUX=y
+CONFIG_QCOM_BIMC_BWMON=y
+CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
 CONFIG_QCOM_DEVFREQ_DEVBW=y
 CONFIG_PWM=y
 CONFIG_PWM_QPNP=y
diff --git a/arch/arm/configs/msm8953_defconfig b/arch/arm/configs/msm8953_defconfig
index 929187a..714ec77 100644
--- a/arch/arm/configs/msm8953_defconfig
+++ b/arch/arm/configs/msm8953_defconfig
@@ -474,6 +474,7 @@
 CONFIG_REMOTE_SPINLOCK_MSM=y
 CONFIG_MAILBOX=y
 # CONFIG_IOMMU_SUPPORT is not set
+CONFIG_QCOM_RUN_QUEUE_STATS=y
 CONFIG_MSM_SPM=y
 CONFIG_MSM_L2_SPM=y
 CONFIG_MSM_BOOT_STATS=y
@@ -503,6 +504,8 @@
 CONFIG_QTI_RPM_STATS_LOG=y
 CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
 CONFIG_MSM_BAM_DMUX=y
+CONFIG_QCOM_BIMC_BWMON=y
+CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
 CONFIG_QCOM_DEVFREQ_DEVBW=y
 CONFIG_PWM=y
 CONFIG_PWM_QPNP=y
diff --git a/arch/arm/configs/sdxpoorwills-perf_defconfig b/arch/arm/configs/sdxpoorwills-perf_defconfig
index b229209..54fc9eb 100644
--- a/arch/arm/configs/sdxpoorwills-perf_defconfig
+++ b/arch/arm/configs/sdxpoorwills-perf_defconfig
@@ -200,7 +200,12 @@
 CONFIG_USB_NET_SMSC75XX=y
 CONFIG_USB_NET_SMSC95XX=y
 CONFIG_WCNSS_MEM_PRE_ALLOC=y
+CONFIG_CNSS=y
+CONFIG_CNSS_SDIO=y
+CONFIG_CNSS_PCI=y
+CONFIG_CLD_HL_SDIO_CORE=y
 CONFIG_CLD_LL_CORE=y
+CONFIG_CNSS_LOGGER=y
 # CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_KEYBOARD is not set
@@ -341,6 +346,7 @@
 CONFIG_QCOM_SCM=y
 CONFIG_MSM_BOOT_STATS=y
 CONFIG_QCOM_WATCHDOG_V2=y
+CONFIG_QCOM_MEMORY_DUMP_V2=y
 CONFIG_QCOM_BUS_SCALING=y
 CONFIG_QCOM_BUS_CONFIG_RPMH=y
 CONFIG_MSM_SMEM=y
diff --git a/arch/arm/configs/sdxpoorwills_defconfig b/arch/arm/configs/sdxpoorwills_defconfig
index c571b2f..ac19abd 100644
--- a/arch/arm/configs/sdxpoorwills_defconfig
+++ b/arch/arm/configs/sdxpoorwills_defconfig
@@ -192,7 +192,12 @@
 CONFIG_USB_NET_SMSC75XX=y
 CONFIG_USB_NET_SMSC95XX=y
 CONFIG_WCNSS_MEM_PRE_ALLOC=y
+CONFIG_CNSS=y
+CONFIG_CNSS_SDIO=y
+CONFIG_CNSS_PCI=y
+CONFIG_CLD_HL_SDIO_CORE=y
 CONFIG_CLD_LL_CORE=y
+CONFIG_CNSS_LOGGER=y
 # CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_KEYBOARD is not set
@@ -340,6 +345,7 @@
 CONFIG_QCOM_SCM=y
 CONFIG_MSM_BOOT_STATS=y
 CONFIG_QCOM_WATCHDOG_V2=y
+CONFIG_QCOM_MEMORY_DUMP_V2=y
 CONFIG_QCOM_BUS_SCALING=y
 CONFIG_QCOM_BUS_CONFIG_RPMH=y
 CONFIG_MSM_SMEM=y
diff --git a/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi b/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi
index 28a6b74..c6bc2b9 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi
@@ -47,6 +47,23 @@
 			qcom,supply-enable-load = <100000>;
 			qcom,supply-disable-load = <100>;
 		};
+		qcom,panel-supply-entry@2 {
+			reg = <2>;
+			qcom,supply-name = "lab";
+			qcom,supply-min-voltage = <4600000>;
+			qcom,supply-max-voltage = <6000000>;
+			qcom,supply-enable-load = <100000>;
+			qcom,supply-disable-load = <100>;
+		};
+		qcom,panel-supply-entry@3 {
+			reg = <3>;
+			qcom,supply-name = "ibb";
+			qcom,supply-min-voltage = <4600000>;
+			qcom,supply-max-voltage = <6000000>;
+			qcom,supply-enable-load = <100000>;
+			qcom,supply-disable-load = <100>;
+			qcom,supply-post-on-sleep = <10>;
+		};
 	};
 };
 
diff --git a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi
index 2c3ff9b..76e39f6 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi
@@ -197,3 +197,9 @@
 		};
 	};
 };
+
+&thermal_zones {
+	case-therm-step {
+		status = "disabled";
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-thermal.dtsi b/arch/arm64/boot/dts/qcom/msm8953-thermal.dtsi
index d6d4427..54634ce 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-thermal.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-thermal.dtsi
@@ -253,6 +253,21 @@
 		};
 	};
 
+	case-therm-adc {
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm8953_vadc 0x13>;
+		thermal-governor = "user_space";
+
+		trips {
+			active-config0 {
+				temperature = <65000>;
+				hysteresis = <1000>;
+				type = "passive";
+			};
+		};
+	};
+
 	gpu1-step {
 		polling-delay-passive = <250>;
 		polling-delay = <0>;
@@ -1102,4 +1117,86 @@
 			};
 		};
 	};
+
+	case-therm-step {
+		polling-delay-passive = <2000>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm8953_vadc 0x13>;
+		thermal-governor = "step_wise";
+
+		trips {
+			cpus_trip: cpus-trip {
+				temperature = <43000>;
+				hysteresis = <0>;
+				type = "passive";
+			};
+			modem_trip0: modem-trip0 {
+				temperature = <45000>;
+				hysteresis = <2000>;
+				type = "passive";
+			};
+			modem_trip1: modem-trip1 {
+				temperature = <48000>;
+				hysteresis = <3000>;
+				type = "passive";
+			};
+			modem_trip2: modem-trip2 {
+				temperature = <54000>;
+				hysteresis = <4000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			skin_cpu0 {
+				trip = <&cpus_trip>;
+				/* throttle from fmax to 1689600KHz */
+				cooling-device = <&CPU0 THERMAL_NO_LIMIT 3>;
+			};
+			skin_cpu1 {
+				trip = <&cpus_trip>;
+				cooling-device = <&CPU1 THERMAL_NO_LIMIT 3>;
+			};
+			skin_cpu2 {
+				trip = <&cpus_trip>;
+				cooling-device = <&CPU2 THERMAL_NO_LIMIT 3>;
+			};
+			skin_cpu3 {
+				trip = <&cpus_trip>;
+				cooling-device = <&CPU3 THERMAL_NO_LIMIT 3>;
+			};
+			skin_cpu4 {
+				trip = <&cpus_trip>;
+				cooling-device = <&CPU4 THERMAL_NO_LIMIT 3>;
+			};
+			skin_cpu5 {
+				trip = <&cpus_trip>;
+				cooling-device = <&CPU5 THERMAL_NO_LIMIT 3>;
+			};
+			skin_cpu6 {
+				trip = <&cpus_trip>;
+				cooling-device = <&CPU6 THERMAL_NO_LIMIT 3>;
+			};
+			skin_cpu7 {
+				trip = <&cpus_trip>;
+				cooling-device = <&CPU7 THERMAL_NO_LIMIT 3>;
+			};
+			modem_lvl1 {
+				trip = <&modem_trip1>;
+				cooling-device = <&modem_pa 2 2>;
+			};
+			modem_lvl2 {
+				trip = <&modem_trip2>;
+				cooling-device = <&modem_pa 3 3>;
+			};
+			modem_proc_lvl1 {
+				trip = <&modem_trip0>;
+				cooling-device = <&modem_proc 1 1>;
+			};
+			modem_proc_lvl2 {
+				trip = <&modem_trip2>;
+				cooling-device = <&modem_proc 3 3>;
+			};
+		};
+	};
 };
diff --git a/arch/arm64/boot/dts/qcom/pm8953.dtsi b/arch/arm64/boot/dts/qcom/pm8953.dtsi
index feec1ae..4e041bc 100644
--- a/arch/arm64/boot/dts/qcom/pm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8953.dtsi
@@ -252,6 +252,7 @@
 				qcom,scale-function = <2>;
 				qcom,hw-settle-time = <2>;
 				qcom,fast-avg-setup = <0>;
+				qcom,vadc-thermal-node;
 			};
 		};
 
diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi
index e263058..c3ea7c4 100644
--- a/arch/arm64/boot/dts/qcom/pmi632.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi
@@ -219,10 +219,15 @@
 			compatible = "qcom,qpnp-smb5";
 			#address-cells = <1>;
 			#size-cells = <1>;
+			#cooling-cells = <2>;
 
 			qcom,pmic-revid = <&pmi632_revid>;
 			dpdm-supply = <&qusb_phy>;
 
+			qcom,thermal-mitigation
+				= <3000000 2500000 2000000 1500000
+					1000000 500000>;
+
 			qcom,chgr@1000 {
 				reg = <0x1000 0x100>;
 				interrupts =
@@ -407,6 +412,21 @@
 				reg = <0xb100 0x100>;
 			};
 		};
+
+		bcl_sensor: bcl@3d00 {
+			compatible = "qcom,msm-bcl-pmic5";
+			reg = <0x3d00 0xff>;
+			interrupts = <0x2 0x3d 0x0 IRQ_TYPE_NONE>,
+					<0x2 0x3d 0x1 IRQ_TYPE_NONE>;
+			interrupt-names = "bcl-high-ibat",
+						"bcl-low-vbat";
+			#thermal-sensor-cells = <1>;
+		};
+
+		bcl_soc: bcl-soc {
+			compatible = "qcom,msm-bcl-soc";
+			#thermal-sensor-cells = <0>;
+		};
 	};
 
 	pmi632_3: qcom,pmi632@3 {
@@ -436,16 +456,19 @@
 				label = "red";
 				pwms = <&pmi632_pwm 0 1000000>;
 				led-sources = <0>;
+				linux,default-trigger = "timer";
 			};
 			green {
 				label = "green";
 				pwms = <&pmi632_pwm 1 1000000>;
 				led-sources = <1>;
+				linux,default-trigger = "timer";
 			};
 			blue {
 				label = "blue";
 				pwms = <&pmi632_pwm 2 1000000>;
 				led-sources = <2>;
+				linux,default-trigger = "timer";
 			};
 		};
 
@@ -571,3 +594,105 @@
 		qcom,switch-source = <&pmi632_switch0>;
 	};
 };
+
+&thermal_zones {
+	ibat-high {
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		thermal-governor = "step_wise";
+		thermal-sensors = <&bcl_sensor 0>;
+
+		trips {
+			pmi632_ibat:ibat-high {
+				temperature = <3500>;
+				hysteresis = <200>;
+				type = "passive";
+			};
+		};
+	};
+
+	vbat_low {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-governor = "low_limits_cap";
+		thermal-sensors = <&bcl_sensor 2>;
+		tracks-low;
+
+		trips {
+			pmi632_vbat_low: vbat-low {
+				temperature = <3000>;
+				hysteresis = <100>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			vbat_map4 {
+				trip = <&pmi632_vbat_low>;
+				cooling-device =
+					<&CPU4 THERMAL_MAX_LIMIT
+						THERMAL_MAX_LIMIT>;
+			};
+			vbat_map5 {
+				trip = <&pmi632_vbat_low>;
+				cooling-device =
+					<&CPU5 THERMAL_MAX_LIMIT
+						THERMAL_MAX_LIMIT>;
+			};
+			vbat_map6 {
+				trip = <&pmi632_vbat_low>;
+				cooling-device =
+					<&CPU6 THERMAL_MAX_LIMIT
+						THERMAL_MAX_LIMIT>;
+			};
+			vbat_map7 {
+				trip = <&pmi632_vbat_low>;
+				cooling-device =
+					<&CPU7 THERMAL_MAX_LIMIT
+						THERMAL_MAX_LIMIT>;
+			};
+		};
+	};
+
+	soc {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-governor = "low_limits_cap";
+		thermal-sensors = <&bcl_soc>;
+		tracks-low;
+
+		trips {
+			pmi632_low_soc: low-soc {
+				temperature = <10>;
+				hysteresis = <0>;
+				type = "passive";
+			};
+		};
+		cooling-maps {
+			soc_map4 {
+				trip = <&pmi632_low_soc>;
+				cooling-device =
+					<&CPU4 THERMAL_MAX_LIMIT
+						THERMAL_MAX_LIMIT>;
+			};
+			soc_map5 {
+				trip = <&pmi632_low_soc>;
+				cooling-device =
+					<&CPU5 THERMAL_MAX_LIMIT
+						THERMAL_MAX_LIMIT>;
+			};
+			soc_map6 {
+				trip = <&pmi632_low_soc>;
+				cooling-device =
+					<&CPU6 THERMAL_MAX_LIMIT
+						THERMAL_MAX_LIMIT>;
+			};
+			soc_map7 {
+				trip = <&pmi632_low_soc>;
+				cooling-device =
+					<&CPU7 THERMAL_MAX_LIMIT
+						THERMAL_MAX_LIMIT>;
+			};
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm450-pmi632-cdp-s2.dtsi b/arch/arm64/boot/dts/qcom/sdm450-pmi632-cdp-s2.dtsi
index c47e323..d8a0e9d 100644
--- a/arch/arm64/boot/dts/qcom/sdm450-pmi632-cdp-s2.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm450-pmi632-cdp-s2.dtsi
@@ -37,25 +37,3 @@
 	qcom,mdss-dsi-bl-pmic-bank-select = <0>;
 	qcom,mdss-dsi-pwm-gpio = <&pm8953_gpios 8 0>;
 };
-
-
-&dsi_panel_pwr_supply {
-	qcom,panel-supply-entry@2 {
-		reg = <2>;
-		qcom,supply-name = "lab";
-		qcom,supply-min-voltage = <4600000>;
-		qcom,supply-max-voltage = <6000000>;
-		qcom,supply-enable-load = <100000>;
-		qcom,supply-disable-load = <100>;
-	};
-	qcom,panel-supply-entry@3 {
-		reg = <3>;
-		qcom,supply-name = "ibb";
-		qcom,supply-min-voltage = <4600000>;
-		qcom,supply-max-voltage = <6000000>;
-		qcom,supply-enable-load = <100000>;
-		qcom,supply-disable-load = <100>;
-		qcom,supply-post-on-sleep = <10>;
-	};
-};
-
diff --git a/arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dtsi b/arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dtsi
index d532434..129d507 100644
--- a/arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dtsi
@@ -38,24 +38,3 @@
 	qcom,mdss-dsi-bl-pmic-bank-select = <0>;
 	qcom,mdss-dsi-pwm-gpio = <&pm8953_gpios 8 0>;
 };
-
-&dsi_panel_pwr_supply {
-	qcom,panel-supply-entry@2 {
-		reg = <2>;
-		qcom,supply-name = "lab";
-		qcom,supply-min-voltage = <4600000>;
-		qcom,supply-max-voltage = <6000000>;
-		qcom,supply-enable-load = <100000>;
-		qcom,supply-disable-load = <100>;
-	};
-	qcom,panel-supply-entry@3 {
-		reg = <3>;
-		qcom,supply-name = "ibb";
-		qcom,supply-min-voltage = <4600000>;
-		qcom,supply-max-voltage = <6000000>;
-		qcom,supply-enable-load = <100000>;
-		qcom,supply-disable-load = <100>;
-		qcom,supply-post-on-sleep = <10>;
-	};
-};
-
diff --git a/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi b/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi
index f0f7ad7..a488df6 100644
--- a/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi
@@ -60,3 +60,49 @@
 &pm8953_pwm {
 	status = "ok";
 };
+
+&thermal_zones {
+	case-therm-step {
+		trips {
+			batt_trip1: batt-trip1 {
+				temperature = <38000>;
+				hysteresis = <3000>;
+				type = "passive";
+			};
+			batt_trip2: batt-trip2 {
+				temperature = <40000>;
+				hysteresis = <2000>;
+				type = "passive";
+			};
+			batt_trip3: batt-trip3 {
+				temperature = <43000>;
+				hysteresis = <3000>;
+				type = "passive";
+			};
+			batt_trip4: batt-trip4 {
+				temperature = <48000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			battery_lvl1 {
+				trip = <&batt_trip1>;
+				cooling-device = <&pmi632_charger 2 2>;
+			};
+			battery_lvl2 {
+				trip = <&batt_trip2>;
+				cooling-device = <&pmi632_charger 3 3>;
+			};
+			battery_lvl3 {
+				trip = <&batt_trip3>;
+				cooling-device = <&pmi632_charger 4 4>;
+			};
+			battery_lvl4 {
+				trip = <&batt_trip4>;
+				cooling-device = <&pmi632_charger 5 5>;
+			};
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm632-cpu.dtsi b/arch/arm64/boot/dts/qcom/sdm632-cpu.dtsi
index 031fd7e..4bda08bd 100644
--- a/arch/arm64/boot/dts/qcom/sdm632-cpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm632-cpu.dtsi
@@ -58,6 +58,7 @@
 			efficiency = <1024>;
 			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
 			next-level-cache = <&L2_0>;
+			#cooling-cells = <2>;
 			L2_0: l2-cache {
 			      compatible = "arm,arch-cache";
 			      cache-level = <2>;
@@ -85,6 +86,7 @@
 			efficiency = <1024>;
 			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
 			next-level-cache = <&L2_0>;
+			#cooling-cells = <2>;
 			L1_I_1: l1-icache {
 			      compatible = "arm,arch-cache";
 			      qcom,dump-size = <0x9040>;
@@ -106,6 +108,7 @@
 			efficiency = <1024>;
 			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
 			next-level-cache = <&L2_0>;
+			#cooling-cells = <2>;
 			L1_I_2: l1-icache {
 			      compatible = "arm,arch-cache";
 			      qcom,dump-size = <0x9040>;
@@ -127,6 +130,7 @@
 			efficiency = <1024>;
 			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
 			next-level-cache = <&L2_0>;
+			#cooling-cells = <2>;
 			L1_I_3: l1-icache {
 			      compatible = "arm,arch-cache";
 			      qcom,dump-size = <0x9040>;
@@ -148,6 +152,7 @@
 			efficiency = <1638>;
 			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
 			next-level-cache = <&L2_1>;
+			#cooling-cells = <2>;
 			L2_1: l2-cache {
 			      compatible = "arm,arch-cache";
 			      cache-level = <2>;
@@ -173,6 +178,7 @@
 			efficiency = <1638>;
 			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
 			next-level-cache = <&L2_1>;
+			#cooling-cells = <2>;
 			L1_I_101: l1-icache {
 			      compatible = "arm,arch-cache";
 			      qcom,dump-size = <0x12000>;
@@ -194,6 +200,7 @@
 			efficiency = <1638>;
 			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
 			next-level-cache = <&L2_1>;
+			#cooling-cells = <2>;
 			L1_I_102: l1-icache {
 			      compatible = "arm,arch-cache";
 			      qcom,dump-size = <0x12000>;
@@ -215,6 +222,7 @@
 			efficiency = <1638>;
 			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
 			next-level-cache = <&L2_1>;
+			#cooling-cells = <2>;
 			L1_I_103: l1-icache {
 			      compatible = "arm,arch-cache";
 			      qcom,dump-size = <0x12000>;
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index 3df416e..98f540d317 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -2668,6 +2668,18 @@
 			< 1 >;
 	};
 
+	bus_proxy_client: qcom,bus_proxy_client {
+		compatible = "qcom,bus-proxy-client";
+		qcom,msm-bus,name = "bus-proxy-client";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,num-paths = <2>;
+		qcom,msm-bus,vectors-KBps =
+			<22 512 0 0>, <23 512 0 0>,
+			<22 512 0 5000000>, <23 512 0 5000000>;
+		qcom,msm-bus,active-only;
+		status = "ok";
+	};
+
 	devfreq_memlat_0: qcom,cpu0-memlat-mon {
 		compatible = "qcom,arm-memlat-mon";
 		qcom,cpulist = <&CPU0 &CPU1 &CPU2 &CPU3 &CPU4 &CPU5>;
diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig
index b71ca1c..00e4a86 100644
--- a/arch/arm64/configs/msm8953-perf_defconfig
+++ b/arch/arm64/configs/msm8953-perf_defconfig
@@ -340,6 +340,8 @@
 CONFIG_QTI_VIRTUAL_SENSOR=y
 CONFIG_QTI_QMI_COOLING_DEVICE=y
 CONFIG_REGULATOR_COOLING_DEVICE=y
+CONFIG_MSM_BCL_PMIC5=y
+CONFIG_QTI_BCL_SOC_DRIVER=y
 CONFIG_MFD_SPMI_PMIC=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_CPR=y
@@ -515,6 +517,7 @@
 CONFIG_MAILBOX=y
 CONFIG_ARM_SMMU=y
 CONFIG_QCOM_LAZY_MAPPING=y
+CONFIG_QCOM_RUN_QUEUE_STATS=y
 CONFIG_MSM_SPM=y
 CONFIG_MSM_L2_SPM=y
 CONFIG_MSM_BOOT_STATS=y
@@ -547,6 +550,8 @@
 CONFIG_WCNSS_CORE=y
 CONFIG_WCNSS_CORE_PRONTO=y
 CONFIG_WCNSS_REGISTER_DUMP_ON_BITE=y
+CONFIG_QCOM_BIMC_BWMON=y
+CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
 CONFIG_QCOM_DEVFREQ_DEVBW=y
 CONFIG_SPDM_SCM=y
 CONFIG_DEVFREQ_SPDM=y
diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig
index a4b881c..1ea739c 100644
--- a/arch/arm64/configs/msm8953_defconfig
+++ b/arch/arm64/configs/msm8953_defconfig
@@ -352,6 +352,8 @@
 CONFIG_QTI_VIRTUAL_SENSOR=y
 CONFIG_QTI_QMI_COOLING_DEVICE=y
 CONFIG_REGULATOR_COOLING_DEVICE=y
+CONFIG_MSM_BCL_PMIC5=y
+CONFIG_QTI_BCL_SOC_DRIVER=y
 CONFIG_MFD_SPMI_PMIC=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_CPR=y
@@ -532,6 +534,7 @@
 CONFIG_IOMMU_DEBUG=y
 CONFIG_IOMMU_DEBUG_TRACKING=y
 CONFIG_IOMMU_TESTS=y
+CONFIG_QCOM_RUN_QUEUE_STATS=y
 CONFIG_MSM_SPM=y
 CONFIG_MSM_L2_SPM=y
 CONFIG_MSM_BOOT_STATS=y
@@ -568,6 +571,8 @@
 CONFIG_WCNSS_CORE=y
 CONFIG_WCNSS_CORE_PRONTO=y
 CONFIG_WCNSS_REGISTER_DUMP_ON_BITE=y
+CONFIG_QCOM_BIMC_BWMON=y
+CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
 CONFIG_QCOM_DEVFREQ_DEVBW=y
 CONFIG_SPDM_SCM=y
 CONFIG_DEVFREQ_SPDM=y
diff --git a/block/blk-core.c b/block/blk-core.c
index ffe0153..3bf59cd 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -582,8 +582,6 @@
 		q->queue_lock = &q->__queue_lock;
 	spin_unlock_irq(lock);
 
-	bdi_unregister(q->backing_dev_info);
-
 	/* @q is and will stay empty, shutdown and put */
 	blk_put_queue(q);
 }
diff --git a/block/genhd.c b/block/genhd.c
index e299597..6ad0fd0 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -660,7 +660,16 @@
 	disk->flags &= ~GENHD_FL_UP;
 
 	sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
-	blk_unregister_queue(disk);
+	if (disk->queue) {
+		/*
+		 * Unregister bdi before releasing device numbers (as they can
+		 * get reused and we'd get clashes in sysfs).
+		 */
+		bdi_unregister(disk->queue->backing_dev_info);
+		blk_unregister_queue(disk);
+	} else {
+		WARN_ON(1);
+	}
 	blk_unregister_region(disk_devt(disk), disk->minors);
 
 	part_stat_set_all(&disk->part0, 0);
@@ -1360,7 +1369,7 @@
 	owner = disk->fops->owner;
 	if (owner && !try_module_get(owner))
 		return NULL;
-	kobj = kobject_get(&disk_to_dev(disk)->kobj);
+	kobj = kobject_get_unless_zero(&disk_to_dev(disk)->kobj);
 	if (kobj == NULL) {
 		module_put(owner);
 		return NULL;
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 0651010..0335e23 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -165,6 +165,11 @@
 
 	  If you are unsure about this, say N here.
 
+config FW_CACHE
+       bool "Enable firmware caching during suspend"
+       depends on PM_SLEEP
+       default n
+
 config WANT_DEV_COREDUMP
 	bool
 	help
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 914433f..813a191 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -994,7 +994,7 @@
 	return _request_firmware_load(fw_priv, opt_flags, timeout);
 }
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_FW_CACHE
 /* kill pending requests without uevent to avoid blocking suspend */
 static void kill_requests_without_uevent(void)
 {
@@ -1395,7 +1395,7 @@
 }
 EXPORT_SYMBOL(request_firmware_nowait);
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_FW_CACHE
 static ASYNC_DOMAIN_EXCLUSIVE(fw_cache_domain);
 
 /**
@@ -1741,7 +1741,7 @@
 	INIT_LIST_HEAD(&fw_cache.head);
 	fw_cache.state = FW_LOADER_NO_CACHE;
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_FW_CACHE
 	spin_lock_init(&fw_cache.name_lock);
 	INIT_LIST_HEAD(&fw_cache.fw_names);
 
@@ -1768,7 +1768,7 @@
 
 static void __exit firmware_class_exit(void)
 {
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_FW_CACHE
 	unregister_syscore_ops(&fw_syscore_ops);
 	unregister_pm_notifier(&fw_cache.pm_notify);
 #endif
diff --git a/drivers/clk/msm/clock-alpha-pll.c b/drivers/clk/msm/clock-alpha-pll.c
index dbe8d8e..37e34d5 100644
--- a/drivers/clk/msm/clock-alpha-pll.c
+++ b/drivers/clk/msm/clock-alpha-pll.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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
@@ -774,6 +774,13 @@
 		writel_relaxed(regval, USER_CTL_HI_REG(pll));
 	}
 
+	if (masks->cal_l_val_mask && pll->cal_l_val) {
+		regval = readl_relaxed(USER_CTL_HI_REG(pll));
+		regval &= ~masks->cal_l_val_mask;
+		regval |= pll->cal_l_val;
+		writel_relaxed(regval, USER_CTL_HI_REG(pll));
+	}
+
 	if (masks->test_ctl_lo_mask) {
 		regval = readl_relaxed(TEST_CTL_LO_REG(pll));
 		regval &= ~masks->test_ctl_lo_mask;
diff --git a/drivers/cpuidle/lpm-levels.c b/drivers/cpuidle/lpm-levels.c
index c62b970..786ba01 100644
--- a/drivers/cpuidle/lpm-levels.c
+++ b/drivers/cpuidle/lpm-levels.c
@@ -1371,11 +1371,6 @@
 	const struct cpumask *cpumask = get_cpu_mask(dev->cpu);
 	ktime_t start = ktime_get();
 	uint64_t start_time = ktime_to_ns(start), end_time;
-	struct power_params *pwr_params;
-
-	pwr_params = &cpu->levels[idx].pwr;
-	sched_set_cpu_cstate(dev->cpu, idx + 1,
-			pwr_params->energy_overhead, pwr_params->latency_us);
 
 	cpu_prepare(cpu, idx, true);
 	cluster_prepare(cpu->parent, cpumask, idx, true, start_time);
@@ -1394,7 +1389,6 @@
 
 	cluster_unprepare(cpu->parent, cpumask, idx, true, end_time);
 	cpu_unprepare(cpu, idx, true);
-	sched_set_cpu_cstate(smp_processor_id(), 0, 0, 0);
 	dev->last_residency = ktime_us_delta(ktime_get(), start);
 	update_history(dev, idx);
 	trace_cpu_idle_exit(idx, success);
diff --git a/drivers/devfreq/governor_bw_hwmon.c b/drivers/devfreq/governor_bw_hwmon.c
index 3026bc2..cb04014 100644
--- a/drivers/devfreq/governor_bw_hwmon.c
+++ b/drivers/devfreq/governor_bw_hwmon.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-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
@@ -171,7 +171,7 @@
 #define MAX_MS	500U
 
 /* Returns MBps of read/writes for the sampling window. */
-static unsigned int bytes_to_mbps(long long bytes, unsigned int us)
+static unsigned long bytes_to_mbps(unsigned long long bytes, unsigned int us)
 {
 	bytes *= USEC_PER_SEC;
 	do_div(bytes, us);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 731a554..bf903b9 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -816,7 +816,7 @@
 	struct dp_display_private *dp = container_of(dw,
 			struct dp_display_private, connect_work);
 
-	if (dp->dp_display.is_connected) {
+	if (dp->dp_display.is_connected && dp_display_framework_ready(dp)) {
 		pr_debug("HPD already on\n");
 		return;
 	}
@@ -1085,6 +1085,11 @@
 
 	dp->aux->init(dp->aux, dp->parser->aux_cfg);
 
+	if (dp->debug->psm_enabled) {
+		dp->link->psm_config(dp->link, &dp->panel->link_info, false);
+		dp->debug->psm_enabled = false;
+	}
+
 	rc = dp->ctrl->on(dp->ctrl);
 
 	if (dp->debug->tpg_state)
@@ -1227,10 +1232,9 @@
 	 * any notification from driver. Initialize post_open callback to notify
 	 * DP connection once framework restarts.
 	 */
-	if (dp->usbpd->hpd_high && dp->usbpd->alt_mode_cfg_done) {
+	if (dp->usbpd->hpd_high && dp->usbpd->alt_mode_cfg_done)
 		dp_display->post_open = dp_display_post_open;
-		dp->dp_display.is_connected = false;
-	}
+
 	dp->power_on = false;
 	dp->aux->state = DP_STATE_CTRL_POWERED_OFF;
 end:
diff --git a/drivers/gpu/drm/msm/sde/sde_color_processing.c b/drivers/gpu/drm/msm/sde/sde_color_processing.c
index 22d2093..782cd13 100644
--- a/drivers/gpu/drm/msm/sde/sde_color_processing.c
+++ b/drivers/gpu/drm/msm/sde/sde_color_processing.c
@@ -25,6 +25,7 @@
 #include "sde_hw_interrupts.h"
 #include "sde_core_irq.h"
 #include "dsi_panel.h"
+#include "sde_hw_color_processing.h"
 
 struct sde_cp_node {
 	u32 property_id;
@@ -148,6 +149,24 @@
 	SDE_CP_CRTC_MAX_FEATURES,
 };
 
+#define HIGH_BUS_VOTE_NEEDED(feature) ((feature == SDE_CP_CRTC_DSPP_IGC) |\
+				 (feature == SDE_CP_CRTC_DSPP_GC) |\
+				 (feature == SDE_CP_CRTC_DSPP_SIXZONE) |\
+				 (feature == SDE_CP_CRTC_DSPP_GAMUT))
+
+static u32 crtc_feature_map[SDE_CP_CRTC_MAX_FEATURES] = {
+	[SDE_CP_CRTC_DSPP_IGC] = SDE_DSPP_IGC,
+	[SDE_CP_CRTC_DSPP_PCC] = SDE_DSPP_PCC,
+	[SDE_CP_CRTC_DSPP_GC] = SDE_DSPP_GC,
+	[SDE_CP_CRTC_DSPP_MEMCOL_SKIN] = SDE_DSPP_MEMCOLOR,
+	[SDE_CP_CRTC_DSPP_MEMCOL_SKY] = SDE_DSPP_MEMCOLOR,
+	[SDE_CP_CRTC_DSPP_MEMCOL_FOLIAGE] = SDE_DSPP_MEMCOLOR,
+	[SDE_CP_CRTC_DSPP_SIXZONE] = SDE_DSPP_SIXZONE,
+	[SDE_CP_CRTC_DSPP_GAMUT] = SDE_DSPP_GAMUT,
+	[SDE_CP_CRTC_DSPP_DITHER] = SDE_DSPP_DITHER,
+	[SDE_CP_CRTC_DSPP_VLUT] = SDE_DSPP_VLUT,
+};
+
 #define INIT_PROP_ATTACH(p, crtc, prop, node, feature, val) \
 	do { \
 		(p)->crtc = crtc; \
@@ -859,6 +878,10 @@
 	struct sde_hw_ctl *ctl;
 	uint32_t flush_mask = 0;
 	u32 num_mixers = 0, i = 0;
+	u32 sde_dspp_feature = SDE_DSPP_MAX;
+	struct msm_drm_private *priv = NULL;
+	struct sde_kms *sde_kms = NULL;
+	bool mdss_bus_vote = false;
 
 	if (!crtc || !crtc->dev) {
 		DRM_ERROR("invalid crtc %pK dev %pK\n", crtc,
@@ -878,6 +901,17 @@
 		return;
 	}
 
+	priv = crtc->dev->dev_private;
+	if (!priv || !priv->kms) {
+		SDE_ERROR("invalid kms\n");
+		return;
+	}
+	sde_kms = to_sde_kms(priv->kms);
+	if (!sde_kms) {
+		SDE_ERROR("invalid sde kms\n");
+		return;
+	}
+
 	mutex_lock(&sde_crtc->crtc_cp_lock);
 
 	/* Check if dirty lists are empty and ad features are disabled for
@@ -896,6 +930,16 @@
 
 	list_for_each_entry_safe(prop_node, n, &sde_crtc->dirty_list,
 				dirty_list) {
+		sde_dspp_feature = crtc_feature_map[prop_node->feature];
+		if (!mdss_bus_vote && HIGH_BUS_VOTE_NEEDED(prop_node->feature)
+			&& !reg_dmav1_dspp_feature_support(sde_dspp_feature)) {
+			sde_power_scale_reg_bus(&priv->phandle,
+				sde_kms->core_client,
+				VOTE_INDEX_HIGH, false);
+			pr_debug("Vote HIGH for data bus: feature %d\n",
+					prop_node->feature);
+			mdss_bus_vote = true;
+		}
 		sde_cp_crtc_setfeature(prop_node, sde_crtc);
 		/* Set the flush flag to true */
 		if (prop_node->is_dspp_feature)
@@ -903,6 +947,12 @@
 		else
 			set_lm_flush = true;
 	}
+	if (mdss_bus_vote) {
+		sde_power_scale_reg_bus(&priv->phandle, sde_kms->core_client,
+			VOTE_INDEX_LOW, false);
+		pr_debug("Vote LOW for data bus\n");
+		mdss_bus_vote = false;
+	}
 
 	list_for_each_entry_safe(prop_node, n, &sde_crtc->ad_dirty,
 				dirty_list) {
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c b/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c
index 0dc3fed..05ac893 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c
@@ -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
@@ -248,6 +248,32 @@
 	return rc;
 }
 
+bool reg_dmav1_dspp_feature_support(int feature)
+{
+	struct sde_hw_reg_dma_ops *dma_ops;
+	bool is_supported = false;
+
+	if (feature >= SDE_DSPP_MAX) {
+		DRM_ERROR("invalid feature %x max %x\n",
+			feature, SDE_DSPP_MAX);
+		return is_supported;
+	}
+
+	if (feature_map[feature] >= REG_DMA_FEATURES_MAX) {
+		DRM_ERROR("invalid feature map %d for feature %d\n",
+			feature_map[feature], feature);
+		return is_supported;
+	}
+
+	dma_ops = sde_reg_dma_get_ops();
+	if (IS_ERR_OR_NULL(dma_ops))
+		return is_supported;
+
+	dma_ops->check_support(feature_map[feature], DSPP0, &is_supported);
+
+	return is_supported;
+}
+
 int reg_dmav1_init_dspp_op_v4(int feature, enum sde_dspp idx)
 {
 	int rc = -ENOTSUPP;
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.h b/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.h
index a8115d6..5cd212a 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.h
@@ -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
@@ -25,6 +25,13 @@
 int reg_dmav1_init_dspp_op_v4(int feature, enum sde_dspp idx);
 
 /**
+ * reg_dmav1_dspp_feature_support() - check if dspp feature using REG_DMA
+ *                                    or not.
+ * @feature: dspp feature
+ */
+bool reg_dmav1_dspp_feature_support(int feature);
+
+/**
  * reg_dma_init_sspp_op_v4() - initialize the sspp feature op for sde v4
  * @feature: sspp feature
  * @idx: sspp idx
diff --git a/drivers/gpu/drm/msm/sde_power_handle.c b/drivers/gpu/drm/msm/sde_power_handle.c
index 40542ab..037c036 100644
--- a/drivers/gpu/drm/msm/sde_power_handle.c
+++ b/drivers/gpu/drm/msm/sde_power_handle.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-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
@@ -844,6 +844,68 @@
 		sde_rsc_client_destroy(phandle->rsc_client);
 }
 
+
+int sde_power_scale_reg_bus(struct sde_power_handle *phandle,
+	struct sde_power_client *pclient, u32 usecase_ndx, bool skip_lock)
+{
+	struct sde_power_client *client;
+	int rc = 0;
+	u32 max_usecase_ndx = VOTE_INDEX_DISABLE;
+
+	if (!skip_lock) {
+		mutex_lock(&phandle->phandle_lock);
+
+		if (WARN_ON(pclient->refcount == 0)) {
+			/*
+			 * This is not expected, clients calling without skip
+			 * lock are outside the power resource enable, which
+			 * means that they should have enabled the power
+			 * resource before trying to scale.
+			 */
+			rc = -EINVAL;
+			goto exit;
+		}
+	}
+
+	pr_debug("%pS: current idx:%d requested:%d client:%d\n",
+		__builtin_return_address(0), pclient->usecase_ndx,
+		usecase_ndx, pclient->id);
+
+	pclient->usecase_ndx = usecase_ndx;
+
+	list_for_each_entry(client, &phandle->power_client_clist, list) {
+		if (client->usecase_ndx < VOTE_INDEX_MAX &&
+		    client->usecase_ndx > max_usecase_ndx)
+			max_usecase_ndx = client->usecase_ndx;
+	}
+
+	rc = sde_power_reg_bus_update(phandle->reg_bus_hdl,
+						max_usecase_ndx);
+	if (rc)
+		pr_err("failed to set reg bus vote rc=%d\n", rc);
+
+exit:
+	if (!skip_lock)
+		mutex_unlock(&phandle->phandle_lock);
+
+	return rc;
+}
+
+static inline bool _resource_changed(u32 current_usecase_ndx,
+		u32 max_usecase_ndx)
+{
+	WARN_ON((current_usecase_ndx >= VOTE_INDEX_MAX)
+		|| (max_usecase_ndx >= VOTE_INDEX_MAX));
+
+	if (((current_usecase_ndx >= VOTE_INDEX_LOW) && /*current enabled */
+		(max_usecase_ndx == VOTE_INDEX_DISABLE)) || /* max disabled */
+		((current_usecase_ndx == VOTE_INDEX_DISABLE) && /* disabled */
+		(max_usecase_ndx >= VOTE_INDEX_LOW))) /* max enabled */
+		return true;
+
+	return false;
+}
+
 int sde_power_resource_enable(struct sde_power_handle *phandle,
 	struct sde_power_client *pclient, bool enable)
 {
@@ -877,7 +939,15 @@
 			max_usecase_ndx = client->usecase_ndx;
 	}
 
-	if (phandle->current_usecase_ndx != max_usecase_ndx) {
+	/*
+	 * Check if we need to enable/disable the power resource, we won't
+	 * only-scale up/down the AHB vote in this API; if a client wants to
+	 * bump up the AHB clock above the LOW (default) level, it needs to
+	 * call 'sde_power_scale_reg_bus' with the desired vote after the power
+	 * resource was enabled.
+	 */
+	if (_resource_changed(phandle->current_usecase_ndx,
+			max_usecase_ndx)) {
 		changed = true;
 		prev_usecase_ndx = phandle->current_usecase_ndx;
 		phandle->current_usecase_ndx = max_usecase_ndx;
@@ -920,8 +990,8 @@
 			}
 		}
 
-		rc = sde_power_reg_bus_update(phandle->reg_bus_hdl,
-							max_usecase_ndx);
+		rc = sde_power_scale_reg_bus(phandle, pclient,
+				max_usecase_ndx, true);
 		if (rc) {
 			pr_err("failed to set reg bus vote rc=%d\n", rc);
 			goto reg_bus_hdl_err;
@@ -952,8 +1022,8 @@
 
 		sde_power_rsc_update(phandle, false);
 
-		sde_power_reg_bus_update(phandle->reg_bus_hdl,
-							max_usecase_ndx);
+		sde_power_scale_reg_bus(phandle, pclient,
+				max_usecase_ndx, true);
 
 		if (!phandle->rsc_client)
 			msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg,
@@ -975,7 +1045,7 @@
 clk_err:
 	sde_power_rsc_update(phandle, false);
 rsc_err:
-	sde_power_reg_bus_update(phandle->reg_bus_hdl, prev_usecase_ndx);
+	sde_power_scale_reg_bus(phandle, pclient, max_usecase_ndx, true);
 reg_bus_hdl_err:
 	if (!phandle->rsc_client)
 		msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, 0);
diff --git a/drivers/gpu/drm/msm/sde_power_handle.h b/drivers/gpu/drm/msm/sde_power_handle.h
index fb7322e..f02ca0a 100644
--- a/drivers/gpu/drm/msm/sde_power_handle.h
+++ b/drivers/gpu/drm/msm/sde_power_handle.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-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
@@ -43,11 +43,15 @@
  * mdss_bus_vote_type: register bus vote type
  * VOTE_INDEX_DISABLE: removes the client vote
  * VOTE_INDEX_LOW: keeps the lowest vote for register bus
+ * VOTE_INDEX_MEDIUM: keeps medium vote for register bus
+ * VOTE_INDEX_HIGH: keeps the highest vote for register bus
  * VOTE_INDEX_MAX: invalid
  */
 enum mdss_bus_vote_type {
 	VOTE_INDEX_DISABLE,
 	VOTE_INDEX_LOW,
+	VOTE_INDEX_MEDIUM,
+	VOTE_INDEX_HIGH,
 	VOTE_INDEX_MAX,
 };
 
@@ -228,6 +232,19 @@
 	struct sde_power_client *pclient, bool enable);
 
 /**
+ * sde_power_scale_reg_bus() - Scale the registers bus for the specified client
+ * @pdata:  power handle containing the resources
+ * @client: client information to scale its vote
+ * @usecase_ndx: new use case to scale the reg bus
+ * @skip_lock: will skip holding the power rsrc mutex during the call, this is
+ *		for internal callers that already hold this required lock.
+ *
+ * Return: error code.
+ */
+int sde_power_scale_reg_bus(struct sde_power_handle *phandle,
+	struct sde_power_client *pclient, u32 usecase_ndx, bool skip_lock);
+
+/**
  * sde_power_resource_is_enabled() - return true if power resource is enabled
  * @pdata:  power handle containing the resources
  *
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 431123b..dac7a71 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -44,7 +44,8 @@
 		goto unlock;
 	}
 
-	if (sysfs_streq(buf, "none")) {
+	if (sysfs_streq(buf, "none") &&
+			!(led_cdev->flags & LED_KEEP_TRIGGER)) {
 		led_trigger_remove(led_cdev);
 		goto unlock;
 	}
diff --git a/drivers/leds/leds-qti-tri-led.c b/drivers/leds/leds-qti-tri-led.c
index ab5e876..ea8ef9d 100644
--- a/drivers/leds/leds-qti-tri-led.c
+++ b/drivers/leds/leds-qti-tri-led.c
@@ -41,8 +41,6 @@
 #define TRILED_NUM_MAX			3
 
 #define PWM_PERIOD_DEFAULT_NS		1000000
-#define LED_BLINK_ON_MS			125
-#define LED_BLINK_OFF_MS		875
 
 struct pwm_setting {
 	u32	pre_period_ns;
@@ -309,8 +307,7 @@
 		led->cdev.blink_set = qpnp_tri_led_set_blink;
 		led->cdev.default_trigger = led->default_trigger;
 		led->cdev.brightness = LED_OFF;
-		led->cdev.blink_delay_on = LED_BLINK_ON_MS;
-		led->cdev.blink_delay_off = LED_BLINK_OFF_MS;
+		led->cdev.flags |= LED_KEEP_TRIGGER;
 
 		rc = devm_led_classdev_register(chip->dev, &led->cdev);
 		if (rc < 0) {
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index fab2623f..58bd744 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -4115,12 +4115,7 @@
 		return;
 	}
 
-	if (vfe_dev->vt_enable) {
-		msm_isp_get_avtimer_ts(ts);
-		time_stamp = &ts->vt_time;
-	} else {
-		time_stamp = &ts->buf_time;
-	}
+	time_stamp = &ts->buf_time;
 
 	frame_id = vfe_dev->axi_data.
 		src_info[SRC_TO_INTF(stream_info->stream_src)].frame_id;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index 9959f70..643de59 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -207,15 +207,11 @@
 	struct timespec ts;
 
 	do_gettimeofday(&(time_stamp->event_time));
-	if (vfe_dev->vt_enable) {
-		msm_isp_get_avtimer_ts(time_stamp);
-		time_stamp->buf_time.tv_sec    = time_stamp->vt_time.tv_sec;
-		time_stamp->buf_time.tv_usec   = time_stamp->vt_time.tv_usec;
-	} else {
-		get_monotonic_boottime(&ts);
-		time_stamp->buf_time.tv_sec    = ts.tv_sec;
-		time_stamp->buf_time.tv_usec   = ts.tv_nsec/1000;
-	}
+
+	get_monotonic_boottime(&ts);
+	time_stamp->buf_time.tv_sec    = ts.tv_sec;
+	time_stamp->buf_time.tv_usec   = ts.tv_nsec/1000;
+
 }
 
 static inline u32 msm_isp_evt_mask_to_isp_event(u32 evt_mask)
diff --git a/drivers/platform/msm/ipa/ipa_clients/ecm_ipa.c b/drivers/platform/msm/ipa/ipa_clients/ecm_ipa.c
index eadd58b..9f8bfbe 100644
--- a/drivers/platform/msm/ipa/ipa_clients/ecm_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_clients/ecm_ipa.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-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
@@ -619,8 +619,10 @@
 	}
 
 	if (ecm_ipa_ctx->is_vlan_mode)
-		if (unlikely(skb->protocol != ETH_P_8021Q))
-			ECM_IPA_DEBUG("ether_type != ETH_P_8021Q && vlan\n");
+		if (unlikely(skb->protocol != htons(ETH_P_8021Q)))
+			ECM_IPA_DEBUG(
+				"ether_type != ETH_P_8021Q && vlan, prot = 0x%X\n"
+				, skb->protocol);
 
 	ret = ipa_tx_dp(ecm_ipa_ctx->ipa_to_usb_client, skb, NULL);
 	if (ret) {
diff --git a/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c b/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c
index ad23d82..4980167 100644
--- a/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c
@@ -2026,8 +2026,10 @@
 	}
 
 	if (rndis_ipa_ctx->is_vlan_mode)
-		if (unlikely(skb->protocol != ETH_P_8021Q))
-			RNDIS_IPA_DEBUG("ether_type != ETH_P_8021Q && vlan\n");
+		if (unlikely(skb->protocol != htons(ETH_P_8021Q)))
+			RNDIS_IPA_DEBUG(
+				"ether_type != ETH_P_8021Q && vlan, prot = 0x%X\n"
+				, skb->protocol);
 
 	/* make room at the head of the SKB to put the RNDIS header */
 	rndis_hdr = (struct rndis_pkt_hdr *)skb_push(skb,
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index 496a276..90745fd 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -4805,7 +4805,7 @@
 
 	if (++chg->vconn_attempts > VCONN_MAX_ATTEMPTS) {
 		smblib_err(chg, "VCONN failed to enable after %d attempts\n",
-			   chg->otg_attempts - 1);
+			   chg->vconn_attempts - 1);
 		chg->vconn_en = false;
 		chg->vconn_attempts = 0;
 		goto unlock;
@@ -4829,14 +4829,7 @@
 		chg->vconn_attempts = 0;
 		goto unlock;
 	}
-
 	smblib_dbg(chg, PR_OTG, "VCONN OC fell after %dms\n", 2 * i + 1);
-	if (++chg->vconn_attempts > VCONN_MAX_ATTEMPTS) {
-		smblib_err(chg, "VCONN failed to enable after %d attempts\n",
-			   chg->vconn_attempts - 1);
-		chg->vconn_en = false;
-		goto unlock;
-	}
 
 	rc = _smblib_vconn_regulator_enable(chg->vconn_vreg->rdev);
 	if (rc < 0) {
diff --git a/drivers/pwm/pwm-qti-lpg.c b/drivers/pwm/pwm-qti-lpg.c
index 328f4b6..85a5ea0 100644
--- a/drivers/pwm/pwm-qti-lpg.c
+++ b/drivers/pwm/pwm-qti-lpg.c
@@ -28,6 +28,7 @@
 
 #define REG_SIZE_PER_LPG	0x100
 
+#define REG_LPG_PERPH_SUBTYPE		0x05
 #define REG_LPG_PWM_SIZE_CLK		0x41
 #define REG_LPG_PWM_FREQ_PREDIV_CLK	0x42
 #define REG_LPG_PWM_TYPE_CONFIG		0x43
@@ -36,9 +37,15 @@
 #define REG_LPG_ENABLE_CONTROL		0x46
 #define REG_LPG_PWM_SYNC		0x47
 
+/* REG_LPG_PERPH_SUBTYPE */
+#define SUBTYPE_PWM			0x0b
+#define SUBTYPE_LPG_LITE		0x11
+
 /* REG_LPG_PWM_SIZE_CLK */
-#define LPG_PWM_SIZE_MASK		BIT(4)
-#define LPG_PWM_SIZE_SHIFT		4
+#define LPG_PWM_SIZE_MASK_LPG		BIT(4)
+#define LPG_PWM_SIZE_MASK_PWM		BIT(2)
+#define LPG_PWM_SIZE_SHIFT_LPG		4
+#define LPG_PWM_SIZE_SHIFT_PWM		2
 #define LPG_PWM_CLK_FREQ_SEL_MASK	GENMASK(1, 0)
 
 /* REG_LPG_PWM_FREQ_PREDIV_CLK */
@@ -95,6 +102,7 @@
 	u32				lpg_idx;
 	u32				reg_base;
 	u8				src_sel;
+	u8				subtype;
 	int				current_period_ns;
 	int				current_duty_ns;
 };
@@ -108,6 +116,23 @@
 	u32			num_lpgs;
 };
 
+static int qpnp_lpg_read(struct qpnp_lpg_channel *lpg, u16 addr, u8 *val)
+{
+	int rc;
+	unsigned int tmp;
+
+	mutex_lock(&lpg->chip->bus_lock);
+	rc = regmap_read(lpg->chip->regmap, lpg->reg_base + addr, &tmp);
+	if (rc < 0)
+		dev_err(lpg->chip->dev, "Read addr 0x%x failed, rc=%d\n",
+				lpg->reg_base + addr, rc);
+	else
+		*val = (u8)tmp;
+	mutex_unlock(&lpg->chip->bus_lock);
+
+	return rc;
+}
+
 static int qpnp_lpg_write(struct qpnp_lpg_channel *lpg, u16 addr, u8 val)
 {
 	int rc;
@@ -166,10 +191,24 @@
 	return -EINVAL;
 }
 
+static int qpnp_lpg_set_glitch_removal(struct qpnp_lpg_channel *lpg, bool en)
+{
+	int rc;
+	u8 mask, val;
+
+	val = en ? LPG_PWM_EN_GLITCH_REMOVAL_MASK : 0;
+	mask = LPG_PWM_EN_GLITCH_REMOVAL_MASK;
+	rc = qpnp_lpg_masked_write(lpg, REG_LPG_PWM_TYPE_CONFIG, mask, val);
+	if (rc < 0)
+		dev_err(lpg->chip->dev, "Write LPG_PWM_TYPE_CONFIG failed, rc=%d\n",
+							rc);
+	return rc;
+}
+
 static int qpnp_lpg_set_pwm_config(struct qpnp_lpg_channel *lpg)
 {
 	int rc;
-	u8 val, mask;
+	u8 val, mask, shift;
 	int pwm_size_idx, pwm_clk_idx, prediv_idx, clk_exp_idx;
 
 	pwm_size_idx = __find_index_in_array(lpg->pwm_config.pwm_size,
@@ -187,8 +226,16 @@
 
 	/* pwm_clk_idx is 1 bit lower than the register value */
 	pwm_clk_idx += 1;
-	val = pwm_size_idx << LPG_PWM_SIZE_SHIFT | pwm_clk_idx;
-	mask = LPG_PWM_SIZE_MASK | LPG_PWM_CLK_FREQ_SEL_MASK;
+	if (lpg->subtype == SUBTYPE_PWM) {
+		shift = LPG_PWM_SIZE_SHIFT_PWM;
+		mask = LPG_PWM_SIZE_MASK_PWM;
+	} else {
+		shift = LPG_PWM_SIZE_SHIFT_LPG;
+		mask = LPG_PWM_SIZE_MASK_LPG;
+	}
+
+	val = pwm_size_idx << shift | pwm_clk_idx;
+	mask |= LPG_PWM_CLK_FREQ_SEL_MASK;
 	rc = qpnp_lpg_masked_write(lpg, REG_LPG_PWM_SIZE_CLK, mask, val);
 	if (rc < 0) {
 		dev_err(lpg->chip->dev, "Write LPG_PWM_SIZE_CLK failed, rc=%d\n",
@@ -377,6 +424,13 @@
 		return -ENODEV;
 	}
 
+	rc = qpnp_lpg_set_glitch_removal(lpg, true);
+	if (rc < 0) {
+		dev_err(lpg->chip->dev, "Enable glitch-removal failed, rc=%d\n",
+							rc);
+		return rc;
+	}
+
 	mask = LPG_PWM_SRC_SELECT_MASK | LPG_EN_LPG_OUT_BIT;
 	val = lpg->src_sel << LPG_PWM_SRC_SELECT_SHIFT | LPG_EN_LPG_OUT_BIT;
 
@@ -405,9 +459,16 @@
 	val = lpg->src_sel << LPG_PWM_SRC_SELECT_SHIFT;
 
 	rc = qpnp_lpg_masked_write(lpg, REG_LPG_ENABLE_CONTROL, mask, val);
-	if (rc < 0)
+	if (rc < 0) {
 		dev_err(pwm_chip->dev, "Disable PWM output failed for channel %d, rc=%d\n",
 						lpg->lpg_idx, rc);
+		return;
+	}
+
+	rc = qpnp_lpg_set_glitch_removal(lpg, false);
+	if (rc < 0)
+		dev_err(lpg->chip->dev, "Disable glitch-removal failed, rc=%d\n",
+							rc);
 }
 
 #ifdef CONFIG_DEBUG_FS
@@ -490,6 +551,12 @@
 		chip->lpgs[i].lpg_idx = i;
 		chip->lpgs[i].reg_base = base + i * REG_SIZE_PER_LPG;
 		chip->lpgs[i].src_sel = PWM_OUTPUT;
+		rc = qpnp_lpg_read(&chip->lpgs[i], REG_LPG_PERPH_SUBTYPE,
+				&chip->lpgs[i].subtype);
+		if (rc < 0) {
+			dev_err(chip->dev, "Read subtype failed, rc=%d\n", rc);
+			return rc;
+		}
 	}
 
 	return rc;
@@ -511,16 +578,15 @@
 		return -EINVAL;
 	}
 
+	mutex_init(&chip->bus_lock);
 	rc = qpnp_lpg_parse_dt(chip);
 	if (rc < 0) {
 		dev_err(chip->dev, "Devicetree properties parsing failed, rc=%d\n",
 				rc);
-		return rc;
+		goto destroy;
 	}
 
 	dev_set_drvdata(chip->dev, chip);
-
-	mutex_init(&chip->bus_lock);
 	chip->pwm_chip.dev = chip->dev;
 	chip->pwm_chip.base = -1;
 	chip->pwm_chip.npwm = chip->num_lpgs;
@@ -529,9 +595,12 @@
 	rc = pwmchip_add(&chip->pwm_chip);
 	if (rc < 0) {
 		dev_err(chip->dev, "Add pwmchip failed, rc=%d\n", rc);
-		mutex_destroy(&chip->bus_lock);
+		goto destroy;
 	}
 
+	return 0;
+destroy:
+	mutex_destroy(&chip->bus_lock);
 	return rc;
 }
 
diff --git a/drivers/soc/qcom/msm_bus/Makefile b/drivers/soc/qcom/msm_bus/Makefile
index 15569b1..c2ef70c 100644
--- a/drivers/soc/qcom/msm_bus/Makefile
+++ b/drivers/soc/qcom/msm_bus/Makefile
@@ -7,7 +7,7 @@
 
 ifdef CONFIG_QCOM_BUS_CONFIG_RPMH
 	obj-y += msm_bus_fabric_rpmh.o msm_bus_arb_rpmh.o msm_bus_rules.o \
-		msm_bus_bimc_rpmh.o msm_bus_noc_rpmh.o
+		msm_bus_bimc_rpmh.o msm_bus_noc_rpmh.o msm_bus_proxy_client.o
 	obj-$(CONFIG_OF) += msm_bus_of_rpmh.o
 else
 	obj-y += msm_bus_fabric_adhoc.o msm_bus_arb_adhoc.o msm_bus_rules.o \
diff --git a/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c b/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c
index 437984c..8af9b5a 100644
--- a/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c
+++ b/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-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
@@ -1133,7 +1133,7 @@
 	}
 
 	curr = client->curr;
-	if (curr >= pdata->num_usecases) {
+	if (curr >= pdata->num_usecases || curr < 0) {
 		MSM_BUS_ERR("Invalid index Defaulting curr to 0");
 		curr = 0;
 	}
diff --git a/drivers/soc/qcom/msm_bus/msm_bus_proxy_client.c b/drivers/soc/qcom/msm_bus/msm_bus_proxy_client.c
new file mode 100644
index 0000000..cdf61f6
--- /dev/null
+++ b/drivers/soc/qcom/msm_bus/msm_bus_proxy_client.c
@@ -0,0 +1,93 @@
+/* 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/msm-bus.h>
+
+struct proxy_client {
+	struct msm_bus_scale_pdata *pdata;
+	unsigned int client_handle;
+};
+
+static struct proxy_client proxy_client_info;
+
+static int msm_bus_device_proxy_client_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	proxy_client_info.pdata = msm_bus_cl_get_pdata(pdev);
+
+	if (!proxy_client_info.pdata)
+		return 0;
+
+	proxy_client_info.client_handle =
+		msm_bus_scale_register_client(proxy_client_info.pdata);
+
+	if (!proxy_client_info.client_handle) {
+		dev_err(&pdev->dev, "Unable to register bus client\n");
+		return -ENODEV;
+	}
+
+	ret = msm_bus_scale_client_update_request(
+					proxy_client_info.client_handle, 1);
+	if (ret)
+		dev_err(&pdev->dev, "Bandwidth update failed (%d)\n", ret);
+
+	return ret;
+}
+
+static const struct of_device_id proxy_client_match[] = {
+	{.compatible = "qcom,bus-proxy-client"},
+	{}
+};
+
+static struct platform_driver msm_bus_proxy_client_driver = {
+	.probe = msm_bus_device_proxy_client_probe,
+	.driver = {
+		.name = "msm_bus_proxy_client_device",
+		.owner = THIS_MODULE,
+		.of_match_table = proxy_client_match,
+	},
+};
+
+static int __init msm_bus_proxy_client_init_driver(void)
+{
+	int rc;
+
+	rc =  platform_driver_register(&msm_bus_proxy_client_driver);
+	if (rc) {
+		pr_err("Failed to register proxy client device driver");
+		return rc;
+	}
+
+	return rc;
+}
+
+static int __init msm_bus_proxy_client_unvote(void)
+{
+	int ret;
+
+	if (!proxy_client_info.pdata || !proxy_client_info.client_handle)
+		return 0;
+
+	ret = msm_bus_scale_client_update_request(
+					proxy_client_info.client_handle, 0);
+	if (ret)
+		pr_err("%s: bandwidth update request failed (%d)\n",
+			__func__, ret);
+
+	msm_bus_scale_unregister_client(proxy_client_info.client_handle);
+
+	return 0;
+}
+
+subsys_initcall_sync(msm_bus_proxy_client_init_driver);
+late_initcall_sync(msm_bus_proxy_client_unvote);
diff --git a/drivers/soc/qcom/rpm-smd.c b/drivers/soc/qcom/rpm-smd.c
index 3fc7fbf..c29cfcb 100644
--- a/drivers/soc/qcom/rpm-smd.c
+++ b/drivers/soc/qcom/rpm-smd.c
@@ -31,7 +31,6 @@
 #include <linux/device.h>
 #include <linux/notifier.h>
 #include <linux/slab.h>
-#include <linux/workqueue.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
@@ -126,8 +125,6 @@
 	return atomic_notifier_chain_unregister(&msm_rpm_sleep_notifier, nb);
 }
 
-static struct workqueue_struct *msm_rpm_smd_wq;
-
 enum {
 	MSM_RPM_MSG_REQUEST_TYPE = 0,
 	MSM_RPM_MSG_TYPE_NR,
@@ -2120,15 +2117,6 @@
 
 	smd_disable_read_intr(msm_rpm_data.ch_info);
 
-	msm_rpm_smd_wq = alloc_workqueue("rpm-smd",
-				WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_HIGHPRI, 1);
-	if (!msm_rpm_smd_wq) {
-		pr_err("%s: Unable to alloc rpm-smd workqueue\n", __func__);
-		ret = -EINVAL;
-		goto fail;
-	}
-	queue_work(msm_rpm_smd_wq, &msm_rpm_data.work);
-
 	probe_status = ret;
 skip_init:
 	of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
diff --git a/drivers/soc/qcom/rq_stats.c b/drivers/soc/qcom/rq_stats.c
index 5850c46..1b4cf4f 100644
--- a/drivers/soc/qcom/rq_stats.c
+++ b/drivers/soc/qcom/rq_stats.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2015, 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
@@ -264,7 +264,7 @@
 static ssize_t show_def_timer_ms(struct kobject *kobj,
 		struct kobj_attribute *attr, char *buf)
 {
-	int64_t diff;
+	uint64_t diff;
 	unsigned int udiff;
 
 	diff = ktime_to_ns(ktime_get()) - rq_info.def_start_time;
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index e0321a1..edf855c 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -256,9 +256,9 @@
 
 	dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
 
-	dwc3_notify_event(dwc, DWC3_CONTROLLER_RESET_EVENT);
+	dwc3_notify_event(dwc, DWC3_CONTROLLER_RESET_EVENT, 0);
 
-	dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_RESET_EVENT);
+	dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_RESET_EVENT, 0);
 
 	return 0;
 }
@@ -366,7 +366,7 @@
 		dwc3_free_one_event_buffer(dwc, evt);
 
 	/* free GSI related event buffers */
-	dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_FREE);
+	dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_FREE, 0);
 }
 
 /**
@@ -389,7 +389,7 @@
 	dwc->ev_buf = evt;
 
 	/* alloc GSI related event buffers */
-	dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_ALLOC);
+	dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_ALLOC, 0);
 	return 0;
 }
 
@@ -420,7 +420,7 @@
 	dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
 
 	/* setup GSI related event buffers */
-	dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_SETUP);
+	dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_SETUP, 0);
 	return 0;
 }
 
@@ -442,7 +442,7 @@
 	dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
 
 	/* cleanup GSI related event buffers */
-	dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_CLEANUP);
+	dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_CLEANUP, 0);
 }
 
 static int dwc3_alloc_scratch_buffers(struct dwc3 *dwc)
@@ -1026,19 +1026,20 @@
 	dwc3_gadget_restart(dwc);
 }
 
-static void (*notify_event)(struct dwc3 *, unsigned int);
-void dwc3_set_notifier(void (*notify)(struct dwc3 *, unsigned int))
+static void (*notify_event)(struct dwc3 *, unsigned int, unsigned int);
+void dwc3_set_notifier(void (*notify)(struct dwc3 *, unsigned int,
+							unsigned int))
 {
 	notify_event = notify;
 }
 EXPORT_SYMBOL(dwc3_set_notifier);
 
-int dwc3_notify_event(struct dwc3 *dwc, unsigned int event)
+int dwc3_notify_event(struct dwc3 *dwc, unsigned int event, unsigned int value)
 {
 	int ret = 0;
 
 	if (dwc->notify_event)
-		dwc->notify_event(dwc, event);
+		dwc->notify_event(dwc, event, value);
 	else
 		ret = -ENODEV;
 
@@ -1459,7 +1460,7 @@
 	int		ret;
 
 	/* Check if platform glue driver handling PM, if not then handle here */
-	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_RESUME_EVENT))
+	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_RESUME_EVENT, 0))
 		return 0;
 
 	ret = dwc3_suspend_common(dwc);
@@ -1477,7 +1478,7 @@
 	int		ret;
 
 	/* Check if platform glue driver handling PM, if not then handle here */
-	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_RESUME_EVENT))
+	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_RESUME_EVENT, 0))
 		return 0;
 
 	device_init_wakeup(dev, false);
@@ -1533,7 +1534,7 @@
 	int		ret;
 
 	/* Check if platform glue driver handling PM, if not then handle here */
-	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_SUSPEND_EVENT))
+	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_SUSPEND_EVENT, 0))
 		return 0;
 
 	ret = dwc3_suspend_common(dwc);
@@ -1551,7 +1552,7 @@
 	int		ret;
 
 	/* Check if platform glue driver handling PM, if not then handle here */
-	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_RESUME_EVENT))
+	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_RESUME_EVENT, 0))
 		return 0;
 
 	pinctrl_pm_select_default_state(dev);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index b91642a..69d3fa8 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -821,21 +821,22 @@
 	__le64	dma_adr[DWC3_MAX_HIBER_SCRATCHBUFS];
 };
 
-#define DWC3_CONTROLLER_ERROR_EVENT		0
-#define DWC3_CONTROLLER_RESET_EVENT		1
-#define DWC3_CONTROLLER_POST_RESET_EVENT	2
-#define DWC3_CORE_PM_SUSPEND_EVENT		3
-#define DWC3_CORE_PM_RESUME_EVENT		4
-#define DWC3_CONTROLLER_CONNDONE_EVENT		5
-#define DWC3_CONTROLLER_NOTIFY_OTG_EVENT	6
-#define DWC3_CONTROLLER_SET_CURRENT_DRAW_EVENT	7
-#define DWC3_CONTROLLER_RESTART_USB_SESSION	8
+#define DWC3_CONTROLLER_ERROR_EVENT			0
+#define DWC3_CONTROLLER_RESET_EVENT			1
+#define DWC3_CONTROLLER_POST_RESET_EVENT		2
+#define DWC3_CORE_PM_SUSPEND_EVENT			3
+#define DWC3_CORE_PM_RESUME_EVENT			4
+#define DWC3_CONTROLLER_CONNDONE_EVENT			5
+#define DWC3_CONTROLLER_NOTIFY_OTG_EVENT		6
+#define DWC3_CONTROLLER_SET_CURRENT_DRAW_EVENT		7
+#define DWC3_CONTROLLER_RESTART_USB_SESSION		8
+#define DWC3_CONTROLLER_NOTIFY_DISABLE_UPDXFER		9
 
 /* USB GSI event buffer related notification */
-#define DWC3_GSI_EVT_BUF_ALLOC			9
-#define DWC3_GSI_EVT_BUF_SETUP			10
-#define DWC3_GSI_EVT_BUF_CLEANUP		11
-#define DWC3_GSI_EVT_BUF_FREE			12
+#define DWC3_GSI_EVT_BUF_ALLOC			10
+#define DWC3_GSI_EVT_BUF_SETUP			11
+#define DWC3_GSI_EVT_BUF_CLEANUP		12
+#define DWC3_GSI_EVT_BUF_FREE			13
 
 #define MAX_INTR_STATS				10
 
@@ -1081,7 +1082,7 @@
 	const char		*hsphy_interface;
 
 	unsigned		connected:1;
-	void (*notify_event)(struct dwc3 *, unsigned int);
+	void (*notify_event)(struct dwc3 *, unsigned int, unsigned int);
 	struct work_struct	wakeup_work;
 
 	unsigned		delayed_status:1;
@@ -1416,6 +1417,9 @@
 void dwc3_usb3_phy_suspend(struct dwc3 *dwc, int suspend);
 
 extern void dwc3_set_notifier(
-		void (*notify)(struct dwc3 *dwc3, unsigned int event));
-extern int dwc3_notify_event(struct dwc3 *dwc3, unsigned int event);
+	void (*notify)(struct dwc3 *dwc3, unsigned int event,
+						unsigned int value));
+extern int dwc3_notify_event(struct dwc3 *dwc3, unsigned int event,
+							unsigned int value);
+
 #endif /* __DRIVERS_USB_DWC3_CORE_H */
diff --git a/drivers/usb/dwc3/dbm.c b/drivers/usb/dwc3/dbm.c
index ec2e736..48b3894 100644
--- a/drivers/usb/dwc3/dbm.c
+++ b/drivers/usb/dwc3/dbm.c
@@ -37,6 +37,7 @@
 	DBM_HW_TRB2_EP,
 	DBM_HW_TRB3_EP,
 	DBM_PIPE_CFG,
+	DBM_DISABLE_UPDXFER,
 	DBM_SOFT_RESET,
 	DBM_GEN_CFG,
 	DBM_GEVNTADR_LSB,
@@ -103,6 +104,7 @@
 	[DBM_HW_TRB2_EP]	= { 0x0240, 0x4 },
 	[DBM_HW_TRB3_EP]	= { 0x0250, 0x4 },
 	[DBM_PIPE_CFG]		= { 0x0274, 0x0 },
+	[DBM_DISABLE_UPDXFER]	= { 0x0298, 0x0 },
 	[DBM_SOFT_RESET]	= { 0x020C, 0x0 },
 	[DBM_GEN_CFG]		= { 0x0210, 0x0 },
 	[DBM_GEVNTADR_LSB]	= { 0x0260, 0x0 },
@@ -291,6 +293,7 @@
 {
 	int dbm_ep;
 	u32 ep_cfg;
+	u32 data;
 
 	if (!dbm) {
 		pr_err("%s: dbm pointer is NULL!\n", __func__);
@@ -334,6 +337,10 @@
 
 	msm_dbm_write_ep_reg_field(dbm, DBM_EP_CFG, dbm_ep, DBM_EN_EP, 1);
 
+	data = msm_dbm_read_reg(dbm, DBM_DISABLE_UPDXFER);
+	data &= ~(0x1 << dbm_ep);
+	msm_dbm_write_reg(dbm, DBM_DISABLE_UPDXFER, data);
+
 	return dbm_ep;
 }
 
@@ -433,6 +440,35 @@
 	return 0;
 }
 
+/**
+ * Disable update xfer before queueing stop xfer command to USB3 core.
+ *
+ * @usb_ep - USB physical EP number.
+ *
+ */
+int dwc3_dbm_disable_update_xfer(struct dbm *dbm, u8 usb_ep)
+{
+	u32 data;
+	int dbm_ep;
+
+	if (!dbm) {
+		pr_err("%s: dbm pointer is NULL!\n", __func__);
+		return -EPERM;
+	}
+
+	dbm_ep = find_matching_dbm_ep(dbm, usb_ep);
+
+	if (dbm_ep < 0) {
+		pr_err("usb ep index %d has no corresponding dbm ep\n", usb_ep);
+		return -ENODEV;
+	}
+
+	data = msm_dbm_read_reg(dbm, DBM_DISABLE_UPDXFER);
+	data |= (0x1 << dbm_ep);
+	msm_dbm_write_reg(dbm, DBM_DISABLE_UPDXFER, data);
+
+	return 0;
+}
 
 int dbm_data_fifo_config(struct dbm *dbm, u8 dep_num, unsigned long addr,
 				u32 size, u8 dst_pipe_idx)
diff --git a/drivers/usb/dwc3/dbm.h b/drivers/usb/dwc3/dbm.h
index d8e1ce9..259900d 100644
--- a/drivers/usb/dwc3/dbm.h
+++ b/drivers/usb/dwc3/dbm.h
@@ -65,6 +65,7 @@
 				int size);
 int dbm_data_fifo_config(struct dbm *dbm, u8 dep_num, unsigned long addr,
 				u32 size, u8 dst_pipe_idx);
+int dwc3_dbm_disable_update_xfer(struct dbm *dbm, u8 usb_ep);
 void dbm_set_speed(struct dbm *dbm, bool speed);
 void dbm_enable(struct dbm *dbm);
 int dbm_ep_soft_reset(struct dbm *dbm, u8 usb_ep, bool enter_reset);
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index a7ec04f..ded62f1 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -289,7 +289,8 @@
 
 static void dwc3_pwr_event_handler(struct dwc3_msm *mdwc);
 static int dwc3_msm_gadget_vbus_draw(struct dwc3_msm *mdwc, unsigned int mA);
-static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event);
+static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event,
+						unsigned int value);
 static int dwc3_restart_usb_host_mode(struct notifier_block *nb,
 					unsigned long event, void *ptr);
 
@@ -441,6 +442,16 @@
 	return dwc3_msm_is_dev_superspeed(mdwc);
 }
 
+static int dwc3_msm_dbm_disable_updxfer(struct dwc3 *dwc, u8 usb_ep)
+{
+	struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent);
+
+	dev_dbg(mdwc->dev, "%s\n", __func__);
+	dwc3_dbm_disable_update_xfer(mdwc->dbm, usb_ep);
+
+	return 0;
+}
+
 #if IS_ENABLED(CONFIG_USB_DWC3_GADGET) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
 /**
  * Configure the DBM with the BAM's data fifo.
@@ -1817,7 +1828,8 @@
 	dwc3_msm_gadget_vbus_draw(mdwc, dwc->vbus_draw);
 }
 
-static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event)
+static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event,
+							unsigned int value)
 {
 	struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent);
 	struct dwc3_event_buffer *evt;
@@ -2004,6 +2016,9 @@
 							evt->buf, evt->dma);
 		}
 		break;
+	case DWC3_CONTROLLER_NOTIFY_DISABLE_UPDXFER:
+		dwc3_msm_dbm_disable_updxfer(dwc, value);
+		break;
 	default:
 		dev_dbg(mdwc->dev, "unknown dwc3 event\n");
 		break;
@@ -3872,6 +3887,9 @@
 	if (on) {
 		dev_dbg(mdwc->dev, "%s: turn on host\n", __func__);
 
+		pm_runtime_get_sync(mdwc->dev);
+		dbg_event(0xFF, "StrtHost gync",
+			atomic_read(&mdwc->dev->power.usage_count));
 		mdwc->hs_phy->flags |= PHY_HOST_MODE;
 		if (dwc->maximum_speed == USB_SPEED_SUPER) {
 			mdwc->ss_phy->flags |= PHY_HOST_MODE;
@@ -3880,9 +3898,6 @@
 		}
 
 		usb_phy_notify_connect(mdwc->hs_phy, USB_SPEED_HIGH);
-		pm_runtime_get_sync(mdwc->dev);
-		dbg_event(0xFF, "StrtHost gync",
-			atomic_read(&mdwc->dev->power.usage_count));
 		if (!IS_ERR_OR_NULL(mdwc->vbus_reg))
 			ret = regulator_enable(mdwc->vbus_reg);
 		if (ret) {
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 8f0ca3f..3157195 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -416,7 +416,7 @@
 		if (cmd != DWC3_DEPCMD_ENDTRANSFER) {
 			dwc->ep_cmd_timeout_cnt++;
 			dwc3_notify_event(dwc,
-				DWC3_CONTROLLER_RESTART_USB_SESSION);
+				DWC3_CONTROLLER_RESTART_USB_SESSION, 0);
 		}
 		cmd_status = -ETIMEDOUT;
 	}
@@ -2074,7 +2074,7 @@
 	dwc->vbus_draw = mA;
 	dev_dbg(dwc->dev, "Notify controller from %s. mA = %u\n", __func__, mA);
 	dbg_event(0xFF, "currentDraw", mA);
-	dwc3_notify_event(dwc, DWC3_CONTROLLER_SET_CURRENT_DRAW_EVENT);
+	dwc3_notify_event(dwc, DWC3_CONTROLLER_SET_CURRENT_DRAW_EVENT, 0);
 	return 0;
 }
 
@@ -2105,7 +2105,8 @@
 	 * during enumeration.
 	 */
 	dwc->b_suspend = false;
-	dwc3_notify_event(dwc, DWC3_CONTROLLER_NOTIFY_OTG_EVENT);
+	dwc3_notify_event(dwc, DWC3_CONTROLLER_NOTIFY_OTG_EVENT, 0);
+
 	ret = dwc3_gadget_run_stop(dwc, is_on, false);
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
@@ -2416,7 +2417,7 @@
 	struct dwc3		*dwc = gadget_to_dwc(g);
 
 	dbg_event(0xFF, "RestartUSBSession", 0);
-	return dwc3_notify_event(dwc, DWC3_CONTROLLER_RESTART_USB_SESSION);
+	return dwc3_notify_event(dwc, DWC3_CONTROLLER_RESTART_USB_SESSION, 0);
 }
 
 static const struct usb_gadget_ops dwc3_gadget_ops = {
@@ -2969,6 +2970,10 @@
 	if (!dep->resource_index)
 		return;
 
+	if (dep->endpoint.endless)
+		dwc3_notify_event(dwc, DWC3_CONTROLLER_NOTIFY_DISABLE_UPDXFER,
+								dep->number);
+
 	/*
 	 * NOTICE: We are violating what the Databook says about the
 	 * EndTransfer command. Ideally we would _always_ wait for the
@@ -3062,7 +3067,7 @@
 	dbg_event(0xFF, "DISCONNECT INT", 0);
 	dev_dbg(dwc->dev, "Notify OTG from %s\n", __func__);
 	dwc->b_suspend = false;
-	dwc3_notify_event(dwc, DWC3_CONTROLLER_NOTIFY_OTG_EVENT);
+	dwc3_notify_event(dwc, DWC3_CONTROLLER_NOTIFY_OTG_EVENT, 0);
 
 	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
 	reg &= ~DWC3_DCTL_INITU1ENA;
@@ -3122,7 +3127,7 @@
 	dbg_event(0xFF, "BUS RESET", 0);
 	dev_dbg(dwc->dev, "Notify OTG from %s\n", __func__);
 	dwc->b_suspend = false;
-	dwc3_notify_event(dwc, DWC3_CONTROLLER_NOTIFY_OTG_EVENT);
+	dwc3_notify_event(dwc, DWC3_CONTROLLER_NOTIFY_OTG_EVENT, 0);
 
 	dwc3_usb3_phy_suspend(dwc, false);
 	usb_gadget_vbus_draw(&dwc->gadget, 100);
@@ -3297,7 +3302,8 @@
 		return;
 	}
 
-	dwc3_notify_event(dwc, DWC3_CONTROLLER_CONNDONE_EVENT);
+	dwc3_notify_event(dwc, DWC3_CONTROLLER_CONNDONE_EVENT, 0);
+
 	/*
 	 * Configure PHY via GUSB3PIPECTLn if required.
 	 *
@@ -3332,7 +3338,8 @@
 		 */
 		dev_dbg(dwc->dev, "Notify OTG from %s\n", __func__);
 		dwc->b_suspend = false;
-		dwc3_notify_event(dwc, DWC3_CONTROLLER_NOTIFY_OTG_EVENT);
+		dwc3_notify_event(dwc,
+				DWC3_CONTROLLER_NOTIFY_OTG_EVENT, 0);
 
 		/*
 		 * set state to U0 as function level resume is trying to queue
@@ -3476,7 +3483,7 @@
 
 		dev_dbg(dwc->dev, "Notify OTG from %s\n", __func__);
 		dwc->b_suspend = true;
-		dwc3_notify_event(dwc, DWC3_CONTROLLER_NOTIFY_OTG_EVENT);
+		dwc3_notify_event(dwc, DWC3_CONTROLLER_NOTIFY_OTG_EVENT, 0);
 	}
 
 	dwc->link_state = next;
@@ -3640,7 +3647,8 @@
 			evt->lpos = (evt->lpos + left) %
 					DWC3_EVENT_BUFFERS_SIZE;
 			dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), left);
-			if (dwc3_notify_event(dwc, DWC3_CONTROLLER_ERROR_EVENT))
+			if (dwc3_notify_event(dwc,
+						DWC3_CONTROLLER_ERROR_EVENT, 0))
 				dwc->err_evt_seen = 0;
 			break;
 		}
diff --git a/drivers/usb/phy/phy-msm-snps-hs.c b/drivers/usb/phy/phy-msm-snps-hs.c
index 3482c93..e625839 100644
--- a/drivers/usb/phy/phy-msm-snps-hs.c
+++ b/drivers/usb/phy/phy-msm-snps-hs.c
@@ -96,6 +96,9 @@
 	bool			suspended;
 	bool			cable_connected;
 
+	int			*param_override_seq;
+	int			param_override_seq_cnt;
+
 	/* emulation targets specific */
 	void __iomem		*emu_phy_base;
 	int			*emu_init_seq;
@@ -381,6 +384,11 @@
 	msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL1,
 				VBUSVLDEXT0, VBUSVLDEXT0);
 
+	/* set parameter ovrride  if needed */
+	if (phy->param_override_seq)
+		hsusb_phy_write_seq(phy->base, phy->param_override_seq,
+				phy->param_override_seq_cnt, 0);
+
 	msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON2,
 				VREGBYPASS, VREGBYPASS);
 
@@ -576,6 +584,34 @@
 		}
 	}
 
+	phy->param_override_seq_cnt = of_property_count_elems_of_size(
+					dev->of_node,
+					"qcom,param-override-seq",
+					sizeof(*phy->param_override_seq));
+	if (phy->param_override_seq_cnt > 0) {
+		phy->param_override_seq = devm_kcalloc(dev,
+					phy->param_override_seq_cnt,
+					sizeof(*phy->param_override_seq),
+					GFP_KERNEL);
+		if (!phy->param_override_seq)
+			return -ENOMEM;
+
+		if (phy->param_override_seq_cnt % 2) {
+			dev_err(dev, "invalid param_override_seq_len\n");
+			return -EINVAL;
+		}
+
+		ret = of_property_read_u32_array(dev->of_node,
+				"qcom,param-override-seq",
+				phy->param_override_seq,
+				phy->param_override_seq_cnt);
+		if (ret) {
+			dev_err(dev, "qcom,param-override-seq read failed %d\n",
+				ret);
+			return ret;
+		}
+	}
+
 	ret = of_property_read_u32_array(dev->of_node, "qcom,vdd-voltage-level",
 					 (u32 *) phy->vdd_levels,
 					 ARRAY_SIZE(phy->vdd_levels));
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 3b69ed3..9900693 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -629,6 +629,8 @@
 	spin_lock(&bdev_lock);
 	list_del_init(&bdev->bd_list);
 	spin_unlock(&bdev_lock);
+	/* Detach inode from wb early as bdi_put() may free bdi->wb */
+	inode_detach_wb(inode);
 	if (bdev->bd_bdi != &noop_backing_dev_info) {
 		bdi_put(bdev->bd_bdi);
 		bdev->bd_bdi = &noop_backing_dev_info;
@@ -1299,8 +1301,6 @@
 		bdev->bd_disk = disk;
 		bdev->bd_queue = disk->queue;
 		bdev->bd_contains = bdev;
-		if (bdev->bd_bdi == &noop_backing_dev_info)
-			bdev->bd_bdi = bdi_get(disk->queue->backing_dev_info);
 
 		if (!partno) {
 			ret = -ENXIO;
@@ -1365,6 +1365,9 @@
 			}
 			bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9);
 		}
+
+		if (bdev->bd_bdi == &noop_backing_dev_info)
+			bdev->bd_bdi = bdi_get(disk->queue->backing_dev_info);
 	} else {
 		if (bdev->bd_contains == bdev) {
 			ret = 0;
@@ -1396,8 +1399,6 @@
 	bdev->bd_disk = NULL;
 	bdev->bd_part = NULL;
 	bdev->bd_queue = NULL;
-	bdi_put(bdev->bd_bdi);
-	bdev->bd_bdi = &noop_backing_dev_info;
 	if (bdev != bdev->bd_contains)
 		__blkdev_put(bdev->bd_contains, mode, 1);
 	bdev->bd_contains = NULL;
@@ -1619,12 +1620,6 @@
 		kill_bdev(bdev);
 
 		bdev_write_inode(bdev);
-		/*
-		 * Detaching bdev inode from its wb in __destroy_inode()
-		 * is too late: the queue which embeds its bdi (along with
-		 * root wb) can be gone as soon as we put_disk() below.
-		 */
-		inode_detach_wb(bdev->bd_inode);
 	}
 	if (bdev->bd_contains == bdev) {
 		if (disk->fops->release)
diff --git a/include/linux/backing-dev-defs.h b/include/linux/backing-dev-defs.h
index 2ae452e..0691068 100644
--- a/include/linux/backing-dev-defs.h
+++ b/include/linux/backing-dev-defs.h
@@ -21,6 +21,7 @@
  */
 enum wb_state {
 	WB_registered,		/* bdi_register() was done */
+	WB_shutting_down,	/* wb_shutdown() in progress */
 	WB_writeback_running,	/* Writeback is in progress */
 	WB_has_dirty_io,	/* Dirty inodes on ->b_{dirty|io|more_io} */
 };
@@ -54,7 +55,9 @@
 	atomic_t refcnt;		/* nr of attached wb's and blkg */
 
 #ifdef CONFIG_CGROUP_WRITEBACK
-	struct backing_dev_info *bdi;	/* the associated bdi */
+	struct backing_dev_info *__bdi;	/* the associated bdi, set to NULL
+					 * on bdi unregistration. For memcg-wb
+					 * internal use only! */
 	int blkcg_id;			/* ID of the associated blkcg */
 	struct rb_node rb_node;		/* on bdi->cgwb_congestion_tree */
 #endif
@@ -158,7 +161,6 @@
 #ifdef CONFIG_CGROUP_WRITEBACK
 	struct radix_tree_root cgwb_tree; /* radix tree of active cgroup wbs */
 	struct rb_root cgwb_congested_tree; /* their congested states */
-	atomic_t usage_cnt; /* counts both cgwbs and cgwb_contested's */
 #else
 	struct bdi_writeback_congested *wb_congested;
 #endif
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index 74de8b6..5c8b65a 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -108,6 +108,8 @@
 extern int __must_check kobject_move(struct kobject *, struct kobject *);
 
 extern struct kobject *kobject_get(struct kobject *kobj);
+extern struct kobject * __must_check kobject_get_unless_zero(
+						struct kobject *kobj);
 extern void kobject_put(struct kobject *kobj);
 
 extern const void *kobject_namespace(struct kobject *kobj);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 290e2b2..8933c9f 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2754,11 +2754,6 @@
 	return 0;
 }
 
-static inline void
-sched_set_cpu_cstate(int cpu, int cstate, int wakeup_energy, int wakeup_latency)
-{
-}
-
 #ifdef CONFIG_SCHED_WALT
 extern int register_cpu_cycle_counter_cb(struct cpu_cycle_counter_cb *cb);
 extern void sched_set_io_is_busy(int val);
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 797100e..9a8eb83 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -224,6 +224,7 @@
 static inline void inode_detach_wb(struct inode *inode)
 {
 	if (inode->i_wb) {
+		WARN_ON_ONCE(!(inode->i_state & I_CLEAR));
 		wb_put(inode->i_wb);
 		inode->i_wb = NULL;
 	}
diff --git a/include/soc/qcom/clock-alpha-pll.h b/include/soc/qcom/clock-alpha-pll.h
index f8130f1..20f8a2f 100644
--- a/include/soc/qcom/clock-alpha-pll.h
+++ b/include/soc/qcom/clock-alpha-pll.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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
@@ -27,6 +27,7 @@
 	u32 alpha_en_mask;	/* alpha_en bit */
 	u32 output_mask;	/* pllout_* bits */
 	u32 post_div_mask;
+	u32 cal_l_val_mask;
 
 	u32 test_ctl_lo_mask;
 	u32 test_ctl_hi_mask;
@@ -61,6 +62,7 @@
 	u32 config_ctl_val;	/* config register init value */
 	u32 test_ctl_lo_val;	/* test control settings */
 	u32 test_ctl_hi_val;
+	u32 cal_l_val;		/* Calibration L value */
 
 	struct alpha_pll_vco_tbl *vco_tbl;
 	u32 num_vco;
diff --git a/lib/kobject.c b/lib/kobject.c
index 445dcae..763d70a 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -601,12 +601,15 @@
 }
 EXPORT_SYMBOL(kobject_get);
 
-static struct kobject * __must_check kobject_get_unless_zero(struct kobject *kobj)
+struct kobject * __must_check kobject_get_unless_zero(struct kobject *kobj)
 {
+	if (!kobj)
+		return NULL;
 	if (!kref_get_unless_zero(&kobj->kref))
 		kobj = NULL;
 	return kobj;
 }
+EXPORT_SYMBOL(kobject_get_unless_zero);
 
 /*
  * kobject_cleanup - free kobject resources.
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index ed9574e..62ca907 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -294,6 +294,8 @@
 
 	memset(wb, 0, sizeof(*wb));
 
+	if (wb != &bdi->wb)
+		bdi_get(bdi);
 	wb->bdi = bdi;
 	wb->last_old_flush = jiffies;
 	INIT_LIST_HEAD(&wb->b_dirty);
@@ -313,8 +315,10 @@
 	INIT_DELAYED_WORK(&wb->dwork, wb_workfn);
 
 	wb->congested = wb_congested_get_create(bdi, blkcg_id, gfp);
-	if (!wb->congested)
-		return -ENOMEM;
+	if (!wb->congested) {
+		err = -ENOMEM;
+		goto out_put_bdi;
+	}
 
 	err = fprop_local_init_percpu(&wb->completions, gfp);
 	if (err)
@@ -334,9 +338,14 @@
 	fprop_local_destroy_percpu(&wb->completions);
 out_put_cong:
 	wb_congested_put(wb->congested);
+out_put_bdi:
+	if (wb != &bdi->wb)
+		bdi_put(bdi);
 	return err;
 }
 
+static void cgwb_remove_from_bdi_list(struct bdi_writeback *wb);
+
 /*
  * Remove bdi from the global list and shutdown any threads we have running
  */
@@ -346,10 +355,18 @@
 	spin_lock_bh(&wb->work_lock);
 	if (!test_and_clear_bit(WB_registered, &wb->state)) {
 		spin_unlock_bh(&wb->work_lock);
+		/*
+		 * Wait for wb shutdown to finish if someone else is just
+		 * running wb_shutdown(). Otherwise we could proceed to wb /
+		 * bdi destruction before wb_shutdown() is finished.
+		 */
+		wait_on_bit(&wb->state, WB_shutting_down, TASK_UNINTERRUPTIBLE);
 		return;
 	}
+	set_bit(WB_shutting_down, &wb->state);
 	spin_unlock_bh(&wb->work_lock);
 
+	cgwb_remove_from_bdi_list(wb);
 	/*
 	 * Drain work list and shutdown the delayed_work.  !WB_registered
 	 * tells wb_workfn() that @wb is dying and its work_list needs to
@@ -358,6 +375,12 @@
 	mod_delayed_work(bdi_wq, &wb->dwork, 0);
 	flush_delayed_work(&wb->dwork);
 	WARN_ON(!list_empty(&wb->work_list));
+	/*
+	 * Make sure bit gets cleared after shutdown is finished. Matches with
+	 * the barrier provided by test_and_clear_bit() above.
+	 */
+	smp_wmb();
+	clear_bit(WB_shutting_down, &wb->state);
 }
 
 static void wb_exit(struct bdi_writeback *wb)
@@ -371,6 +394,8 @@
 
 	fprop_local_destroy_percpu(&wb->completions);
 	wb_congested_put(wb->congested);
+	if (wb != &wb->bdi->wb)
+		bdi_put(wb->bdi);
 }
 
 #ifdef CONFIG_CGROUP_WRITEBACK
@@ -380,11 +405,9 @@
 /*
  * cgwb_lock protects bdi->cgwb_tree, bdi->cgwb_congested_tree,
  * blkcg->cgwb_list, and memcg->cgwb_list.  bdi->cgwb_tree is also RCU
- * protected.  cgwb_release_wait is used to wait for the completion of cgwb
- * releases from bdi destruction path.
+ * protected.
  */
 static DEFINE_SPINLOCK(cgwb_lock);
-static DECLARE_WAIT_QUEUE_HEAD(cgwb_release_wait);
 
 /**
  * wb_congested_get_create - get or create a wb_congested
@@ -437,7 +460,7 @@
 		return NULL;
 
 	atomic_set(&new_congested->refcnt, 0);
-	new_congested->bdi = bdi;
+	new_congested->__bdi = bdi;
 	new_congested->blkcg_id = blkcg_id;
 	goto retry;
 
@@ -465,10 +488,10 @@
 	}
 
 	/* bdi might already have been destroyed leaving @congested unlinked */
-	if (congested->bdi) {
+	if (congested->__bdi) {
 		rb_erase(&congested->rb_node,
-			 &congested->bdi->cgwb_congested_tree);
-		congested->bdi = NULL;
+			 &congested->__bdi->cgwb_congested_tree);
+		congested->__bdi = NULL;
 	}
 
 	spin_unlock_irqrestore(&cgwb_lock, flags);
@@ -479,11 +502,6 @@
 {
 	struct bdi_writeback *wb = container_of(work, struct bdi_writeback,
 						release_work);
-	struct backing_dev_info *bdi = wb->bdi;
-
-	spin_lock_irq(&cgwb_lock);
-	list_del_rcu(&wb->bdi_node);
-	spin_unlock_irq(&cgwb_lock);
 
 	wb_shutdown(wb);
 
@@ -494,9 +512,6 @@
 	percpu_ref_exit(&wb->refcnt);
 	wb_exit(wb);
 	kfree_rcu(wb, rcu);
-
-	if (atomic_dec_and_test(&bdi->usage_cnt))
-		wake_up_all(&cgwb_release_wait);
 }
 
 static void cgwb_release(struct percpu_ref *refcnt)
@@ -516,6 +531,13 @@
 	percpu_ref_kill(&wb->refcnt);
 }
 
+static void cgwb_remove_from_bdi_list(struct bdi_writeback *wb)
+{
+	spin_lock_irq(&cgwb_lock);
+	list_del_rcu(&wb->bdi_node);
+	spin_unlock_irq(&cgwb_lock);
+}
+
 static int cgwb_create(struct backing_dev_info *bdi,
 		       struct cgroup_subsys_state *memcg_css, gfp_t gfp)
 {
@@ -579,7 +601,6 @@
 		/* we might have raced another instance of this function */
 		ret = radix_tree_insert(&bdi->cgwb_tree, memcg_css->id, wb);
 		if (!ret) {
-			atomic_inc(&bdi->usage_cnt);
 			list_add_tail_rcu(&wb->bdi_node, &bdi->wb_list);
 			list_add(&wb->memcg_node, memcg_cgwb_list);
 			list_add(&wb->blkcg_node, blkcg_cgwb_list);
@@ -669,7 +690,6 @@
 
 	INIT_RADIX_TREE(&bdi->cgwb_tree, GFP_ATOMIC);
 	bdi->cgwb_congested_tree = RB_ROOT;
-	atomic_set(&bdi->usage_cnt, 1);
 
 	ret = wb_init(&bdi->wb, bdi, 1, GFP_KERNEL);
 	if (!ret) {
@@ -679,36 +699,26 @@
 	return ret;
 }
 
-static void cgwb_bdi_destroy(struct backing_dev_info *bdi)
+static void cgwb_bdi_unregister(struct backing_dev_info *bdi)
 {
 	struct radix_tree_iter iter;
-	struct rb_node *rbn;
 	void **slot;
+	struct bdi_writeback *wb;
 
 	WARN_ON(test_bit(WB_registered, &bdi->wb.state));
 
 	spin_lock_irq(&cgwb_lock);
-
 	radix_tree_for_each_slot(slot, &bdi->cgwb_tree, &iter, 0)
 		cgwb_kill(*slot);
 
-	while ((rbn = rb_first(&bdi->cgwb_congested_tree))) {
-		struct bdi_writeback_congested *congested =
-			rb_entry(rbn, struct bdi_writeback_congested, rb_node);
-
-		rb_erase(rbn, &bdi->cgwb_congested_tree);
-		congested->bdi = NULL;	/* mark @congested unlinked */
+	while (!list_empty(&bdi->wb_list)) {
+		wb = list_first_entry(&bdi->wb_list, struct bdi_writeback,
+				      bdi_node);
+		spin_unlock_irq(&cgwb_lock);
+		wb_shutdown(wb);
+		spin_lock_irq(&cgwb_lock);
 	}
-
 	spin_unlock_irq(&cgwb_lock);
-
-	/*
-	 * All cgwb's and their congested states must be shutdown and
-	 * released before returning.  Drain the usage counter to wait for
-	 * all cgwb's and cgwb_congested's ever created on @bdi.
-	 */
-	atomic_dec(&bdi->usage_cnt);
-	wait_event(cgwb_release_wait, !atomic_read(&bdi->usage_cnt));
 }
 
 /**
@@ -748,6 +758,28 @@
 	spin_unlock_irq(&cgwb_lock);
 }
 
+static void cgwb_bdi_exit(struct backing_dev_info *bdi)
+{
+	struct rb_node *rbn;
+
+	spin_lock_irq(&cgwb_lock);
+	while ((rbn = rb_first(&bdi->cgwb_congested_tree))) {
+		struct bdi_writeback_congested *congested =
+			rb_entry(rbn, struct bdi_writeback_congested, rb_node);
+
+		rb_erase(rbn, &bdi->cgwb_congested_tree);
+		congested->__bdi = NULL;	/* mark @congested unlinked */
+	}
+	spin_unlock_irq(&cgwb_lock);
+}
+
+static void cgwb_bdi_register(struct backing_dev_info *bdi)
+{
+	spin_lock_irq(&cgwb_lock);
+	list_add_tail_rcu(&bdi->wb.bdi_node, &bdi->wb_list);
+	spin_unlock_irq(&cgwb_lock);
+}
+
 #else	/* CONFIG_CGROUP_WRITEBACK */
 
 static int cgwb_bdi_init(struct backing_dev_info *bdi)
@@ -768,11 +800,23 @@
 	return 0;
 }
 
-static void cgwb_bdi_destroy(struct backing_dev_info *bdi)
+static void cgwb_bdi_unregister(struct backing_dev_info *bdi) { }
+
+static void cgwb_bdi_exit(struct backing_dev_info *bdi)
 {
 	wb_congested_put(bdi->wb_congested);
 }
 
+static void cgwb_bdi_register(struct backing_dev_info *bdi)
+{
+	list_add_tail_rcu(&bdi->wb.bdi_node, &bdi->wb_list);
+}
+
+static void cgwb_remove_from_bdi_list(struct bdi_writeback *wb)
+{
+	list_del_rcu(&wb->bdi_node);
+}
+
 #endif	/* CONFIG_CGROUP_WRITEBACK */
 
 int bdi_init(struct backing_dev_info *bdi)
@@ -791,8 +835,6 @@
 
 	ret = cgwb_bdi_init(bdi);
 
-	list_add_tail_rcu(&bdi->wb.bdi_node, &bdi->wb_list);
-
 	return ret;
 }
 EXPORT_SYMBOL(bdi_init);
@@ -828,6 +870,7 @@
 	if (IS_ERR(dev))
 		return PTR_ERR(dev);
 
+	cgwb_bdi_register(bdi);
 	bdi->dev = dev;
 
 	bdi_debug_register(bdi, dev_name(dev));
@@ -856,6 +899,8 @@
 			MINOR(owner->devt));
 	if (rc)
 		return rc;
+	/* Leaking owner reference... */
+	WARN_ON(bdi->owner);
 	bdi->owner = owner;
 	get_device(owner);
 	return 0;
@@ -879,7 +924,7 @@
 	/* make sure nobody finds us on the bdi_list anymore */
 	bdi_remove_from_list(bdi);
 	wb_shutdown(&bdi->wb);
-	cgwb_bdi_destroy(bdi);
+	cgwb_bdi_unregister(bdi);
 
 	if (bdi->dev) {
 		bdi_debug_unregister(bdi);
@@ -897,6 +942,7 @@
 {
 	WARN_ON_ONCE(bdi->dev);
 	wb_exit(&bdi->wb);
+	cgwb_bdi_exit(bdi);
 }
 
 static void release_bdi(struct kref *ref)
diff --git a/net/rmnet_data/rmnet_data_handlers.c b/net/rmnet_data/rmnet_data_handlers.c
index 50dd516..98b2511 100644
--- a/net/rmnet_data/rmnet_data_handlers.c
+++ b/net/rmnet_data/rmnet_data_handlers.c
@@ -356,6 +356,7 @@
 			napi = get_current_napi_context();
 
 			skb_size = skb->len;
+			skb_get_hash(skb);
 			gro_res = napi_gro_receive(napi, skb);
 			trace_rmnet_gro_downlink(gro_res);
 			rmnet_optional_gro_flush(napi, ep, skb_size);