Merge "power: qpnp-bms: clean up rbatt logs"
diff --git a/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt b/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt
index cc1ffc2..3c3a242 100644
--- a/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt
+++ b/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt
@@ -11,17 +11,18 @@
 - qcom,iommu-pmu-ngroups: Number of Performance Monitor Unit (PMU) groups.
 - qcom,iommu-pmu-ncounters: Number of PMU counters per group.
 - qcom,iommu-pmu-event-classes: List of event classes supported.
+
 - List of sub nodes, one for each of the translation context banks supported.
-  Each sub node has the following required properties:
+    Required properties for each sub-node:
 
-  - reg : offset and length of the register set for the context bank.
-  - interrupts : should contain the context bank interrupt.
-  - qcom,iommu-ctx-mids : List of machine identifiers associated with this
-    translation context.
-  - label : Name of the context bank
+    - reg : offset and length of the register set for the context bank.
+    - interrupts : should contain the context bank interrupt.
+    - qcom,iommu-ctx-mids : List of machine identifiers associated with this
+      translation context.
+    - label : Name of the context bank
 
-Optional properties:
-  - none
+    Optional properties for each sub-node:
+    - none
 
 Example:
 
diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp.txt b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
index 96d95da..c409ea6 100644
--- a/Documentation/devicetree/bindings/leds/leds-qpnp.txt
+++ b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
@@ -45,6 +45,7 @@
 - qcom,saftey-timer: include for safety timer use, otherwise watchdog timer will be used
 - linux,default-trigger: trigger the led from external modules such as display
 - qcom,default-state:  default state of the led, should be "on" or "off"
+- qcom,torch-enable: set flash led to torch mode
 
 RGB Led is a tri-colored led, Red, Blue & Green.
 
diff --git a/Documentation/devicetree/bindings/sound/taiko_codec.txt b/Documentation/devicetree/bindings/sound/taiko_codec.txt
index 777933a..9abf54e 100644
--- a/Documentation/devicetree/bindings/sound/taiko_codec.txt
+++ b/Documentation/devicetree/bindings/sound/taiko_codec.txt
@@ -76,6 +76,8 @@
 				dynamically.
 				Supplies in this list are off by default.
 
+ - qcom,cdc-micbias2-headset-only: Boolean. Allow micbias 2 only to headset mic.
+
 Example:
 
 taiko_codec {
@@ -138,6 +140,7 @@
 	qcom,cdc-slim-ifd = "taiko-slim-ifd";
 	qcom,cdc-slim-ifd-elemental-addr = [00 00 A0 00 17 02];
 	qcom,cdc-dmic-sample-rate = <4800000>;
+	qcom,cdc-micbias2-headset-only;
 };
 
 Wcd9xxx audio CODEC in I2C mode
diff --git a/arch/arm/boot/dts/apq8084.dtsi b/arch/arm/boot/dts/apq8084.dtsi
index ba1ccd7..2543c40 100644
--- a/arch/arm/boot/dts/apq8084.dtsi
+++ b/arch/arm/boot/dts/apq8084.dtsi
@@ -165,6 +165,42 @@
 	android_usb {
 		compatible = "qcom,android-usb";
 	};
+
+	qcom,ocmem@fdd00000 {
+		compatible = "qcom,msm-ocmem";
+		reg = <0xfdd00000 0x2000>,
+		      <0xfdd02000 0x2000>,
+		      <0xfe039000 0x400>,
+		      <0xfec00000 0x200000>;
+		reg-names = "ocmem_ctrl_physical", "dm_ctrl_physical", "br_ctrl_physical", "ocmem_physical";
+		interrupts = <0 76 0 0 77 0>;
+		interrupt-names = "ocmem_irq", "dm_irq";
+		qcom,ocmem-num-regions = <0x4>;
+		qcom,ocmem-num-macros = <0x20>;
+		qcom,resource-type = <0x706d636f>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0xfec00000 0x200000>;
+
+		partition@0 {
+			reg = <0x0 0x180000>;
+			qcom,ocmem-part-name = "graphics";
+			qcom,ocmem-part-min = <0x80000>;
+		};
+
+		partition@80000 {
+			reg = <0x180000 0x80000>;
+			qcom,ocmem-part-name = "lp_audio";
+			qcom,ocmem-part-min = <0x80000>;
+		};
+
+		partition@100000 {
+			reg = <0x180000 0x80000>;
+			qcom,ocmem-part-name = "video";
+			qcom,ocmem-part-min = <0x55000>;
+		};
+
+	};
 };
 
 /include/ "msm-pma8084.dtsi"
diff --git a/arch/arm/boot/dts/msm-pm8110.dtsi b/arch/arm/boot/dts/msm-pm8110.dtsi
index 391c564..bce9806 100644
--- a/arch/arm/boot/dts/msm-pm8110.dtsi
+++ b/arch/arm/boot/dts/msm-pm8110.dtsi
@@ -22,6 +22,29 @@
 		#address-cells = <1>;
 		#size-cells = <1>;
 
+		qcom,power-on@800 {
+			compatible = "qcom,qpnp-power-on";
+			reg = <0x800 0x100>;
+			interrupts = <0x0 0x8 0x0>,
+				     <0x0 0x8 0x1>,
+				     <0x0 0x8 0x4>;
+			interrupt-names = "kpdpwr", "resin", "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>;
+			};
+		};
+
 		pm8110_chg: qcom,charger {
 			spmi-dev-container;
 			compatible = "qcom,qpnp-charger";
diff --git a/arch/arm/boot/dts/msm8226-pm.dtsi b/arch/arm/boot/dts/msm8226-pm.dtsi
index 8a1ac1d..3240efb 100644
--- a/arch/arm/boot/dts/msm8226-pm.dtsi
+++ b/arch/arm/boot/dts/msm8226-pm.dtsi
@@ -153,10 +153,10 @@
 			qcom,mode = "wfi";
 			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
+			qcom,vdd-mem-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <4>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
 			qcom,irqs-detectable;
 			qcom,gpio-detectable;
 			qcom,latency-us = <1>;
@@ -170,10 +170,10 @@
 			qcom,mode = "standalone_pc";
 			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
+			qcom,vdd-mem-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <4>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
 			qcom,irqs-detectable;
 			qcom,gpio-detectable;
 			qcom,latency-us = <3000>;
@@ -187,10 +187,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_retention";
-			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
+			qcom,vdd-mem-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <4>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
 			qcom,irqs-detectable;
 			qcom,gpio-detectable;
 			qcom,latency-us = <8000>;
@@ -204,10 +204,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <3>; /* NORMAL */
-			qcom,vdd-mem-lower-bound = <2>;  /* SVS SOC */
-			qcom,vdd-dig-upper-bound = <3>;  /* NORMAL */
-			qcom,vdd-dig-lower-bound = <2>;  /* SVS SOC */
+			qcom,vdd-mem-upper-bound = <4>; /* NORMAL */
+			qcom,vdd-mem-lower-bound = <3>;  /* SVS SOC */
+			qcom,vdd-dig-upper-bound = <4>;  /* NORMAL */
+			qcom,vdd-dig-lower-bound = <3>;  /* SVS SOC */
 			qcom,irqs-detectable;
 			qcom,gpio-detectable;
 			qcom,latency-us = <9000>;
@@ -221,10 +221,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_off";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
+			qcom,vdd-mem-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <4>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
 			qcom,latency-us = <16300>;
 			qcom,ss-power = <63>;
 			qcom,energy-overhead = <2128000>;
@@ -236,10 +236,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_off";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <3>; /* NORMAL */
-			qcom,vdd-mem-lower-bound = <2>;  /* SVS SOC */
-			qcom,vdd-dig-upper-bound = <3>;  /* NORMAL */
-			qcom,vdd-dig-lower-bound = <2>;  /* SVS SOC */
+			qcom,vdd-mem-upper-bound = <4>; /* NORMAL */
+			qcom,vdd-mem-lower-bound = <3>;  /* SVS SOC */
+			qcom,vdd-dig-upper-bound = <4>;  /* NORMAL */
+			qcom,vdd-dig-lower-bound = <3>;  /* SVS SOC */
 			qcom,latency-us = <24000>;
 			qcom,ss-power = <10>;
 			qcom,energy-overhead = <3202600>;
@@ -251,10 +251,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_off";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <2>; /* SVS SOC */
-			qcom,vdd-mem-lower-bound = <0>; /* RETENTION */
-			qcom,vdd-dig-upper-bound = <2>; /* SVS SOC */
-			qcom,vdd-dig-lower-bound = <0>; /* RETENTION */
+			qcom,vdd-mem-upper-bound = <3>; /* SVS SOC */
+			qcom,vdd-mem-lower-bound = <1>; /* RETENTION */
+			qcom,vdd-dig-upper-bound = <3>; /* SVS SOC */
+			qcom,vdd-dig-lower-bound = <1>; /* RETENTION */
 			qcom,latency-us = <26000>;
 			qcom,ss-power = <2>;
 			qcom,energy-overhead = <4252000>;
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index 6c06336..53e4392 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -980,22 +980,27 @@
 };
 
 &gdsc_venus {
+	qcom,clock-names = "core_clk";
 	status = "ok";
 };
 
 &gdsc_mdss {
+	qcom,clock-names = "core_clk", "lut_clk";
 	status = "ok";
 };
 
 &gdsc_jpeg {
+	qcom,clock-names = "core_clk";
 	status = "ok";
 };
 
 &gdsc_vfe {
+	qcom,clock-names = "core_clk", "csi_clk", "cpp_clk";
 	status = "ok";
 };
 
 &gdsc_oxili_cx {
+	qcom,clock-names = "core_clk";
 	status = "ok";
 };
 
diff --git a/arch/arm/boot/dts/msm8610-cdp.dts b/arch/arm/boot/dts/msm8610-cdp.dts
index 28e9dc5..385e045 100644
--- a/arch/arm/boot/dts/msm8610-cdp.dts
+++ b/arch/arm/boot/dts/msm8610-cdp.dts
@@ -156,7 +156,7 @@
 			qcom,led_mpp_3 {
 				label = "mpp";
 				linux,name = "wled-backlight";
-				linux-default-trigger = "none";
+				linux,default-trigger = "bkl-trigger";
 				qcom,default-state = "on";
 				qcom,max-current = <40>;
 				qcom,id = <6>;
diff --git a/arch/arm/boot/dts/msm8610-mtp.dts b/arch/arm/boot/dts/msm8610-mtp.dts
index 83e7b48..540c966 100644
--- a/arch/arm/boot/dts/msm8610-mtp.dts
+++ b/arch/arm/boot/dts/msm8610-mtp.dts
@@ -156,7 +156,7 @@
 			qcom,led_mpp_3 {
 				label = "mpp";
 				linux,name = "wled-backlight";
-				linux-default-trigger = "none";
+				linux,default-trigger = "bkl-trigger";
 				qcom,default-state = "on";
 				qcom,max-current = <40>;
 				qcom,id = <6>;
diff --git a/arch/arm/boot/dts/msm8610-pm.dtsi b/arch/arm/boot/dts/msm8610-pm.dtsi
index 34382c5..938b2aa 100644
--- a/arch/arm/boot/dts/msm8610-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-pm.dtsi
@@ -114,7 +114,7 @@
 			qcom,type = <0x61706d73>;	/* "smpa" */
 			qcom,id = <0x01>;
 			qcom,key = <0x6e726f63>;	/* "corn" */
-			qcom,init-value = <5>;		/* Super Turbo */
+			qcom,init-value = <3>;		/* SVS SOC */
 		};
 
 		qcom,lpm-resources@1 {
@@ -123,7 +123,7 @@
 			qcom,type = <0x616F646C>;	/* "ldoa" */
 			qcom,id = <0x03>;
 			qcom,key = <0x6e726f63>;	/* "corn" */
-			qcom,init-value = <3>;		/* Active */
+			qcom,init-value = <3>;		/* SVS SOC */
 		};
 
 		qcom,lpm-resources@2 {
@@ -153,10 +153,10 @@
 			qcom,mode = "wfi";
 			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
+			qcom,vdd-mem-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <4>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
 			qcom,irqs-detectable;
 			qcom,gpio-detectable;
 			qcom,latency-us = <1>;
@@ -170,10 +170,10 @@
 			qcom,mode = "standalone_pc";
 			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
+			qcom,vdd-mem-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <4>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
 			qcom,irqs-detectable;
 			qcom,gpio-detectable;
 			qcom,latency-us = <3000>;
@@ -187,10 +187,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_retention";
-			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
+			qcom,vdd-mem-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <4>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
 			qcom,irqs-detectable;
 			qcom,gpio-detectable;
 			qcom,latency-us = <8000>;
@@ -204,10 +204,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <3>; /* NORMAL */
-			qcom,vdd-mem-lower-bound = <2>;  /* SVS SOC */
-			qcom,vdd-dig-upper-bound = <3>;  /* NORMAL */
-			qcom,vdd-dig-lower-bound = <2>;  /* SVS SOC */
+			qcom,vdd-mem-upper-bound = <4>; /* NORMAL */
+			qcom,vdd-mem-lower-bound = <3>;  /* SVS SOC */
+			qcom,vdd-dig-upper-bound = <4>;  /* NORMAL */
+			qcom,vdd-dig-lower-bound = <3>;  /* SVS SOC */
 			qcom,irqs-detectable;
 			qcom,gpio-detectable;
 			qcom,latency-us = <9000>;
@@ -221,10 +221,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_off";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
-			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
-			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
-			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
+			qcom,vdd-mem-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <4>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <6>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <4>;  /* NORMAL */
 			qcom,latency-us = <16300>;
 			qcom,ss-power = <63>;
 			qcom,energy-overhead = <2128000>;
@@ -236,10 +236,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_off";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <3>; /* NORMAL */
-			qcom,vdd-mem-lower-bound = <2>;  /* SVS SOC */
-			qcom,vdd-dig-upper-bound = <3>;  /* NORMAL */
-			qcom,vdd-dig-lower-bound = <2>;  /* SVS SOC */
+			qcom,vdd-mem-upper-bound = <4>; /* NORMAL */
+			qcom,vdd-mem-lower-bound = <3>;  /* SVS SOC */
+			qcom,vdd-dig-upper-bound = <4>;  /* NORMAL */
+			qcom,vdd-dig-lower-bound = <3>;  /* SVS SOC */
 			qcom,latency-us = <24000>;
 			qcom,ss-power = <10>;
 			qcom,energy-overhead = <3202600>;
@@ -251,10 +251,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_off";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <2>; /* SVS SOC */
-			qcom,vdd-mem-lower-bound = <0>; /* RETENTION */
-			qcom,vdd-dig-upper-bound = <2>; /* SVS SOC */
-			qcom,vdd-dig-lower-bound = <0>; /* RETENTION */
+			qcom,vdd-mem-upper-bound = <3>; /* SVS SOC */
+			qcom,vdd-mem-lower-bound = <1>; /* RETENTION */
+			qcom,vdd-dig-upper-bound = <3>; /* SVS SOC */
+			qcom,vdd-dig-lower-bound = <1>; /* RETENTION */
 			qcom,latency-us = <26000>;
 			qcom,ss-power = <2>;
 			qcom,energy-overhead = <4252000>;
diff --git a/arch/arm/boot/dts/msm8610-regulator.dtsi b/arch/arm/boot/dts/msm8610-regulator.dtsi
index 9e79df1..3df428a 100644
--- a/arch/arm/boot/dts/msm8610-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8610-regulator.dtsi
@@ -44,6 +44,9 @@
 		qcom,pvs-corner-ceiling-nom  =  <975000 1075000 1200000 1200000>;
 		qcom,pvs-corner-ceiling-fast =  <900000 1000000 1140000 1140000>;
 		vdd-apc-supply = <&pm8110_s2>;
+		vdd-mx-supply = <&pm8110_l3_ao>;
+		qcom,vdd-mx-vmax = <1350000>;
+		qcom,vdd-mx-vmin-method = <1>;
 	};
 };
 
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index 72b6223..5fa7c08 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.dtsi
@@ -195,6 +195,7 @@
 		qcom,model = "msm8974-taiko-cdp-snd-card";
 		qcom,hdmi-audio-rx;
 		qcom,us-euro-gpios = <&pm8941_gpios 20 0>;
+		qcom,cdc-micbias2-headset-only;
 	};
 
 	usb2_otg_sw: regulator-tpd4s214 {
@@ -499,7 +500,7 @@
 		qcom,output-type = <0>;
 		qcom,pull = <5>;
 		qcom,vin-sel = <2>;
-		qcom,out-strength = <3>;
+		qcom,out-strength = <1>;
 		qcom,src-sel = <2>;
 		qcom,master-en = <1>;
 	};
diff --git a/arch/arm/boot/dts/msm8974-fluid.dtsi b/arch/arm/boot/dts/msm8974-fluid.dtsi
index 06b13b8..ad5f175 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-fluid.dtsi
@@ -230,6 +230,7 @@
 
 		qcom,hdmi-audio-rx;
 		qcom,ext-ult-lo-amp-gpio = <&pm8941_gpios 6 0>;
+		qcom,cdc-micbias2-headset-only;
 	};
 };
 
@@ -505,7 +506,7 @@
 		qcom,output-type = <0>;
 		qcom,pull = <5>;
 		qcom,vin-sel = <2>;
-		qcom,out-strength = <3>;
+		qcom,out-strength = <1>;
 		qcom,src-sel = <2>;
 		qcom,master-en = <1>;
 	};
diff --git a/arch/arm/boot/dts/msm8974-leds.dtsi b/arch/arm/boot/dts/msm8974-leds.dtsi
index befd206..b39cc21 100644
--- a/arch/arm/boot/dts/msm8974-leds.dtsi
+++ b/arch/arm/boot/dts/msm8974-leds.dtsi
@@ -93,6 +93,20 @@
 				linux,name = "led:flash_1";
 				qcom,current = <625>;
 			};
+
+			pm8941_torch: qcom,flash_torch {
+				qcom,max-current = <200>;
+				qcom,default-state = "off";
+				qcom,headroom = <0>;
+				qcom,startup-dly = <1>;
+				linux,default-trigger =
+					"torch_trigger";
+				label = "flash";
+				qcom,id = <2>;
+				linux,name = "led:flash_torch";
+				qcom,current = <200>;
+				qcom,torch-enable;
+			};
 		};
 
 		qcom,leds@d400 {
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index 3f4e035..e63b53b 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.dtsi
@@ -511,7 +511,7 @@
 		qcom,output-type = <0>;
 		qcom,pull = <5>;
 		qcom,vin-sel = <2>;
-		qcom,out-strength = <3>;
+		qcom,out-strength = <1>;
 		qcom,src-sel = <2>;
 		qcom,master-en = <1>;
 	};
diff --git a/arch/arm/boot/dts/msm8974-mtp.dtsi b/arch/arm/boot/dts/msm8974-mtp.dtsi
index 37286af..4d28a1d 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-mtp.dtsi
@@ -187,6 +187,7 @@
 
 	sound {
 		qcom,model = "msm8974-taiko-mtp-snd-card";
+		qcom,cdc-micbias2-headset-only;
 	};
 };
 
@@ -489,7 +490,7 @@
 		qcom,output-type = <0>;
 		qcom,pull = <5>;
 		qcom,vin-sel = <2>;
-		qcom,out-strength = <3>;
+		qcom,out-strength = <1>;
 		qcom,src-sel = <2>;
 		qcom,master-en = <1>;
 	};
diff --git a/arch/arm/configs/msm8610-perf_defconfig b/arch/arm/configs/msm8610-perf_defconfig
index 5660dec..e45024e 100644
--- a/arch/arm/configs/msm8610-perf_defconfig
+++ b/arch/arm/configs/msm8610-perf_defconfig
@@ -62,6 +62,7 @@
 CONFIG_MSM_MEMORY_DUMP=y
 CONFIG_MSM_DLOAD_MODE=y
 CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL=y
+CONFIG_MSM_BOOT_STATS=y
 CONFIG_MSM_ADSP_LOADER=m
 CONFIG_MSM_OCMEM=y
 CONFIG_MSM_OCMEM_LOCAL_POWER_CTRL=y
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index 09b038c..bff59db 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -69,6 +69,7 @@
 CONFIG_MSM_RTB=y
 CONFIG_MSM_RTB_SEPARATE_CPUS=y
 CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL=y
+CONFIG_MSM_BOOT_STATS=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_SMP=y
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index 27bfcac..9bb6e80 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -3279,6 +3279,15 @@
 	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd928000.qcom,iommu"),
 	CLK_LOOKUP("core_clk", mdss_axi_clk.c, "fd928000.qcom,iommu"),
 
+	CLK_LOOKUP("core_clk", venus0_vcodec0_clk.c, "fd8c1024.qcom,gdsc"),
+	CLK_LOOKUP("core_clk", mdss_mdp_clk.c, "fd8c2304.qcom,gdsc"),
+	CLK_LOOKUP("lut_clk", mdss_mdp_lut_clk.c, "fd8c2304.qcom,gdsc"),
+	CLK_LOOKUP("core_clk", camss_jpeg_jpeg0_clk.c, "fd8c35a4.qcom,gdsc"),
+	CLK_LOOKUP("core_clk", camss_vfe_vfe0_clk.c,	"fd8c36a4.qcom,gdsc"),
+	CLK_LOOKUP("csi_clk", camss_csi_vfe0_clk.c,	"fd8c36a4.qcom,gdsc"),
+	CLK_LOOKUP("cpp_clk", camss_vfe_cpp_clk.c,	"fd8c36a4.qcom,gdsc"),
+	CLK_LOOKUP("core_clk", oxili_gfx3d_clk.c, "fd8c4034.qcom,gdsc"),
+
 	/* MM sensor clocks */
 	CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6f.qcom,camera"),
 	CLK_LOOKUP("cam_src_clk", mclk1_clk_src.c, "90.qcom,camera"),
diff --git a/drivers/crypto/msm/qcryptohw_50.h b/drivers/crypto/msm/qcryptohw_50.h
index 2210dc8..1be2702 100644
--- a/drivers/crypto/msm/qcryptohw_50.h
+++ b/drivers/crypto/msm/qcryptohw_50.h
@@ -379,7 +379,7 @@
 #define CRYPTO_FIRST				17
 #define CRYPTO_LAST				16
 
-#define CRYPTO_AUTH_POS				15 /* bit 15 .. 14*/
+#define CRYPTO_AUTH_POS				14 /* bit 15 .. 14*/
 #define CRYPTO_AUTH_POS_MASK			(0x3 << CRYPTO_AUTH_POS)
 #define CRYPTO_AUTH_POS_BEFORE			0
 #define CRYPTO_AUTH_POS_AFTER			1
diff --git a/drivers/input/touchscreen/synaptics_fw_update.c b/drivers/input/touchscreen/synaptics_fw_update.c
index dbe378c..d51481f 100644
--- a/drivers/input/touchscreen/synaptics_fw_update.c
+++ b/drivers/input/touchscreen/synaptics_fw_update.c
@@ -107,6 +107,9 @@
 		struct kobject *kobj, struct bin_attribute *attributes,
 		char *buf, loff_t pos, size_t count);
 
+static ssize_t fwu_sysfs_force_reflash_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
 static ssize_t fwu_sysfs_do_reflash_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count);
 
@@ -301,6 +304,9 @@
 };
 
 static struct device_attribute attrs[] = {
+	__ATTR(forceflash, S_IWUGO,
+			synaptics_rmi4_show_error,
+			fwu_sysfs_force_reflash_store),
 	__ATTR(doreflash, S_IWUGO,
 			synaptics_rmi4_show_error,
 			fwu_sysfs_do_reflash_store),
@@ -1462,6 +1468,40 @@
 	return count;
 }
 
+static ssize_t fwu_sysfs_force_reflash_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int retval;
+	unsigned int input;
+	struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
+
+	if (sscanf(buf, "%u", &input) != 1) {
+		retval = -EINVAL;
+		goto exit;
+	}
+
+	if (input != 1) {
+		retval = -EINVAL;
+		goto exit;
+	}
+
+	fwu->force_update = true;
+	retval = synaptics_fw_updater(fwu->ext_data_source);
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to do reflash\n",
+				__func__);
+		goto exit;
+	}
+
+	retval = count;
+
+exit:
+	kfree(fwu->ext_data_source);
+	fwu->ext_data_source = NULL;
+	return retval;
+}
+
 static ssize_t fwu_sysfs_do_reflash_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index 5d5ff43..0233e18 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -93,6 +93,7 @@
 #define FLASH_LED_STROBE_CTRL(base)	(base + 0x47)
 #define FLASH_LED_UNLOCK_SECURE(base)	(base + 0xD0)
 #define FLASH_LED_TORCH(base)		(base + 0xE4)
+#define FLASH_FAULT_DETECT(base)	(base + 0x51)
 
 #define FLASH_MAX_LEVEL			0x4F
 #define	FLASH_NO_MASK			0x00
@@ -106,10 +107,9 @@
 #define FLASH_TMR_MASK			0x03
 #define FLASH_TMR_WATCHDOG		0x03
 #define FLASH_TMR_SAFETY		0x00
-
+#define FLASH_FAULT_DETECT_MASK		0X80
 #define FLASH_HW_VREG_OK		0x80
 #define FLASH_VREG_MASK			0xC0
-
 #define FLASH_STARTUP_DLY_MASK		0x02
 
 #define FLASH_ENABLE_ALL		0xE0
@@ -120,6 +120,7 @@
 #define FLASH_ENABLE_LED_0		0x40
 #define FLASH_ENABLE_LED_1		0x20
 #define FLASH_INIT_MASK			0xE0
+#define	FLASH_SELFCHECK_ENABLE		0x80
 
 #define FLASH_STROBE_SW			0xC0
 #define FLASH_STROBE_HW			0xC4
@@ -130,7 +131,7 @@
 #define FLASH_CURRENT_PRGM_MIN		1
 #define FLASH_CURRENT_PRGM_SHIFT	1
 #define FLASH_CURRENT_MAX		0x4F
-#define FLASH_CURRENT_TORCH		0x0F
+#define FLASH_CURRENT_TORCH		0x07
 
 #define FLASH_DURATION_200ms		0x13
 #define FLASH_CLAMP_200mA		0x0F
@@ -171,6 +172,8 @@
 #define LED_MPP_SINK_MASK		0x07
 #define LED_MPP_MODE_MASK		0x7F
 #define LED_MPP_EN_MASK			0x80
+#define LED_MPP_SRC_MASK		0x0F
+#define LED_MPP_MODE_CTRL_MASK		0x70
 
 #define LED_MPP_MODE_SINK		(0x06 << 4)
 #define LED_MPP_MODE_ENABLE		0x01
@@ -551,7 +554,8 @@
 			return rc;
 		}
 
-		val = led->mpp_cfg->source_sel | led->mpp_cfg->mode_ctrl;
+		val = (led->mpp_cfg->source_sel & LED_MPP_SRC_MASK) |
+			(led->mpp_cfg->mode_ctrl & LED_MPP_MODE_CTRL_MASK);
 
 		rc = qpnp_led_masked_write(led,
 		LED_MPP_MODE_CTRL(led->base), LED_MPP_MODE_MASK,
@@ -632,18 +636,10 @@
 				return rc;
 			}
 
-			qpnp_led_masked_write(led, FLASH_MAX_CURR(led->base),
-				FLASH_CURRENT_MASK, FLASH_CURRENT_TORCH);
-			if (rc) {
-				dev_err(&led->spmi_dev->dev,
-					"Max current reg write failed(%d)\n",
-					rc);
-				return rc;
-			}
-
 			rc = qpnp_led_masked_write(led,
 				led->flash_cfg->current_addr,
-				FLASH_CURRENT_MASK, FLASH_CURRENT_TORCH);
+				FLASH_CURRENT_MASK,
+				led->flash_cfg->current_prgm);
 			if (rc) {
 				dev_err(&led->spmi_dev->dev,
 					"Current reg write failed(%d)\n", rc);
@@ -652,7 +648,8 @@
 
 			rc = qpnp_led_masked_write(led,
 				led->flash_cfg->second_addr,
-				FLASH_CURRENT_MASK, FLASH_CURRENT_TORCH);
+				FLASH_CURRENT_MASK,
+				led->flash_cfg->current_prgm);
 			if (rc) {
 				dev_err(&led->spmi_dev->dev,
 					"2nd Current reg write failed(%d)\n",
@@ -660,6 +657,16 @@
 				return rc;
 			}
 
+			qpnp_led_masked_write(led, FLASH_MAX_CURR(led->base),
+				FLASH_CURRENT_MASK,
+				led->max_current);
+			if (rc) {
+				dev_err(&led->spmi_dev->dev,
+					"Max current reg write failed(%d)\n",
+					rc);
+				return rc;
+			}
+
 			rc = qpnp_led_masked_write(led,
 				FLASH_ENABLE_CONTROL(led->base),
 				FLASH_ENABLE_MODULE_MASK, FLASH_ENABLE_MODULE);
@@ -669,9 +676,22 @@
 				return rc;
 			}
 		} else {
+			/* Set flash safety timer */
 			rc = qpnp_led_masked_write(led,
-				FLASH_MAX_CURR(led->base),
-				FLASH_CURRENT_MASK, FLASH_CURRENT_MAX);
+				FLASH_SAFETY_TIMER(led->base),
+				FLASH_SAFETY_TIMER_MASK,
+				led->flash_cfg->duration);
+			if (rc) {
+				dev_err(&led->spmi_dev->dev,
+					"Safety timer reg write failed(%d)\n",
+					rc);
+				return rc;
+			}
+
+			/* Set max current */
+			rc = qpnp_led_masked_write(led,
+				FLASH_MAX_CURR(led->base), FLASH_CURRENT_MASK,
+				FLASH_MAX_LEVEL);
 			if (rc) {
 				dev_err(&led->spmi_dev->dev,
 					"Max current reg write failed(%d)\n",
@@ -679,6 +699,18 @@
 				return rc;
 			}
 
+			/* Set clamp current */
+			rc = qpnp_led_masked_write(led,
+				FLASH_CLAMP_CURR(led->base),
+				FLASH_CURRENT_MASK,
+				led->flash_cfg->clamp_curr);
+			if (rc) {
+				dev_err(&led->spmi_dev->dev,
+					"Clamp current reg write failed(%d)\n",
+					rc);
+				return rc;
+			}
+
 			/* Write 0x80 to MODULE_ENABLE before writing 0xE0
 			 * in order to avoid reg value goes from 0x00 to
 			 * 0xE0. This causes a hardware bug.
@@ -714,16 +746,6 @@
 			}
 
 			rc = qpnp_led_masked_write(led,
-				FLASH_CLAMP_CURR(led->base),
-				FLASH_CURRENT_MASK, FLASH_CURRENT_TORCH);
-			if (rc) {
-				dev_err(&led->spmi_dev->dev,
-					"Clamp Current reg write failed(%d)\n",
-					rc);
-				return rc;
-			}
-
-			rc = qpnp_led_masked_write(led,
 				FLASH_ENABLE_CONTROL(led->base),
 				FLASH_ENABLE_MASK, FLASH_ENABLE_ALL);
 			if (rc) {
@@ -762,25 +784,16 @@
 			if (rc) {
 				dev_err(&led->spmi_dev->dev,
 					"Secure reg write failed(%d)\n", rc);
-			}
-
-			rc = qpnp_led_masked_write(led,
-				FLASH_LED_TORCH(led->base),
-				FLASH_TORCH_MASK, FLASH_LED_TORCH_DISABLE);
-			if (rc) {
-				dev_err(&led->spmi_dev->dev,
-					"Torch reg write failed(%d)\n", rc);
 				return rc;
 			}
 
 			rc = qpnp_led_masked_write(led,
-				FLASH_SAFETY_TIMER(led->base),
-				FLASH_SAFETY_TIMER_MASK,
-				led->flash_cfg->duration);
+					FLASH_LED_TORCH(led->base),
+					FLASH_TORCH_MASK,
+					FLASH_LED_TORCH_DISABLE);
 			if (rc) {
 				dev_err(&led->spmi_dev->dev,
-					"Safety timer reg write failed(%d)\n",
-					rc);
+					"Torch reg write failed(%d)\n", rc);
 				return rc;
 			}
 		}
@@ -936,6 +949,7 @@
 		if (rc < 0)
 			dev_err(&led->spmi_dev->dev,
 					"MPP set brightness failed (%d)\n", rc);
+		break;
 	case QPNP_ID_KPDBL:
 		rc = qpnp_kpdbl_set(led);
 		if (rc < 0)
@@ -1208,52 +1222,7 @@
 			"LED %d flash write failed(%d)\n", led->id, rc);
 		return rc;
 	}
-	rc = qpnp_led_masked_write(led, FLASH_ENABLE_CONTROL(led->base),
-		FLASH_INIT_MASK, FLASH_ENABLE_MODULE);
-	if (rc) {
-		dev_err(&led->spmi_dev->dev,
-			"Enable reg write failed(%d)\n", rc);
-		return rc;
-	}
 
-	/* Set flash safety timer */
-	rc = qpnp_led_masked_write(led, FLASH_SAFETY_TIMER(led->base),
-		FLASH_SAFETY_TIMER_MASK, led->flash_cfg->duration);
-	if (rc) {
-		dev_err(&led->spmi_dev->dev,
-			"Safety timer reg write failed(%d)\n", rc);
-		return rc;
-	}
-
-	/* Set max current */
-	rc = qpnp_led_masked_write(led, FLASH_MAX_CURR(led->base),
-		FLASH_CURRENT_MASK, FLASH_MAX_LEVEL);
-	if (rc) {
-		dev_err(&led->spmi_dev->dev,
-			"Max current reg write failed(%d)\n", rc);
-		return rc;
-	}
-	/* Set clamp current */
-	rc = qpnp_led_masked_write(led, FLASH_CLAMP_CURR(led->base),
-		FLASH_CURRENT_MASK, led->flash_cfg->clamp_curr);
-	if (rc) {
-		dev_err(&led->spmi_dev->dev,
-			"Clamp current reg write failed(%d)\n", rc);
-		return rc;
-	}
-
-	/* Set timer control - safety or watchdog */
-	if (led->flash_cfg->safety_timer)
-		rc = qpnp_led_masked_write(led, FLASH_LED_TMR_CTRL(led->base),
-			FLASH_TMR_MASK, FLASH_TMR_SAFETY);
-	else
-		rc = qpnp_led_masked_write(led, FLASH_LED_TMR_CTRL(led->base),
-			FLASH_TMR_MASK, FLASH_TMR_WATCHDOG);
-	if (rc) {
-		dev_err(&led->spmi_dev->dev,
-			"LED timer ctrl reg write failed(%d)\n", rc);
-		return rc;
-	}
 	/* Set headroom */
 	rc = qpnp_led_masked_write(led, FLASH_HEADROOM(led->base),
 		FLASH_HEADROOM_MASK, led->flash_cfg->headroom);
@@ -1263,6 +1232,47 @@
 		return rc;
 	}
 
+	/* Set startup delay */
+	rc = qpnp_led_masked_write(led,
+		FLASH_STARTUP_DELAY(led->base), FLASH_STARTUP_DLY_MASK,
+		led->flash_cfg->startup_dly);
+	if (rc) {
+		dev_err(&led->spmi_dev->dev,
+			"Startup delay reg write failed(%d)\n", rc);
+		return rc;
+	}
+
+	/* Set timer control - safety or watchdog */
+	if (led->flash_cfg->safety_timer) {
+		rc = qpnp_led_masked_write(led,
+			FLASH_LED_TMR_CTRL(led->base),
+			FLASH_TMR_MASK, FLASH_TMR_SAFETY);
+		if (rc) {
+			dev_err(&led->spmi_dev->dev,
+				"LED timer ctrl reg write failed(%d)\n",
+				rc);
+			return rc;
+		}
+	}
+
+	/* Set Vreg force */
+	rc = qpnp_led_masked_write(led,	FLASH_VREG_OK_FORCE(led->base),
+		FLASH_VREG_MASK, FLASH_HW_VREG_OK);
+	if (rc) {
+		dev_err(&led->spmi_dev->dev,
+			"Vreg OK reg write failed(%d)\n", rc);
+		return rc;
+	}
+
+	/* Set self fault check */
+	rc = qpnp_led_masked_write(led, FLASH_FAULT_DETECT(led->base),
+		FLASH_FAULT_DETECT_MASK, FLASH_SELFCHECK_ENABLE);
+	if (rc) {
+		dev_err(&led->spmi_dev->dev,
+			"Fault detect reg write failed(%d)\n", rc);
+		return rc;
+	}
+
 	/* Set mask enable */
 	rc = qpnp_led_masked_write(led, FLASH_MASK_ENABLE(led->base),
 		FLASH_MASK_REG_MASK, FLASH_MASK_1);
@@ -1272,32 +1282,7 @@
 		return rc;
 	}
 
-	/* Set startup delay */
-	rc = qpnp_led_masked_write(led, FLASH_STARTUP_DELAY(led->base),
-		FLASH_STARTUP_DLY_MASK, led->flash_cfg->startup_dly);
-	if (rc) {
-		dev_err(&led->spmi_dev->dev,
-			"Startup delay reg write failed(%d)\n", rc);
-		return rc;
-	}
-
-	rc = qpnp_led_masked_write(led, FLASH_VREG_OK_FORCE(led->base),
-		FLASH_VREG_MASK, FLASH_HW_VREG_OK);
-	if (rc) {
-		dev_err(&led->spmi_dev->dev,
-			"Vreg OK reg write failed(%d)\n", rc);
-		return rc;
-	}
-
-	/* Set led current and disable module */
-	rc = qpnp_led_masked_write(led, led->flash_cfg->current_addr,
-		FLASH_CURRENT_MASK, led->flash_cfg->current_prgm);
-	if (rc) {
-		dev_err(&led->spmi_dev->dev,
-			"Current reg write failed(%d)\n", rc);
-		return rc;
-	}
-
+	/* Disable flash LED module */
 	rc = qpnp_led_masked_write(led, FLASH_ENABLE_CONTROL(led->base),
 		FLASH_ENABLE_MODULE_MASK, FLASH_DISABLE_ALL);
 	if (rc) {
@@ -1306,7 +1291,6 @@
 		return rc;
 	}
 
-	led->flash_cfg->torch_enable = false;
 	led->flash_cfg->strobe_type = 0;
 
 	/* dump flash registers */
@@ -1679,6 +1663,9 @@
 	led->flash_cfg->safety_timer =
 		of_property_read_bool(node, "qcom,safety-timer");
 
+	led->flash_cfg->torch_enable =
+		of_property_read_bool(node, "qcom,torch-enable");
+
 	return 0;
 }
 
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
index 731056b..756cb41 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -520,26 +520,37 @@
 	comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40);
 	comp_mask &= ~(0x7F << (comp_mask_index * 8));
 	comp_mask |= (axi_data->composite_info[comp_mask_index].
-	stream_composite_mask << (comp_mask_index * 8));
+		stream_composite_mask << (comp_mask_index * 8));
+	if (stream_info->plane_offset[0])
+		comp_mask |= (axi_data->composite_info[comp_mask_index].
+		stream_composite_mask << 24);
 	msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40);
 
 	irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28);
 	irq_mask |= 1 << (comp_mask_index + 25);
+	if (stream_info->plane_offset[0] && (comp_mask >> 24))
+		irq_mask |= BIT(28);
 	msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28);
 }
 
 static void msm_vfe40_axi_clear_comp_mask(struct vfe_device *vfe_dev,
 	struct msm_vfe_axi_stream *stream_info)
 {
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
 	uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index;
 	uint32_t irq_mask;
 
 	comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40);
 	comp_mask &= ~(0x7F << (comp_mask_index * 8));
+	if (stream_info->plane_offset[0])
+		comp_mask &= ~(axi_data->composite_info[comp_mask_index].
+		stream_composite_mask << 24);
 	msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40);
 
 	irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28);
 	irq_mask &= ~(1 << (comp_mask_index + 25));
+	if (stream_info->plane_offset[0] && !(comp_mask >> 24))
+		irq_mask &= ~BIT(28);
 	msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28);
 }
 
@@ -1219,7 +1230,7 @@
 
 static struct msm_vfe_axi_hardware_info msm_vfe40_axi_hw_info = {
 	.num_wm = 4,
-	.num_comp_mask = 4,
+	.num_comp_mask = 3,
 	.num_rdi = 3,
 	.num_rdi_master = 3,
 	.min_wm_ub = 64,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
index 47e672d..3dd3a4e 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
@@ -42,13 +42,13 @@
 			e_ctrl->eboard_info->eeprom_name,
 			sizeof(cdata->cfg.eeprom_name));
 		break;
-	case CFG_EEPROM_GET_DATA:
-		CDBG("%s E CFG_EEPROM_GET_DATA\n", __func__);
+	case CFG_EEPROM_GET_CAL_DATA:
+		CDBG("%s E CFG_EEPROM_GET_CAL_DATA\n", __func__);
 		cdata->cfg.get_data.num_bytes =
 			e_ctrl->num_bytes;
 		break;
-	case CFG_EEPROM_READ_DATA:
-		CDBG("%s E CFG_EEPROM_READ_DATA\n", __func__);
+	case CFG_EEPROM_READ_CAL_DATA:
+		CDBG("%s E CFG_EEPROM_READ_CAL_DATA\n", __func__);
 		rc = copy_to_user(cdata->cfg.read_data.dbuffer,
 			e_ctrl->memory_data,
 			cdata->cfg.read_data.num_bytes);
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 1611a09..62f09d0 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -697,32 +697,43 @@
 }
 int msm_vdec_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a)
 {
-	u32 us_per_frame = 0;
-	int rc = 0;
+	u64 us_per_frame = 0;
+	int rc = 0, fps = 0, rem = 0;
 	if (a->parm.output.timeperframe.denominator) {
 		switch (a->type) {
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-			us_per_frame = a->parm.output.timeperframe.numerator/
-				a->parm.output.timeperframe.denominator;
-			break;
 		case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-			us_per_frame = a->parm.capture.timeperframe.numerator/
-				a->parm.capture.timeperframe.denominator;
+		case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+			us_per_frame = a->parm.output.timeperframe.numerator *
+				(u64)USEC_PER_SEC;
+			do_div(us_per_frame, a->parm.output.\
+					timeperframe.denominator);
 			break;
 		default:
 			dprintk(VIDC_ERR,
-				"Scale clocks : Unknown buffer type\n");
+					"Scale clocks : Unknown buffer type %d\n",
+					a->type);
 			break;
 		}
 	}
+
 	if (!us_per_frame) {
 		dprintk(VIDC_ERR,
-				"Failed to scale clocks : time between frames is 0\n");
+			"Failed to scale clocks : time between frames is 0\n");
 		rc = -EINVAL;
 		goto exit;
 	}
-	inst->prop.fps = (u8) (USEC_PER_SEC / us_per_frame);
-	if (inst->prop.fps) {
+
+	fps = USEC_PER_SEC;
+	rem = do_div(fps, us_per_frame);
+	if (rem) {
+		/* Effectively fps = ceil((float)USEC_PER_SEC/us_per_frame) */
+		fps++;
+	}
+
+	if (inst->prop.fps != fps) {
+		dprintk(VIDC_PROF, "reported fps changed for %p: %d->%d\n",
+				inst, inst->prop.fps, fps);
+		inst->prop.fps = fps;
 		msm_comm_scale_clocks_and_bus(inst);
 	}
 exit:
@@ -1191,7 +1202,6 @@
 	inst->capability.width.min = MIN_SUPPORTED_WIDTH;
 	inst->capability.width.max = DEFAULT_WIDTH;
 	inst->prop.fps = 30;
-	inst->prop.prev_time_stamp = 0;
 	return rc;
 }
 
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 66a3b6e..b6e77dc 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -1970,7 +1970,7 @@
 {
 	u32 property_id = 0, us_per_frame = 0;
 	void *pdata;
-	int rc = 0;
+	int rc = 0, fps = 0, rem = 0;
 	struct hal_frame_rate frame_rate;
 	struct hfi_device *hdev;
 
@@ -1978,32 +1978,45 @@
 		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
 		return -EINVAL;
 	}
-	hdev = inst->core->device;
 
+	hdev = inst->core->device;
 	property_id = HAL_CONFIG_FRAME_RATE;
+
 	if (a->parm.output.timeperframe.denominator) {
 		switch (a->type) {
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
 		case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
 			us_per_frame = a->parm.output.timeperframe.numerator *
-				USEC_PER_SEC / a->parm.output.\
-				timeperframe.denominator;
+				(u64)USEC_PER_SEC;
+			do_div(us_per_frame, a->parm.output.\
+					timeperframe.denominator);
 			break;
 		default:
 			dprintk(VIDC_ERR,
-				"Scale clocks : Unknown buffer type\n");
+					"Scale clocks : Unknown buffer type %d\n",
+					a->type);
 			break;
 		}
 	}
 
 	if (!us_per_frame) {
 		dprintk(VIDC_ERR,
-			"Failed to scale clocks : time between frames is 0\n");
+				"Failed to scale clocks : time between frames is 0\n");
 		rc = -EINVAL;
 		goto exit;
 	}
-	inst->prop.fps = (u8) (USEC_PER_SEC / us_per_frame);
-	if (inst->prop.fps) {
+
+	fps = USEC_PER_SEC;
+	rem = do_div(fps, us_per_frame);
+	if (rem) {
+		/* Effectively fps = ceil((float)USEC_PER_SEC/us_per_frame) */
+		fps++;
+	}
+
+	if (inst->prop.fps != fps) {
+		dprintk(VIDC_PROF, "reported fps changed for %p: %d->%d\n",
+				inst, inst->prop.fps, fps);
+		inst->prop.fps = fps;
 		frame_rate.frame_rate = inst->prop.fps * (0x1<<16);
 		frame_rate.buffer_type = HAL_BUFFER_OUTPUT;
 		pdata = &frame_rate;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index eb5a03c..bd4854c 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -47,8 +47,6 @@
 	__mbs;\
 })
 
-#define TIME_DIFF_THRESHOLD 200
-
 static int msm_comm_get_load(struct msm_vidc_core *core,
 	enum session_type type)
 {
@@ -638,56 +636,6 @@
 	}
 }
 
-static void msm_comm_update_clocks(struct msm_vidc_inst *inst,
-	u64 cur_time_stamp)
-{
-	u32 new_time_diff = 0, cur_time_diff = 0;
-	u8 updated_fps = 0;
-	struct v4l2_ctrl *ctrl = NULL;
-	u32 output_order = 0;
-
-	if (inst->session_type == MSM_VIDC_ENCODER)
-		goto exit;
-	if (cur_time_stamp >= LLONG_MAX) {
-		dprintk(VIDC_DBG,
-			"Clock scaling failed : Timestamp invalid\n");
-		goto exit;
-	}
-	ctrl = v4l2_ctrl_find(&inst->ctrl_handler,
-		V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER);
-	if (!ctrl) {
-		dprintk(VIDC_WARN, "Unable to find output order control\n");
-		dprintk(VIDC_WARN,
-			"Performance might be impacted for higher fps clips\n");
-		goto exit;
-	}
-	output_order = v4l2_ctrl_g_ctrl(ctrl);
-	if (output_order == V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY) {
-		new_time_diff =
-			(u32)(cur_time_stamp - inst->prop.prev_time_stamp);
-		inst->prop.prev_time_stamp = cur_time_stamp;
-		if (!new_time_diff)
-			goto exit;
-		if (inst->prop.fps)
-			cur_time_diff = USEC_PER_SEC / inst->prop.fps;
-		cur_time_diff = cur_time_diff > new_time_diff ?
-			cur_time_diff - new_time_diff :
-			new_time_diff - cur_time_diff;
-		if (cur_time_diff > TIME_DIFF_THRESHOLD) {
-			updated_fps = (u8) (USEC_PER_SEC / new_time_diff);
-			if (updated_fps && (updated_fps != inst->prop.fps)) {
-				inst->prop.fps = updated_fps;
-				dprintk(VIDC_DBG,
-						"Updating clocks: Decoding fps = %d\n",
-						inst->prop.fps);
-				msm_comm_scale_clocks_and_bus(inst);
-			}
-		}
-	}
-exit:
-	return;
-}
-
 static void handle_fbd(enum command_response cmd, void *data)
 {
 	struct msm_vidc_cb_data_done *response = data;
@@ -717,7 +665,6 @@
 				fill_buf_done->timestamp_lo;
 			vb->v4l2_buf.timestamp =
 				ns_to_timeval(time_usec * NSEC_PER_USEC);
-				msm_comm_update_clocks(inst, time_usec);
 		}
 		vb->v4l2_buf.flags = 0;
 
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index e5696be..d9a2332 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -130,7 +130,6 @@
 	u32 height;
 	u32 fps;
 	u32 bitrate;
-	u64 prev_time_stamp;
 };
 
 struct buf_queue {
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index 046faac..130ff48 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -70,8 +70,7 @@
 static int wcd9xxx_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
 		       int bytes, void *dest, bool interface_reg)
 {
-	int ret;
-	u8 *buf = dest;
+	int i, ret;
 
 	if (bytes <= 0) {
 		dev_err(wcd9xxx->dev, "Invalid byte read length %d\n", bytes);
@@ -82,9 +81,11 @@
 	if (ret < 0) {
 		dev_err(wcd9xxx->dev, "Codec read failed\n");
 		return ret;
-	} else
-		dev_dbg(wcd9xxx->dev, "Read 0x%02x from 0x%x\n",
-			 *buf, reg);
+	} else {
+		for (i = 0; i < bytes; i++)
+			dev_dbg(wcd9xxx->dev, "Read 0x%02x from 0x%x\n",
+				((u8 *)dest)[i], reg + i);
+	}
 
 	return 0;
 }
@@ -107,15 +108,16 @@
 static int wcd9xxx_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
 			int bytes, void *src, bool interface_reg)
 {
-	u8 *buf = src;
+	int i;
 
 	if (bytes <= 0) {
 		pr_err("%s: Error, invalid write length\n", __func__);
 		return -EINVAL;
 	}
 
-	dev_dbg(wcd9xxx->dev, "Write %02x to 0x%x\n",
-		 *buf, reg);
+	for (i = 0; i < bytes; i++)
+		dev_dbg(wcd9xxx->dev, "Write %02x to 0x%x\n", ((u8 *)src)[i],
+			reg + i);
 
 	return wcd9xxx->write_dev(wcd9xxx, reg, bytes, src, interface_reg);
 }
@@ -1147,6 +1149,10 @@
 	    (of_property_read_bool(dev->of_node, "qcom,cdc-micbias4-ext-cap") ?
 	     MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);
 
+	micbias->bias2_is_headset_only =
+	    of_property_read_bool(dev->of_node,
+				  "qcom,cdc-micbias2-headset-only");
+
 	dev_dbg(dev, "ldoh_v  %u cfilt1_mv %u cfilt2_mv %u cfilt3_mv %u",
 		(u32)micbias->ldoh_v, (u32)micbias->cfilt1_mv,
 		(u32)micbias->cfilt2_mv, (u32)micbias->cfilt3_mv);
@@ -1162,6 +1168,8 @@
 	dev_dbg(dev, "bias3_ext_cap %d bias4_ext_cap %d\n",
 		micbias->bias3_cap_mode, micbias->bias4_cap_mode);
 
+	dev_dbg(dev, "bias2_is_headset_only %d\n",
+		micbias->bias2_is_headset_only);
 	return 0;
 }
 
diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c
index a0179cb..86ae8db 100644
--- a/drivers/slimbus/slim-msm-ngd.c
+++ b/drivers/slimbus/slim-msm-ngd.c
@@ -471,6 +471,8 @@
 	DECLARE_COMPLETION_ONSTACK(done);
 	u8 wbuf[SLIM_RX_MSGQ_BUF_LEN];
 
+	*clkgear = ctrl->clkgear;
+	*subfrmc = 0;
 	txn.mt = SLIM_MSG_MT_DEST_REFERRED_USER;
 	txn.dt = SLIM_MSG_DEST_LOGICALADDR;
 	txn.la = SLIM_LA_MGR;
@@ -479,6 +481,34 @@
 	txn.wbuf = wbuf;
 	txn.rbuf = NULL;
 
+	if (ctrl->sched.msgsl != ctrl->sched.pending_msgsl) {
+		pr_debug("slim reserve BW for messaging: req: %d",
+				ctrl->sched.pending_msgsl);
+		txn.mc = SLIM_USR_MC_REQ_BW;
+		wbuf[txn.len++] = ((sb->laddr & 0x1f) |
+				((u8)(ctrl->sched.pending_msgsl & 0x7) << 5));
+		wbuf[txn.len++] = (u8)(ctrl->sched.pending_msgsl >> 3);
+		ret = ngd_get_tid(ctrl, &txn, &wbuf[txn.len++], &done);
+		if (ret)
+			return ret;
+		txn.rl = txn.len + 4;
+		ret = ngd_xferandwait_ack(ctrl, &txn);
+		if (ret)
+			return ret;
+
+		txn.mc = SLIM_USR_MC_RECONFIG_NOW;
+		txn.len = 2;
+		wbuf[1] = sb->laddr;
+		txn.rl = txn.len + 4;
+		ret = ngd_get_tid(ctrl, &txn, &wbuf[0], &done);
+		if (ret)
+			return ret;
+		ret = ngd_xferandwait_ack(ctrl, &txn);
+		if (ret)
+			return ret;
+
+		txn.len = 0;
+	}
 	list_for_each_entry(pch, &sb->mark_define, pending) {
 		struct slim_ich *slc;
 		slc = &ctrl->chans[pch->chan];
@@ -1039,8 +1069,6 @@
 	dev->ctrl.config_port = msm_config_port;
 	dev->ctrl.port_xfer = msm_slim_port_xfer;
 	dev->ctrl.port_xfer_status = msm_slim_port_xfer_status;
-	/* Reserve some messaging BW for satellite-apps driver communication */
-	dev->ctrl.sched.pending_msgsl = 30;
 	dev->bam_mem = bam_mem;
 
 	init_completion(&dev->reconf);
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index a650522..122dcb9 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -465,7 +465,7 @@
 				u32 *copyback);
 int mdss_mdp_igc_lut_config(struct mdss_mdp_ctl *ctl,
 				struct mdp_igc_lut_data *config,
-				u32 *copyback);
+				u32 *copyback, u32 copy_from_kernel);
 int mdss_mdp_argc_config(struct mdss_mdp_ctl *ctl,
 				struct mdp_pgc_lut_data *config,
 				u32 *copyback);
@@ -536,6 +536,7 @@
 u32 mdss_mdp_fb_stride(u32 fb_index, u32 xres, int bpp);
 
 int mdss_panel_register_done(struct mdss_panel_data *pdata);
+int mdss_mdp_limited_lut_igc_config(struct mdss_mdp_ctl *ctl);
 
 #define mfd_to_mdp5_data(mfd) (mfd->mdp.private1)
 #define mfd_to_mdata(mfd) (((struct mdss_overlay_private *)\
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index b2147c3..e346082 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -248,13 +248,14 @@
 	return ret;
 }
 
-static struct mdss_mdp_ctl *mdss_mdp_ctl_alloc(struct mdss_data_type *mdata)
+static struct mdss_mdp_ctl *mdss_mdp_ctl_alloc(struct mdss_data_type *mdata,
+					       u32 off)
 {
 	struct mdss_mdp_ctl *ctl = NULL;
-	int cnum;
+	u32 cnum;
 
 	mutex_lock(&mdss_mdp_ctl_lock);
-	for (cnum = 0; cnum < mdata->nctl; cnum++) {
+	for (cnum = off; cnum < mdata->nctl; cnum++) {
 		ctl = mdata->ctl_off + cnum;
 		if (ctl->ref_cnt == 0) {
 			ctl->ref_cnt++;
@@ -391,7 +392,7 @@
 	struct mdss_mdp_ctl *ctl = NULL;
 	struct mdss_mdp_mixer *mixer = NULL;
 
-	ctl = mdss_mdp_ctl_alloc(mdss_res);
+	ctl = mdss_mdp_ctl_alloc(mdss_res, mdss_res->nmixers_intf);
 	if (!ctl)
 		return NULL;
 
@@ -669,7 +670,7 @@
 	int ret = 0;
 
 	struct mdss_data_type *mdata = mfd_to_mdata(mfd);
-	ctl = mdss_mdp_ctl_alloc(mdata);
+	ctl = mdss_mdp_ctl_alloc(mdata, MDSS_MDP_CTL0);
 	if (!ctl) {
 		pr_err("unable to allocate ctl\n");
 		return ERR_PTR(-ENOMEM);
@@ -711,6 +712,9 @@
 		ctl->intf_type = MDSS_INTF_HDMI;
 		ctl->opmode = MDSS_MDP_CTL_OP_VIDEO_MODE;
 		ctl->start_fnc = mdss_mdp_video_start;
+		ret = mdss_mdp_limited_lut_igc_config(ctl);
+		if (ret)
+			pr_err("Unable to config IGC LUT data");
 		break;
 	case WRITEBACK_PANEL:
 		ctl->intf_num = MDSS_MDP_NO_INTF;
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 56fd163..26c6934 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -1467,6 +1467,7 @@
 	int ret;
 	struct msmfb_mdp_pp mdp_pp;
 	u32 copyback = 0;
+	u32 copy_from_kernel = 0;
 	struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
 
 	ret = copy_from_user(&mdp_pp, argp, sizeof(mdp_pp));
@@ -1493,7 +1494,7 @@
 					mdp5_data->ctl,
 					(struct mdp_igc_lut_data *)
 					&mdp_pp.data.lut_cfg_data.data,
-					&copyback);
+					&copyback, copy_from_kernel);
 			break;
 
 		case mdp_lut_pgc:
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index 4e7cc37..65b5fc4 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -93,6 +93,72 @@
 static u32 dither_depth_map[9] = {
 	0, 0, 0, 0, 0, 1, 2, 3, 3};
 
+static u32 igc_limited[IGC_LUT_ENTRIES] = {
+	16777472, 17826064, 18874656, 19923248,
+	19923248, 20971840, 22020432, 23069024,
+	24117616, 25166208, 26214800, 26214800,
+	27263392, 28311984, 29360576, 30409168,
+	31457760, 32506352, 32506352, 33554944,
+	34603536, 35652128, 36700720, 37749312,
+	38797904, 38797904, 39846496, 40895088,
+	41943680, 42992272, 44040864, 45089456,
+	45089456, 46138048, 47186640, 48235232,
+	49283824, 50332416, 51381008, 51381008,
+	52429600, 53478192, 54526784, 55575376,
+	56623968, 57672560, 58721152, 58721152,
+	59769744, 60818336, 61866928, 62915520,
+	63964112, 65012704, 65012704, 66061296,
+	67109888, 68158480, 69207072, 70255664,
+	71304256, 71304256, 72352848, 73401440,
+	74450032, 75498624, 76547216, 77595808,
+	77595808, 78644400, 79692992, 80741584,
+	81790176, 82838768, 83887360, 83887360,
+	84935952, 85984544, 87033136, 88081728,
+	89130320, 90178912, 90178912, 91227504,
+	92276096, 93324688, 94373280, 95421872,
+	96470464, 96470464, 97519056, 98567648,
+	99616240, 100664832, 101713424, 102762016,
+	102762016, 103810608, 104859200, 105907792,
+	106956384, 108004976, 109053568, 109053568,
+	110102160, 111150752, 112199344, 113247936,
+	114296528, 115345120, 115345120, 116393712,
+	117442304, 118490896, 119539488, 120588080,
+	121636672, 121636672, 122685264, 123733856,
+	124782448, 125831040, 126879632, 127928224,
+	127928224, 128976816, 130025408, 131074000,
+	132122592, 133171184, 134219776, 135268368,
+	135268368, 136316960, 137365552, 138414144,
+	139462736, 140511328, 141559920, 141559920,
+	142608512, 143657104, 144705696, 145754288,
+	146802880, 147851472, 147851472, 148900064,
+	149948656, 150997248, 152045840, 153094432,
+	154143024, 154143024, 155191616, 156240208,
+	157288800, 158337392, 159385984, 160434576,
+	160434576, 161483168, 162531760, 163580352,
+	164628944, 165677536, 166726128, 166726128,
+	167774720, 168823312, 169871904, 170920496,
+	171969088, 173017680, 173017680, 174066272,
+	175114864, 176163456, 177212048, 178260640,
+	179309232, 179309232, 180357824, 181406416,
+	182455008, 183503600, 184552192, 185600784,
+	185600784, 186649376, 187697968, 188746560,
+	189795152, 190843744, 191892336, 191892336,
+	192940928, 193989520, 195038112, 196086704,
+	197135296, 198183888, 198183888, 199232480,
+	200281072, 201329664, 202378256, 203426848,
+	204475440, 204475440, 205524032, 206572624,
+	207621216, 208669808, 209718400, 210766992,
+	211815584, 211815584, 212864176, 213912768,
+	214961360, 216009952, 217058544, 218107136,
+	218107136, 219155728, 220204320, 221252912,
+	222301504, 223350096, 224398688, 224398688,
+	225447280, 226495872, 227544464, 228593056,
+	229641648, 230690240, 230690240, 231738832,
+	232787424, 233836016, 234884608, 235933200,
+	236981792, 236981792, 238030384, 239078976,
+	240127568, 241176160, 242224752, 243273344,
+	243273344, 244321936, 245370528, 246419120};
+
 #define GAMUT_T0_SIZE	125
 #define GAMUT_T1_SIZE	100
 #define GAMUT_T2_SIZE	80
@@ -1543,9 +1609,30 @@
 		MDSS_MDP_REG_WRITE(offset, (cfg->c2_data[i] & 0xFFF) | data);
 }
 
+int mdss_mdp_limited_lut_igc_config(struct mdss_mdp_ctl *ctl)
+{
+	int ret = 0;
+	u32 copyback = 0;
+	u32 copy_from_kernel = 1;
+	struct mdp_igc_lut_data config;
+
+	if (!ctl)
+		return -EINVAL;
+
+	config.len = IGC_LUT_ENTRIES;
+	config.ops = MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE;
+	config.block = (ctl->mfd->index) + MDP_LOGICAL_BLOCK_DISP_0;
+	config.c0_c1_data = igc_limited;
+	config.c2_data = igc_limited;
+
+	ret = mdss_mdp_igc_lut_config(ctl, &config, &copyback,
+					copy_from_kernel);
+	return ret;
+}
+
 int mdss_mdp_igc_lut_config(struct mdss_mdp_ctl *ctl,
 					struct mdp_igc_lut_data *config,
-					u32 *copyback)
+					u32 *copyback, u32 copy_from_kernel)
 {
 	int ret = 0;
 	u32 tbl_idx, igc_offset, disp_num, dspp_num = 0;
@@ -1597,15 +1684,25 @@
 		*copyback = 1;
 		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
 	} else {
-		if (copy_from_user(&mdss_pp_res->igc_lut_c0c1[disp_num][0],
-			config->c0_c1_data, config->len * sizeof(u32))) {
-			ret = -EFAULT;
-			goto igc_config_exit;
-		}
-		if (copy_from_user(&mdss_pp_res->igc_lut_c2[disp_num][0],
-			config->c2_data, config->len * sizeof(u32))) {
-			ret = -EFAULT;
-			goto igc_config_exit;
+		if (copy_from_kernel) {
+			memcpy(&mdss_pp_res->igc_lut_c0c1[disp_num][0],
+			config->c0_c1_data, config->len * sizeof(u32));
+			memcpy(&mdss_pp_res->igc_lut_c2[disp_num][0],
+			config->c2_data, config->len * sizeof(u32));
+		} else {
+			if (copy_from_user(
+				&mdss_pp_res->igc_lut_c0c1[disp_num][0],
+				config->c0_c1_data,
+				config->len * sizeof(u32))) {
+				ret = -EFAULT;
+				goto igc_config_exit;
+			}
+			if (copy_from_user(
+				&mdss_pp_res->igc_lut_c2[disp_num][0],
+				config->c2_data, config->len * sizeof(u32))) {
+				ret = -EFAULT;
+				goto igc_config_exit;
+			}
 		}
 		mdss_pp_res->igc_disp_cfg[disp_num] = *config;
 		mdss_pp_res->igc_disp_cfg[disp_num].c0_c1_data =
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index 2f77d29..73b94af 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -286,7 +286,7 @@
 	MSG_LVL_LOW,
 	MSG_LVL_LOW,
 	MSG_LVL_LOW,
-	MSG_LVL_HIGH,
+	MSG_LVL_LOW,
 	MSG_LVL_LOW,
 	MSG_LVL_LOW,
 	MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
@@ -725,7 +725,7 @@
 /* LOG CODES */
 
 #define LOG_0	0x0
-#define LOG_1	0x17F4
+#define LOG_1	0x17FA
 #define LOG_2	0x0
 #define LOG_3	0x0
 #define LOG_4	0x4910
diff --git a/include/linux/mfd/wcd9xxx/pdata.h b/include/linux/mfd/wcd9xxx/pdata.h
index c6e4ab3..b7ba6fb 100644
--- a/include/linux/mfd/wcd9xxx/pdata.h
+++ b/include/linux/mfd/wcd9xxx/pdata.h
@@ -126,6 +126,7 @@
 	u8 bias2_cap_mode;
 	u8 bias3_cap_mode;
 	u8 bias4_cap_mode;
+	bool bias2_is_headset_only;
 };
 
 struct wcd9xxx_ocp_setting {
diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h
index 992649f..47cf184 100644
--- a/include/media/msm_cam_sensor.h
+++ b/include/media/msm_cam_sensor.h
@@ -289,8 +289,8 @@
 
 enum eeprom_cfg_type_t {
 	CFG_EEPROM_GET_INFO,
-	CFG_EEPROM_GET_DATA,
-	CFG_EEPROM_READ_DATA,
+	CFG_EEPROM_GET_CAL_DATA,
+	CFG_EEPROM_READ_CAL_DATA,
 	CFG_EEPROM_WRITE_DATA,
 };
 struct eeprom_get_t {
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index 01e30d0..0d3b5a0 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -2237,7 +2237,7 @@
 */
 #define ADSP_MEMORY_MAP_PHYSICAL_MEMORY 0
 
-
+#define NULL_COPP_TOPOLOGY				0x00010312
 #define DEFAULT_COPP_TOPOLOGY				0x00010be3
 #define DEFAULT_POPP_TOPOLOGY				0x00010be4
 #define VPM_TX_SM_ECNS_COPP_TOPOLOGY			0x00010F71
diff --git a/include/sound/q6adm-v2.h b/include/sound/q6adm-v2.h
index 4bea1e1..449694e 100644
--- a/include/sound/q6adm-v2.h
+++ b/include/sound/q6adm-v2.h
@@ -47,10 +47,10 @@
 int adm_memory_unmap_regions(int port_id, uint32_t *buf_add, uint32_t *bufsz,
 						uint32_t bufcnt);
 
-int adm_close(int port);
+int adm_close(int port, bool perf_mode);
 
 int adm_matrix_map(int session_id, int path, int num_copps,
-				unsigned int *port_id, int copp_id);
+		unsigned int *port_id, int copp_id, bool perf_mode);
 
 int adm_connect_afe_port(int mode, int session_id, int port_id);
 
diff --git a/kernel/timer.c b/kernel/timer.c
index 24c5d20..cf7217a 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1679,12 +1679,12 @@
 			boot_done = 1;
 			base = &boot_tvec_bases;
 		}
+		spin_lock_init(&base->lock);
 		tvec_base_done[cpu] = 1;
 	} else {
 		base = per_cpu(tvec_bases, cpu);
 	}
 
-	spin_lock_init(&base->lock);
 
 	for (j = 0; j < TVN_SIZE; j++) {
 		INIT_LIST_HEAD(base->tv5.vec + j);
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 845f1a2..5d4f9e6 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -488,6 +488,8 @@
 	bool spkr_pa_widget_on;
 	struct regulator *spkdrv_reg;
 
+	bool mbhc_started;
+
 	struct afe_param_cdc_slimbus_slave_cfg slimbus_slave_cfg;
 
 	/* resmgr module */
@@ -2648,7 +2650,9 @@
 		else if (strnstr(w->name, internal3_text, 30))
 			snd_soc_update_bits(codec, micb_int_reg, 0x3, 0x3);
 
-		if (micb_ctl_reg == TAIKO_A_MICB_2_CTL)
+		if (taiko->mbhc_started &&
+		    taiko->resmgr.pdata->micbias.bias2_is_headset_only &&
+		    micb_ctl_reg == TAIKO_A_MICB_2_CTL)
 			wcd9xxx_resmgr_add_cond_update_bits(&taiko->resmgr,
 						  WCD9XXX_COND_HPH_MIC,
 						  micb_ctl_reg, w->shift,
@@ -2663,7 +2667,9 @@
 		wcd9xxx_resmgr_notifier_call(&taiko->resmgr, e_post_on);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		if (micb_ctl_reg == TAIKO_A_MICB_2_CTL)
+		if (taiko->mbhc_started &&
+		    taiko->resmgr.pdata->micbias.bias2_is_headset_only &&
+		    micb_ctl_reg == TAIKO_A_MICB_2_CTL)
 			wcd9xxx_resmgr_rm_cond_update_bits(&taiko->resmgr,
 						  WCD9XXX_COND_HPH_MIC,
 						  micb_ctl_reg, 7, false);
@@ -5960,8 +5966,12 @@
 int taiko_hs_detect(struct snd_soc_codec *codec,
 		    struct wcd9xxx_mbhc_config *mbhc_cfg)
 {
+	int rc;
 	struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
-	return wcd9xxx_mbhc_start(&taiko->mbhc, mbhc_cfg);
+	rc = wcd9xxx_mbhc_start(&taiko->mbhc, mbhc_cfg);
+	if (!rc)
+		taiko->mbhc_started = true;
+	return rc;
 }
 EXPORT_SYMBOL_GPL(taiko_hs_detect);
 
@@ -6017,13 +6027,20 @@
 	taiko_init_slim_slave_cfg(codec);
 	taiko_slim_interface_init_reg(codec);
 
-	wcd9xxx_mbhc_deinit(&taiko->mbhc);
-	ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec,
-				WCD9XXX_MBHC_VERSION_TAIKO);
-	if (ret)
-		pr_err("%s: mbhc init failed %d\n", __func__, ret);
-	else
-		wcd9xxx_mbhc_start(&taiko->mbhc, taiko->mbhc.mbhc_cfg);
+	if (taiko->mbhc_started) {
+		wcd9xxx_mbhc_deinit(&taiko->mbhc);
+		taiko->mbhc_started = false;
+		ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec,
+					WCD9XXX_MBHC_VERSION_TAIKO);
+		if (ret) {
+			pr_err("%s: mbhc init failed %d\n", __func__, ret);
+		} else {
+			ret = wcd9xxx_mbhc_start(&taiko->mbhc,
+						 taiko->mbhc.mbhc_cfg);
+			if (!ret)
+				taiko->mbhc_started = true;
+		}
+	}
 	mutex_unlock(&codec->mutex);
 	return ret;
 }
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index fa476ee..af4632c 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -44,7 +44,7 @@
 	unsigned int  sample_rate;
 	unsigned int  channel;
 	unsigned int  format;
-	bool perf_mode;
+	unsigned long perf_mode;
 };
 
 #define INVALID_SESSION -1
@@ -270,7 +270,7 @@
 }
 
 static void msm_pcm_routing_build_matrix(int fedai_id, int dspst_id,
-	int path_type)
+	int path_type, bool perf_mode)
 {
 	int i, port_type;
 	struct route_payload payload;
@@ -290,7 +290,7 @@
 
 	if (payload.num_copps)
 		adm_matrix_map(dspst_id, path_type,
-			payload.num_copps, payload.copp_ids, 0);
+			payload.num_copps, payload.copp_ids, 0, perf_mode);
 }
 
 void msm_pcm_routing_reg_psthr_stream(int fedai_id, int dspst_id,
@@ -365,8 +365,8 @@
 		msm_send_eq_values(fedai_id);
 	topology = get_topology(path_type);
 	for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
-		if (test_bit(fedai_id, &msm_bedais[i].fe_sessions))
-			msm_bedais[i].perf_mode = perf_mode;
+		if (test_bit(fedai_id, &msm_bedais[i].fe_sessions) && perf_mode)
+			set_bit(fedai_id, &msm_bedais[i].perf_mode);
 		if (!is_be_dai_extproc(i) &&
 		   (afe_get_port_type(msm_bedais[i].port_id) == port_type) &&
 		   (msm_bedais[i].active) &&
@@ -385,7 +385,8 @@
 				path_type,
 				msm_bedais[i].sample_rate,
 				msm_bedais[i].channel,
-				topology, msm_bedais[i].perf_mode,
+				topology,
+				test_bit(fedai_id, &msm_bedais[i].perf_mode),
 				bits_per_sample);
 			else
 				adm_open(msm_bedais[i].port_id,
@@ -408,7 +409,7 @@
 	}
 	if (payload.num_copps)
 		adm_matrix_map(dspst_id, path_type,
-			payload.num_copps, payload.copp_ids, 0);
+			payload.num_copps, payload.copp_ids, 0, perf_mode);
 
 	mutex_unlock(&routing_lock);
 }
@@ -440,7 +441,8 @@
 		   (afe_get_port_type(msm_bedais[i].port_id) == port_type) &&
 		   (msm_bedais[i].active) &&
 		   (test_bit(fedai_id, &msm_bedais[i].fe_sessions))) {
-			adm_close(msm_bedais[i].port_id);
+			adm_close(msm_bedais[i].port_id,
+				test_bit(fedai_id, &msm_bedais[i].perf_mode));
 			if (DOLBY_ADM_COPP_TOPOLOGY_ID == topology)
 				dolby_dap_deinit(msm_bedais[i].port_id);
 		}
@@ -473,6 +475,7 @@
 	int session_type, path_type, port_id, topology;
 	u32 channels;
 	uint16_t bits_per_sample = 16;
+	bool perf_mode = false;
 
 	pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
 
@@ -507,12 +510,14 @@
 
 			if ((session_type == SESSION_TYPE_RX) &&
 				(channels > 0)) {
+				perf_mode = test_bit(val,
+						&msm_bedais[reg].perf_mode);
 				adm_multi_ch_copp_open(msm_bedais[reg].port_id,
 				path_type,
 				msm_bedais[reg].sample_rate,
 				channels,
 				topology,
-				msm_bedais[reg].perf_mode,
+				perf_mode,
 				bits_per_sample);
 			} else
 				adm_open(msm_bedais[reg].port_id,
@@ -521,7 +526,8 @@
 				topology, false, bits_per_sample);
 
 			msm_pcm_routing_build_matrix(val,
-				fe_dai_map[val][session_type], path_type);
+				fe_dai_map[val][session_type], path_type,
+				perf_mode);
 			port_id = srs_port_id = msm_bedais[reg].port_id;
 			srs_send_params(srs_port_id, 1, 0);
 			if (DOLBY_ADM_COPP_TOPOLOGY_ID == topology)
@@ -536,11 +542,13 @@
 		clear_bit(val, &msm_bedais[reg].fe_sessions);
 		if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
 			INVALID_SESSION) {
-			adm_close(msm_bedais[reg].port_id);
+			perf_mode = test_bit(val, &msm_bedais[reg].perf_mode);
+			adm_close(msm_bedais[reg].port_id, perf_mode);
 			if (DOLBY_ADM_COPP_TOPOLOGY_ID == topology)
 				dolby_dap_deinit(msm_bedais[reg].port_id);
 			msm_pcm_routing_build_matrix(val,
-				fe_dai_map[val][session_type], path_type);
+				fe_dai_map[val][session_type], path_type,
+				perf_mode);
 		}
 	}
 	if ((msm_bedais[reg].port_id == VOICE_RECORD_RX)
@@ -3243,8 +3251,10 @@
 	topology = get_topology(path_type);
 	for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) {
 		if (fe_dai_map[i][session_type] != INVALID_SESSION) {
-			adm_close(bedai->port_id);
+			adm_close(bedai->port_id,
+				test_bit(i, &(bedai->perf_mode)));
 			srs_port_id = -1;
+			clear_bit(i, &(bedai->perf_mode));
 			if (DOLBY_ADM_COPP_TOPOLOGY_ID == topology)
 				dolby_dap_deinit(bedai->port_id);
 		}
@@ -3253,7 +3263,6 @@
 	bedai->active = 0;
 	bedai->sample_rate = 0;
 	bedai->channel = 0;
-	bedai->perf_mode = false;
 	mutex_unlock(&routing_lock);
 
 	return 0;
@@ -3268,6 +3277,7 @@
 	u32 channels;
 	bool playback, capture;
 	uint16_t bits_per_sample = 16;
+	bool perf_mode = false;
 
 	if (be_id >= MSM_BACKEND_DAI_MAX) {
 		pr_err("%s: unexpected be_id %d\n", __func__, be_id);
@@ -3306,11 +3316,13 @@
 				bits_per_sample = 24;
 
 			if ((playback) && (channels > 0)) {
+				perf_mode = test_bit(i, &(bedai->perf_mode));
 				adm_multi_ch_copp_open(bedai->port_id,
 					path_type,
 					bedai->sample_rate,
 					channels,
-					topology, bedai->perf_mode,
+					topology,
+					perf_mode,
 					bits_per_sample);
 			} else if (capture) {
 				adm_open(bedai->port_id,
@@ -3322,7 +3334,8 @@
 			}
 
 			msm_pcm_routing_build_matrix(i,
-				fe_dai_map[i][session_type], path_type);
+				fe_dai_map[i][session_type], path_type,
+				perf_mode);
 			port_id = srs_port_id = bedai->port_id;
 			srs_send_params(srs_port_id, 1, 0);
 			if (DOLBY_ADM_COPP_TOPOLOGY_ID == topology)
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index 1bd3eac..29c06cb 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -39,6 +39,9 @@
 	void *apr;
 	atomic_t copp_id[AFE_MAX_PORTS];
 	atomic_t copp_cnt[AFE_MAX_PORTS];
+	atomic_t copp_low_latency_id[AFE_MAX_PORTS];
+	atomic_t copp_low_latency_cnt[AFE_MAX_PORTS];
+	atomic_t copp_perf_mode[AFE_MAX_PORTS];
 	atomic_t copp_stat[AFE_MAX_PORTS];
 	wait_queue_head_t wait[AFE_MAX_PORTS];
 
@@ -445,7 +448,12 @@
 			for (i = 0; i < AFE_MAX_PORTS; i++) {
 				atomic_set(&this_adm.copp_id[i],
 							RESET_COPP_ID);
+				atomic_set(&this_adm.copp_low_latency_id[i],
+							RESET_COPP_ID);
 				atomic_set(&this_adm.copp_cnt[i], 0);
+				atomic_set(&this_adm.copp_low_latency_cnt[i],
+						0);
+				atomic_set(&this_adm.copp_perf_mode[i], 0);
 				atomic_set(&this_adm.copp_stat[i], 0);
 			}
 			this_adm.apr = NULL;
@@ -545,7 +553,13 @@
 				wake_up(&this_adm.wait[index]);
 				break;
 			}
-			atomic_set(&this_adm.copp_id[index], open->copp_id);
+			if (atomic_read(&this_adm.copp_perf_mode[index])) {
+				atomic_set(&this_adm.copp_low_latency_id[index],
+						open->copp_id);
+			} else {
+				atomic_set(&this_adm.copp_id[index],
+					open->copp_id);
+			}
 			atomic_set(&this_adm.copp_stat[index], 1);
 			pr_debug("%s: coppid rxed=%d\n", __func__,
 							open->copp_id);
@@ -892,8 +906,8 @@
 	int index;
 	int tmp_port = q6audio_get_port_id(port_id);
 
-	pr_debug("%s: port %#x path:%d rate:%d mode:%d\n", __func__,
-				port_id, path, rate, channel_mode);
+	pr_debug("%s: port %#x path:%d rate:%d mode:%d perf_mode:%d\n",
+		 __func__, port_id, path, rate, channel_mode, perf_mode);
 
 	port_id = q6audio_convert_virtual_to_portid(port_id);
 
@@ -916,11 +930,19 @@
 		rtac_set_adm_handle(this_adm.apr);
 	}
 
-	send_adm_custom_topology(port_id);
+	if (!perf_mode) {
+		atomic_set(&this_adm.copp_perf_mode[index], 0);
+		send_adm_custom_topology(port_id);
+	} else {
+		atomic_set(&this_adm.copp_perf_mode[index], 1);
+	}
 
 	/* Create a COPP if port id are not enabled */
-	if (atomic_read(&this_adm.copp_cnt[index]) == 0) {
-
+	if ((!perf_mode && (atomic_read(&this_adm.copp_cnt[index]) == 0)) ||
+		(perf_mode &&
+		(atomic_read(&this_adm.copp_low_latency_cnt[index]) == 0))) {
+		pr_debug("%s:opening ADM: perf_mode: %d\n", __func__,
+			perf_mode);
 		open.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 		open.hdr.pkt_size = sizeof(open);
@@ -950,6 +972,9 @@
 			(open.topology_id == VPM_TX_DM_FLUENCE_COPP_TOPOLOGY))
 				rate = 16000;
 
+		if (perf_mode)
+			open.topology_id = NULL_COPP_TOPOLOGY;
+
 		open.dev_num_channel = channel_mode & 0x00FF;
 		open.bit_width = bits_per_sample;
 		open.sample_rate  = rate;
@@ -1026,7 +1051,15 @@
 			goto fail_cmd;
 		}
 	}
-	atomic_inc(&this_adm.copp_cnt[index]);
+	if (perf_mode) {
+		atomic_inc(&this_adm.copp_low_latency_cnt[index]);
+		pr_debug("%s: index: %d coppid: %d", __func__, index,
+			atomic_read(&this_adm.copp_low_latency_id[index]));
+	} else {
+		atomic_inc(&this_adm.copp_cnt[index]);
+		pr_debug("%s: index: %d coppid: %d", __func__, index,
+			atomic_read(&this_adm.copp_id[index]));
+	}
 	return 0;
 
 fail_cmd:
@@ -1046,7 +1079,7 @@
 }
 
 int adm_matrix_map(int session_id, int path, int num_copps,
-			unsigned int *port_id, int copp_id)
+			unsigned int *port_id, int copp_id, bool perf_mode)
 {
 	struct adm_cmd_matrix_map_routings_v5	*route;
 	struct adm_session_map_node_v5 *node;
@@ -1085,7 +1118,12 @@
 	route->hdr.src_port = copp_id;
 	route->hdr.dest_svc = APR_SVC_ADM;
 	route->hdr.dest_domain = APR_DOMAIN_ADSP;
-	route->hdr.dest_port = atomic_read(&this_adm.copp_id[index]);
+	if (perf_mode) {
+		route->hdr.dest_port =
+			atomic_read(&this_adm.copp_low_latency_id[index]);
+	} else {
+		route->hdr.dest_port = atomic_read(&this_adm.copp_id[index]);
+	}
 	route->hdr.token = copp_id;
 	route->hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS_V5;
 	route->num_sessions = 1;
@@ -1117,9 +1155,14 @@
 		tmp = q6audio_get_port_index(port_id[i]);
 
 
-		if (tmp >= 0 && tmp < AFE_MAX_PORTS)
-			copps_list[i] =
+		if (tmp >= 0 && tmp < AFE_MAX_PORTS) {
+			if (perf_mode)
+				copps_list[i] =
+				atomic_read(&this_adm.copp_low_latency_id[tmp]);
+			else
+				copps_list[i] =
 					atomic_read(&this_adm.copp_id[tmp]);
+		}
 		else
 			continue;
 		pr_debug("%s: port_id[%#x]: %d, index: %d act coppid[0x%x]\n",
@@ -1144,21 +1187,42 @@
 		ret = -EINVAL;
 		goto fail_cmd;
 	}
-	for (i = 0; i < num_copps; i++)
-		send_adm_cal(port_id[i], path);
+	if (perf_mode) {
+		for (i = 0; i < num_copps; i++) {
+			int tmp;
 
-	for (i = 0; i < num_copps; i++) {
-		int tmp;
-		tmp = afe_get_port_index(port_id[i]);
-		if (tmp >= 0 && tmp < AFE_MAX_PORTS)
-			rtac_add_adm_device(port_id[i],
-				atomic_read(&this_adm.copp_id[tmp]),
-				path, session_id);
-		else
-			pr_debug("%s: Invalid port index %d",
-				__func__, tmp);
+			tmp = afe_get_port_index(port_id[i]);
+			if (tmp >= 0 && tmp < AFE_MAX_PORTS) {
+				rtac_add_adm_device(port_id[i], atomic_read(
+					&this_adm.copp_low_latency_id[tmp]),
+					path, session_id);
+				pr_debug("%s, copp_id: %d\n", __func__,
+					atomic_read(
+					&this_adm.copp_low_latency_id[tmp]));
+			} else {
+				pr_debug("%s: Invalid port index %d",
+					__func__, tmp);
+			}
+		}
+	} else {
+		for (i = 0; i < num_copps; i++)
+			send_adm_cal(port_id[i], path);
+
+		for (i = 0; i < num_copps; i++) {
+			int tmp;
+			tmp = afe_get_port_index(port_id[i]);
+			if (tmp >= 0 && tmp < AFE_MAX_PORTS) {
+				rtac_add_adm_device(port_id[i],
+					atomic_read(&this_adm.copp_id[tmp]),
+					path, session_id);
+				pr_debug("%s, copp_id: %d\n", __func__,
+					atomic_read(&this_adm.copp_id[tmp]));
+			} else {
+				pr_debug("%s: Invalid port index %d",
+					__func__, tmp);
+			}
+		}
 	}
-
 fail_cmd:
 	kfree(matrix_map);
 	return ret;
@@ -1319,7 +1383,7 @@
 	return atomic_read(&this_adm.copp_id[port_index]);
 }
 
-int adm_close(int port_id)
+int adm_close(int port_id, bool perf_mode)
 {
 	struct apr_hdr close;
 
@@ -1332,16 +1396,30 @@
 	if (q6audio_validate_port(port_id) < 0)
 		return -EINVAL;
 
-	pr_debug("%s port_id=%#x index %d\n", __func__, port_id, index);
+	pr_debug("%s port_id=%#x index %d perf_mode: %d\n", __func__, port_id,
+		index, perf_mode);
 
-	if (!(atomic_read(&this_adm.copp_cnt[index]))) {
-		pr_err("%s: copp count for port[%#x]is 0\n", __func__, port_id);
-
-		goto fail_cmd;
+	if (perf_mode) {
+		if (!(atomic_read(&this_adm.copp_low_latency_cnt[index]))) {
+			pr_err("%s: copp count for port[%#x]is 0\n", __func__,
+				port_id);
+			goto fail_cmd;
+		}
+		atomic_dec(&this_adm.copp_low_latency_cnt[index]);
+	} else {
+		if (!(atomic_read(&this_adm.copp_cnt[index]))) {
+			pr_err("%s: copp count for port[%#x]is 0\n", __func__,
+				port_id);
+			goto fail_cmd;
+		}
+		atomic_dec(&this_adm.copp_cnt[index]);
 	}
-	atomic_dec(&this_adm.copp_cnt[index]);
-	if (!(atomic_read(&this_adm.copp_cnt[index]))) {
+	if ((!perf_mode && !(atomic_read(&this_adm.copp_cnt[index]))) ||
+		(perf_mode &&
+		!(atomic_read(&this_adm.copp_low_latency_cnt[index])))) {
 
+		pr_debug("%s:Closing ADM: perf_mode: %d\n", __func__,
+				perf_mode);
 		close.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
 			APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 		close.pkt_size = sizeof(close);
@@ -1350,19 +1428,33 @@
 		close.src_port = port_id;
 		close.dest_svc = APR_SVC_ADM;
 		close.dest_domain = APR_DOMAIN_ADSP;
-		close.dest_port = atomic_read(&this_adm.copp_id[index]);
+		if (perf_mode)
+			close.dest_port =
+			     atomic_read(&this_adm.copp_low_latency_id[index]);
+		else
+			close.dest_port = atomic_read(&this_adm.copp_id[index]);
 		close.token = port_id;
 		close.opcode = ADM_CMD_DEVICE_CLOSE_V5;
 
-		atomic_set(&this_adm.copp_id[index], RESET_COPP_ID);
 		atomic_set(&this_adm.copp_stat[index], 0);
 
-
-		pr_debug("%s:coppid %d portid=%#x index=%d coppcnt=%d\n",
+		if (perf_mode) {
+			pr_debug("%s:coppid %d portid=%#x index=%d coppcnt=%d\n",
+			    __func__,
+			    atomic_read(&this_adm.copp_low_latency_id[index]),
+			    port_id, index,
+			    atomic_read(&this_adm.copp_low_latency_cnt[index]));
+			atomic_set(&this_adm.copp_low_latency_id[index],
+				RESET_COPP_ID);
+		} else {
+			pr_debug("%s:coppid %d portid=%#x index=%d coppcnt=%d\n",
 				__func__,
 				atomic_read(&this_adm.copp_id[index]),
 				port_id, index,
 				atomic_read(&this_adm.copp_cnt[index]));
+			atomic_set(&this_adm.copp_id[index],
+				RESET_COPP_ID);
+		}
 
 		ret = apr_send_pkt(this_adm.apr, (uint32_t *)&close);
 		if (ret < 0) {
@@ -1380,7 +1472,10 @@
 			ret = -EINVAL;
 			goto fail_cmd;
 		}
-
+	}
+	if (!atomic_read(&this_adm.copp_cnt[index]) &&
+		!atomic_read(&this_adm.copp_low_latency_cnt[index])) {
+		pr_debug("%s: remove adm device from rtac\n", __func__);
 		rtac_remove_adm_device(port_id);
 	}
 
@@ -1396,8 +1491,11 @@
 
 	for (i = 0; i < AFE_MAX_PORTS; i++) {
 		atomic_set(&this_adm.copp_id[i], RESET_COPP_ID);
+		atomic_set(&this_adm.copp_low_latency_id[i], RESET_COPP_ID);
 		atomic_set(&this_adm.copp_cnt[i], 0);
+		atomic_set(&this_adm.copp_low_latency_cnt[i], 0);
 		atomic_set(&this_adm.copp_stat[i], 0);
+		atomic_set(&this_adm.copp_perf_mode[i], 0);
 		init_waitqueue_head(&this_adm.wait[i]);
 	}
 	return 0;