Merge "msm: ipc: Send Resume_Tx from the client/server context"
diff --git a/AndroidKernel.mk b/AndroidKernel.mk
index 3684a3f..d97d3c3 100644
--- a/AndroidKernel.mk
+++ b/AndroidKernel.mk
@@ -5,7 +5,11 @@
 
 KERNEL_OUT := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ
 KERNEL_CONFIG := $(KERNEL_OUT)/.config
+ifeq ($(TARGET_KERNEL_APPEND_DTB), true)
+TARGET_PREBUILT_INT_KERNEL := $(KERNEL_OUT)/arch/arm/boot/zImage-dtb
+else
 TARGET_PREBUILT_INT_KERNEL := $(KERNEL_OUT)/arch/arm/boot/zImage
+endif
 KERNEL_HEADERS_INSTALL := $(KERNEL_OUT)/usr
 KERNEL_MODULES_INSTALL := system
 KERNEL_MODULES_OUT := $(TARGET_OUT)/lib/modules
diff --git a/Documentation/devicetree/bindings/dma/sps/sps.txt b/Documentation/devicetree/bindings/dma/sps/sps.txt
index a979c56..26102c8 100644
--- a/Documentation/devicetree/bindings/dma/sps/sps.txt
+++ b/Documentation/devicetree/bindings/dma/sps/sps.txt
@@ -7,7 +7,11 @@
   - compatible: should be "qcom,msm_sps"
 
 Optional properties:
-  - reg: offset and size of the register set in the memory map
+  - reg: offset and size for the memory mapping, including maps for
+    BAM DMA BAM, BAM DMA peripheral, pipe memory and reserved memory.
+  - reg-names: indicates various resources passed to driver (via reg
+    property) by name. "reg-names" examples are "bam_mem", "core_mem"
+    , "pipe_mem" and "res_mem".
   - interrupts: IRQ line
   - qcom,device-type: specify the device configuration of BAM DMA and
     pipe memory. Can be one of
diff --git a/Documentation/devicetree/bindings/input/misc/stk-stk3x1x.txt b/Documentation/devicetree/bindings/input/misc/stk-stk3x1x.txt
new file mode 100644
index 0000000..aa50140
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/misc/stk-stk3x1x.txt
@@ -0,0 +1,46 @@
+Sensortek stk301x, stk321x and stk331x ambient light/proximity 3-in-1 sensor
+
+Required properties:
+
+ - compatible		: Should be "stk,stk3x1x".
+ - reg					: i2c slave address of the device.
+ - interrupt-parent	: Parent of interrupt.
+ - interrupts		: Sensor will issue interrupt when preset condition is met,
+				typically when proximity sensor detect a change on near/far state.
+ - vdd-supply		: Main power supply to power sensor.
+ - vio-supply		: Power supply required to pullup I2C bus.
+ - stk,irq-gpio	: irq gpio which is to provide interrupts to host, same as
+				"interrupts" node.
+ - stk,transmittance : Transmittance rate of glass above the ambient light
+				detection window. The value may not be equal to real transmittance
+				but just a relative value.
+ - stk,state-reg	: The default setting of state register.
+ - stk,psctrl-reg	: The default setting for proximity sensor.
+ - stk,alsctrl-reg	: The default setting for ambient light sensor.
+ - stk,ledctrl-reg	: The default setting for IR LED.
+ - stk,wait-reg	: The default setting for wait time.
+ - stk,ps-thdh	: High threshold for proximity sensor, sensor will report
+				"near" if the proximity sensor reading is larger or equal to this
+				value.
+ - stk,ps-thdl	: Low threshold for proximity sensor, sensor will report
+				"far" if the proximity sensor reading is larger than this value.
+
+Example:
+	i2c@f9925000 {
+		stk@48 {
+			compatible = "stk,stk3x1x";
+			reg = <0x48>;
+			interrupt-parent = <&msmgpio>;
+			interrupts = <80 0x2>;
+			vdd-supply = <&pm8110_l19>;
+			vio-supply = <&pm8110_l14>;
+			stk,irq-gpio = <&msmgpio 80 0x02>;
+			stk,transmittance = <500>;
+			stk,state-reg = <0x00>;
+			stk,psctrl-reg = <0x71>;
+			stk,alsctrl-reg = <0x38>;
+			stk,ledctrl-reg = <0xFF>;
+			stk,wait-reg = <0x07>;
+			stk,ps-thdh = <1700>;
+			stk,ps-thdl = <1500>;
+		};
diff --git a/Documentation/devicetree/bindings/media/video/msm-camera-flash.txt b/Documentation/devicetree/bindings/media/video/msm-camera-flash.txt
index 72b32be..d848baf 100644
--- a/Documentation/devicetree/bindings/media/video/msm-camera-flash.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-camera-flash.txt
@@ -13,6 +13,10 @@
 - qcom,flash-source : Should contain array of phandles to flash source nodes.
     - pm8941_flash0 pm8941_flash1
 
+Optional properties:
+-qcom,torch-source : Should contain phandle to torch source node.
+    -pm8941_torch
+
 Example:
 
 qcom,camera-led-flash {
@@ -20,4 +24,5 @@
 	compatible = "qcom,camera-led-flash";
 	qcom,flash-type = <1>;
 	qcom,flash-source = <&pm8941_flash0 &pm8941_flash1>;
+	qcom,torch-source = <&pm8941_torch>;
 };
diff --git a/Documentation/devicetree/bindings/media/video/msm-cci.txt b/Documentation/devicetree/bindings/media/video/msm-cci.txt
index b8156c3..c60441f 100644
--- a/Documentation/devicetree/bindings/media/video/msm-cci.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-cci.txt
@@ -49,6 +49,7 @@
 Required properties:
 - compatible : should be manufacturer name followed by sensor name
     - "qcom,s5k3l1yx"
+    - "qcom,imx135"
     - "shinetech,gc0339"
     - "shinetech,hi256"
     - "shinetech,s5k4e1"
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index a3a3807..527c50c 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -42,6 +42,7 @@
 samsung	Samsung Semiconductor
 sbs	Smart Battery System
 schindler	Schindler
+stk	Sensortek Technology Corporation.(formerly Sitronix Technology Co., Ltd.)
 shinetech	Shine Tech Corporation, Ltd.
 sil	Silicon Image
 simtek
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8226e43..69b2cd2 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2015,6 +2015,21 @@
 	help
 	  Include support for flattened device tree machine descriptions.
 
+config BUILD_ARM_APPENDED_DTB_IMAGE
+	bool "Build a concatenated zImage/dtb by default"
+	depends on OF
+	help
+	  Enabling this option will cause a concatenated zImage and list of
+	  DTBs to be built by default (instead of a standalone zImage.)
+	  The image will built in arch/arm/boot/zImage-dtb
+
+config BUILD_ARM_APPENDED_DTB_IMAGE_NAMES
+	string "Default dtb names"
+	depends on BUILD_ARM_APPENDED_DTB_IMAGE
+	help
+	  Space separated list of names of dtbs to append when
+	  building a concatenated zImage-dtb.
+
 # Compressed boot loader in ROM.  Yes, we really want to ask about
 # TEXT and BSS so we preserve their values in the config files.
 config ZBOOT_ROM_TEXT
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 2f2603f..d43e69bf 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -261,6 +261,8 @@
 # Default target when executing plain make
 ifeq ($(CONFIG_XIP_KERNEL),y)
 KBUILD_IMAGE := xipImage
+else ifeq ($(CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE),y)
+KBUILD_IMAGE := zImage-dtb
 else
 KBUILD_IMAGE := zImage
 endif
@@ -292,6 +294,9 @@
 dtbs: scripts
 	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
 
+zImage-dtb: vmlinux scripts
+	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
+
 # We use MRPROPER_FILES and CLEAN_FILES now
 archclean:
 	$(Q)$(MAKE) $(clean)=$(boot)
@@ -306,7 +311,7 @@
   echo  '  Image         - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
   echo  '* xipImage      - XIP kernel image, if configured (arch/$(ARCH)/boot/xipImage)'
   echo  '  uImage        - U-Boot wrapped zImage'
-  echo  '  bootpImage    - Combined zImage and initial RAM disk' 
+  echo  '  bootpImage    - Combined zImage and initial RAM disk'
   echo  '                  (supply initrd image via make variable INITRD=<path>)'
   echo  '* dtbs          - Build device tree blobs for enabled boards'
   echo  '  install       - Install uncompressed kernel'
diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore
index 3c79f85..ad7a025 100644
--- a/arch/arm/boot/.gitignore
+++ b/arch/arm/boot/.gitignore
@@ -4,3 +4,4 @@
 bootpImage
 uImage
 *.dtb
+zImage-dtb
\ No newline at end of file
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index c877087..bc8ee6c 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -27,6 +27,14 @@
 
 targets := Image zImage xipImage bootpImage uImage
 
+DTB_NAMES := $(subst $\",,$(CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE_NAMES))
+ifneq ($(DTB_NAMES),)
+DTB_LIST := $(addsuffix .dtb,$(DTB_NAMES))
+else
+DTB_LIST := $(dtb-y)
+endif
+DTB_OBJS := $(addprefix $(obj)/,$(DTB_LIST))
+
 ifeq ($(CONFIG_XIP_KERNEL),y)
 
 $(obj)/xipImage: vmlinux FORCE
@@ -55,15 +63,19 @@
 	$(call if_changed,objcopy)
 	@echo '  Kernel: $@ is ready'
 
+$(obj)/zImage-dtb:	$(obj)/zImage $(DTB_OBJS) FORCE
+	$(call if_changed,cat)
+	@echo '  Kernel: $@ is ready'
+
 endif
 
-targets += $(dtb-y)
+targets += $(DTB_LIST)
 
 # Rule to build device tree blobs
 $(obj)/%.dtb: $(src)/dts/%.dts FORCE
 	$(call if_changed_dep,dtc)
 
-$(obj)/dtbs: $(addprefix $(obj)/, $(dtb-y))
+$(obj)/dtbs: $(DTB_OBJS)
 
 clean-files := *.dtb
 
diff --git a/arch/arm/boot/dts/apq8026-v1-mtp.dts b/arch/arm/boot/dts/apq8026-v1-mtp.dts
index b89c676..7900ddf 100644
--- a/arch/arm/boot/dts/apq8026-v1-mtp.dts
+++ b/arch/arm/boot/dts/apq8026-v1-mtp.dts
@@ -20,3 +20,10 @@
 	compatible = "qcom,apq8026-mtp", "qcom,apq8026", "qcom,mtp";
 	qcom,msm-id = <199 8 0>;
 };
+
+&cci {
+	/* Rotate rear camera to 0 degrees */
+	qcom,camera@6f {
+	qcom,mount-angle = <0>;
+	};
+};
diff --git a/arch/arm/boot/dts/apq8084-coresight.dtsi b/arch/arm/boot/dts/apq8084-coresight.dtsi
index 6cd238a..22c260f 100644
--- a/arch/arm/boot/dts/apq8084-coresight.dtsi
+++ b/arch/arm/boot/dts/apq8084-coresight.dtsi
@@ -348,4 +348,29 @@
 		coresight-name = "coresight-cti-cpu3";
 		coresight-nr-inports = <0>;
 	};
+
+	hwevent: hwevent@fd828018 {
+		compatible = "qcom,coresight-hwevent";
+		reg = <0xfd828018 0x80>,
+		      <0xf9011080 0x80>,
+		      <0xfd4ab160 0x80>,
+		      <0xfc401600 0x80>;
+		reg-names = "mmss-mux", "apcs-mux", "ppss-mux", "gcc-mux";
+
+		coresight-id = <29>;
+		coresight-name = "coresight-hwevent";
+		coresight-nr-inports = <0>;
+
+		qcom,hwevent-clks = "core_mmss_clk";
+	};
+
+	fuse: fuse@fc4be024 {
+		compatible = "arm,coresight-fuse";
+		reg = <0xfc4be024 0x8>;
+		reg-names = "fuse-base";
+
+		coresight-id = <30>;
+		coresight-name = "coresight-fuse";
+		coresight-nr-inports = <0>;
+	};
 };
diff --git a/arch/arm/boot/dts/dsi-panel-nt35521-720p-video.dtsi b/arch/arm/boot/dts/dsi-panel-nt35521-720p-video.dtsi
new file mode 100644
index 0000000..5b7cc79
--- /dev/null
+++ b/arch/arm/boot/dts/dsi-panel-nt35521-720p-video.dtsi
@@ -0,0 +1,275 @@
+/* Copyright (c) 2013, 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.
+ */
+
+/*---------------------------------------------------------------------------
+ * This file is autogenerated file using gcdb parser. Please do not edit it.
+ * Update input XML file to add a new entry or update variable in this file
+ * VERSION = "1.0"
+ *---------------------------------------------------------------------------*/
+&soc {
+	qcom,mdss_dsi_nt35521_720p_video {
+		compatible = "qcom,mdss-dsi-panel";
+		status = "disable";
+		qcom,mdss-dsi-panel-name = "nt35521 720p video mode dsi panel";
+		qcom,mdss-dsi-panel-controller = <&mdss_dsi0>;
+		qcom,mdss-dsi-panel-type = "dsi_video_mode";
+		qcom,mdss-dsi-panel-destination = "display_1";
+		qcom,mdss-dsi-panel-framerate = <60>;
+		qcom,mdss-dsi-virtual-channel-id = <0>;
+		qcom,mdss-dsi-stream = <0>;
+		qcom,mdss-dsi-panel-width = <720>;
+		qcom,mdss-dsi-panel-height = <1280>;
+		qcom,mdss-dsi-h-front-porch = <44>;
+		qcom,mdss-dsi-h-back-porch = <55>;
+		qcom,mdss-dsi-h-pulse-width = <11>;
+		qcom,mdss-dsi-h-sync-skew = <0>;
+		qcom,mdss-dsi-v-back-porch = <15>;
+		qcom,mdss-dsi-v-front-porch = <14>;
+		qcom,mdss-dsi-v-pulse-width = <1>;
+		qcom,mdss-dsi-h-left-border = <0>;
+		qcom,mdss-dsi-h-right-border = <0>;
+		qcom,mdss-dsi-v-top-border = <0>;
+		qcom,mdss-dsi-v-bottom-border = <0>;
+		qcom,mdss-dsi-bpp = <24>;
+		qcom,mdss-dsi-color-order = <0>;
+		qcom,mdss-dsi-underflow-color = <0xff>;
+		qcom,mdss-dsi-border-color = <0>;
+		qcom,mdss-dsi-pixel-packing = <0>;
+		qcom,mdss-dsi-on-command = [29 01 00 00 00 00 06 F0 55 AA 52 08 00
+				29 01 00 00 00 00 03 B1 68 21
+				23 01 00 00 00 00 02 B5 C8
+				29 01 00 00 00 00 02 B6 0F
+				29 01 00 00 00 00 05 B8 00 00 0A 00
+				23 01 00 00 00 00 02 B9 00
+				23 01 00 00 00 00 02 BA 02
+				29 01 00 00 00 00 03 BB 63 63
+				29 01 00 00 00 00 03 BC 00 00
+				29 01 00 00 00 00 06 BD 02 7F 0D 0B 00
+				29 01 00 00 00 00 11 CC 41 36 87 54 46 65 10 12 14 10 12 14 40 08 15 05
+				23 01 00 00 00 00 02 D0 00
+				29 01 00 00 00 00 11 D1 00 04 08 0C 10 14 18 1C 20 24 28 2C 30 34 38 3C
+				23 01 00 00 00 00 02 D3 00
+				29 01 00 00 00 00 03 D6 44 44
+				29 01 00 00 00 00 0D D7 00 00 00 00 00 00 00 00 00 00 00 00
+				29 01 00 00 00 00 0E D8 00 00 00 00 00 00 00 00 00 00 00 00 00
+				29 01 00 00 00 00 03 D9 00 28
+				29 01 00 00 00 00 03 E5 00 FF
+				29 01 00 00 00 00 05 E6 F3 EC E7 DF
+				29 01 00 00 00 00 0B E7 F3 D9 CC CD B3 A6 99 99 99 95
+				29 01 00 00 00 00 0B E8 F3 D9 CC CD B3 A6 99 99 99 95
+				29 01 00 00 00 00 03 E9 00 04
+				23 01 00 00 00 00 02 EA 00
+				29 01 00 00 00 00 05 EE 87 78 00 00
+				29 01 00 00 00 00 03 EF 07 FF
+				29 01 00 00 00 00 06 F0 55 AA 52 08 01
+				29 01 00 00 00 00 03 B0 0D 0D
+				29 01 00 00 00 00 03 B1 0D 0D
+				29 01 00 00 00 00 03 B3 2D 2D
+				29 01 00 00 00 00 03 B4 19 19
+				29 01 00 00 00 00 03 B5 06 06
+				29 01 00 00 00 00 03 B6 05 05
+				29 01 00 00 00 00 03 B7 05 05
+				29 01 00 00 00 00 03 B8 05 05
+				29 01 00 00 00 00 03 B9 44 44
+				29 01 00 00 00 00 03 BA 36 36
+				29 01 00 00 00 00 03 BC 50 00
+				29 01 00 00 00 00 03 BD 50 00
+				23 01 00 00 00 00 02 BE 39
+				23 01 00 00 00 00 02 BF 39
+				23 01 00 00 00 00 02 C0 0C
+				23 01 00 00 00 00 02 C1 00
+				29 01 00 00 00 00 03 C2 19 19
+				29 01 00 00 00 00 03 C3 0A 0A
+				29 01 00 00 00 00 03 C4 23 23
+				29 01 00 00 00 00 04 C7 00 80 00
+				29 01 00 00 00 00 07 C9 00 00 00 00 00 00
+				23 01 00 00 00 00 02 CA 01
+				29 01 00 00 00 00 03 CB 0B 53
+				23 01 00 00 00 00 02 CC 00
+				29 01 00 00 00 00 04 CD 0B 52 53
+				23 01 00 00 00 00 02 CE 44
+				29 01 00 00 00 00 04 CF 00 50 50
+				29 01 00 00 00 00 03 D0 50 50
+				29 01 00 00 00 00 03 D1 50 50
+				23 01 00 00 00 00 02 D2 39
+				23 01 00 00 00 00 02 D3 39
+				29 01 00 00 00 00 06 F0 55 AA 52 08 02
+				29 01 00 00 00 00 11 B0 00 AC 00 BA 00 D9 00 ED 01 01 01 1E 01 3A 01 62
+				29 01 00 00 00 00 11 B1 01 85 01 B8 01 E4 02 27 02 5B 02 5D 02 8C 02 BE
+				29 01 00 00 00 00 11 B2 02 DF 03 0C 03 2A 03 51 03 6D 03 8D 03 A4 03 BE
+				29 01 00 00 00 00 05 B3 03 CC 03 CC
+				29 01 00 00 00 00 11 B4 00 AC 00 BA 00 D9 00 ED 01 01 01 1E 01 3A 01 62
+				29 01 00 00 00 00 11 B5 01 85 01 B8 01 E4 02 27 02 5B 02 5D 02 8C 02 BE
+				29 01 00 00 00 00 11 B6 02 DF 03 0C 03 2A 03 51 03 6D 03 8D 03 A4 03 BE
+				29 01 00 00 00 00 05 B7 03 CC 03 CC
+				29 01 00 00 00 00 11 B8 00 AC 00 BA 00 D9 00 ED 01 01 01 1E 01 3A 01 62
+				29 01 00 00 00 00 11 B9 01 85 01 B8 01 E4 02 27 02 5B 02 5D 02 8C 02 BE
+				29 01 00 00 00 00 11 BA 02 DF 03 0C 03 2A 03 51 03 6D 03 8D 03 A4 03 BE
+				29 01 00 00 00 00 05 BB 03 CC 03 CC
+				29 01 00 00 00 00 11 BC 00 AC 00 BA 00 D9 00 ED 01 01 01 1E 01 3A 01 62
+				29 01 00 00 00 00 11 BD 01 85 01 B8 01 E4 02 27 02 5B 02 5D 02 8C 02 BE
+				29 01 00 00 00 00 11 BE 02 DF 03 0C 03 2A 03 51 03 6D 03 8D 03 A4 03 BE
+				29 01 00 00 00 00 05 BF 03 CC 03 CC
+				29 01 00 00 00 00 11 C0 00 AC 00 BA 00 D9 00 ED 01 01 01 1E 01 3A 01 62
+				29 01 00 00 00 00 11 C1 01 85 01 B8 01 E4 02 27 02 5B 02 5D 02 8C 02 BE
+				29 01 00 00 00 00 11 C2 02 DF 03 0C 03 2A 03 51 03 6D 03 8D 03 A4 03 BE
+				29 01 00 00 00 00 05 C3 03 CC 03 CC
+				29 01 00 00 00 00 11 C4 00 AC 00 BA 00 D9 00 ED 01 01 01 1E 01 3A 01 62
+				29 01 00 00 00 00 11 C5 01 85 01 B8 01 E4 02 27 02 5B 02 5D 02 8C 02 BE
+				29 01 00 00 00 00 11 C6 02 DF 03 0C 03 2A 03 51 03 6D 03 8D 03 A4 03 BE
+				29 01 00 00 00 00 05 C7 03 CC 03 CC
+				23 01 00 00 00 00 02 EE 00
+				29 01 00 00 00 00 06 F0 55 AA 52 08 03
+				29 01 00 00 00 00 03 B0 00 00
+				29 01 00 00 00 00 03 B1 00 00
+				29 01 00 00 00 00 06 B2 03 00 00 00 00
+				29 01 00 00 00 00 06 B3 03 00 00 00 00
+				29 01 00 00 00 00 06 B4 03 00 00 00 00
+				29 01 00 00 00 00 06 B5 03 00 00 00 00
+				29 01 00 00 00 00 06 B6 03 00 00 00 00
+				29 01 00 00 00 00 06 B7 03 00 00 00 00
+				29 01 00 00 00 00 06 B8 03 00 00 00 00
+				29 01 00 00 00 00 06 B9 03 00 00 00 00
+				29 01 00 00 00 00 06 BA 35 10 00 00 00
+				29 01 00 00 00 00 06 BB 35 10 00 00 00
+				29 01 00 00 00 00 06 BC 35 10 00 00 00
+				29 01 00 00 00 00 06 BD 35 10 00 00 00
+				29 01 00 00 00 00 05 C0 00 34 00 00
+				29 01 00 00 00 00 05 C1 00 34 00 00
+				29 01 00 00 00 00 05 C2 00 34 00 00
+				29 01 00 00 00 00 05 C3 00 34 00 00
+				23 01 00 00 00 00 02 C4 40
+				23 01 00 00 00 00 02 C5 40
+				23 01 00 00 00 00 02 C6 40
+				23 01 00 00 00 00 02 C7 40
+				23 01 00 00 00 00 02 EF 00
+				29 01 00 00 00 00 06 F0 55 AA 52 08 05
+				29 01 00 00 00 00 03 B0 1B 10
+				29 01 00 00 00 00 03 B1 1B 10
+				29 01 00 00 00 00 03 B2 1B 10
+				29 01 00 00 00 00 03 B3 1B 10
+				29 01 00 00 00 00 03 B4 1B 10
+				29 01 00 00 00 00 03 B5 1B 10
+				29 01 00 00 00 00 03 B6 1B 10
+				29 01 00 00 00 00 03 B7 1B 10
+				23 01 00 00 00 00 02 B8 00
+				23 01 00 00 00 00 02 B9 00
+				23 01 00 00 00 00 02 BA 00
+				23 01 00 00 00 00 02 BB 00
+				23 01 00 00 00 00 02 BC 00
+				29 01 00 00 00 00 06 BD 03 03 03 00 01
+				23 01 00 00 00 00 02 C0 03
+				23 01 00 00 00 00 02 C1 05
+				23 01 00 00 00 00 02 C2 03
+				23 01 00 00 00 00 02 C3 05
+				23 01 00 00 00 00 02 C4 80
+				23 01 00 00 00 00 02 C5 A2
+				23 01 00 00 00 00 02 C6 80
+				23 01 00 00 00 00 02 C7 A2
+				29 01 00 00 00 00 03 C8 01 20
+				29 01 00 00 00 00 03 C9 00 20
+				29 01 00 00 00 00 03 CA 01 00
+				29 01 00 00 00 00 03 CB 00 00
+				29 01 00 00 00 00 04 CC 00 00 01
+				29 01 00 00 00 00 04 CD 00 00 01
+				29 01 00 00 00 00 04 CE 00 00 01
+				29 01 00 00 00 00 04 CF 00 00 01
+				23 01 00 00 00 00 02 D0 00
+				29 01 00 00 00 00 06 D1 03 00 00 07 10
+				29 01 00 00 00 00 06 D2 13 00 00 07 11
+				29 01 00 00 00 00 06 D3 23 00 00 07 10
+				29 01 00 00 00 00 06 D4 33 00 00 07 11
+				23 01 00 00 00 00 02 E5 06
+				23 01 00 00 00 00 02 E6 06
+				23 01 00 00 00 00 02 E7 06
+				23 01 00 00 00 00 02 E8 06
+				23 01 00 00 00 00 02 E9 06
+				23 01 00 00 00 00 02 EA 06
+				23 01 00 00 00 00 02 EB 06
+				23 01 00 00 00 00 02 EC 06
+				23 01 00 00 00 00 02 ED 31
+				29 01 00 00 00 00 06 F0 55 AA 52 08 06
+				29 01 00 00 00 00 03 B0 10 11
+				29 01 00 00 00 00 03 B1 12 13
+				29 01 00 00 00 00 03 B2 08 00
+				29 01 00 00 00 00 03 B3 2D 2D
+				29 01 00 00 00 00 03 B4 2D 34
+				29 01 00 00 00 00 03 B5 34 2D
+				29 01 00 00 00 00 03 B6 2D 34
+				29 01 00 00 00 00 03 B7 34 34
+				29 01 00 00 00 00 03 B8 02 0A
+				29 01 00 00 00 00 03 B9 00 08
+				29 01 00 00 00 00 03 BA 09 01
+				29 01 00 00 00 00 03 BB 0B 03
+				29 01 00 00 00 00 03 BC 34 34
+				29 01 00 00 00 00 03 BD 34 2D
+				29 01 00 00 00 00 03 BE 2D 34
+				29 01 00 00 00 00 03 BF 34 2D
+				29 01 00 00 00 00 03 C0 2D 2D
+				29 01 00 00 00 00 03 C1 01 09
+				29 01 00 00 00 00 03 C2 19 18
+				29 01 00 00 00 00 03 C3 17 16
+				29 01 00 00 00 00 03 C4 19 18
+				29 01 00 00 00 00 03 C5 17 16
+				29 01 00 00 00 00 03 C6 01 09
+				29 01 00 00 00 00 03 C7 2D 2D
+				29 01 00 00 00 00 03 C8 2D 34
+				29 01 00 00 00 00 03 C9 34 2D
+				29 01 00 00 00 00 03 CA 2D 34
+				29 01 00 00 00 00 03 CB 34 34
+				29 01 00 00 00 00 03 CC 0B 03
+				29 01 00 00 00 00 03 CD 09 01
+				29 01 00 00 00 00 03 CE 00 08
+				29 01 00 00 00 00 03 CF 02 0A
+				29 01 00 00 00 00 03 D0 34 34
+				29 01 00 00 00 00 03 D1 34 2D
+				29 01 00 00 00 00 03 D2 2D 34
+				29 01 00 00 00 00 03 D3 34 2D
+				29 01 00 00 00 00 03 D4 2D 2D
+				29 01 00 00 00 00 03 D5 08 00
+				29 01 00 00 00 00 03 D6 10 11
+				29 01 00 00 00 00 03 D7 12 13
+				29 01 00 00 00 00 06 D8 55 55 55 55 55
+				29 01 00 00 00 00 06 D9 55 55 55 55 55
+				29 01 00 00 00 00 03 E5 34 34
+				29 01 00 00 00 00 03 E6 34 34
+				23 01 00 00 00 00 02 E7 05
+				29 01 00 00 00 00 06 F0 55 AA 52 00 00
+				05 01 00 00 32 00 02 11 00
+				05 01 00 00 96 00 02 29 00
+				29 01 00 00 00 00 06 F0 55 AA 52 08 01
+				29 01 00 00 00 00 06 F0 55 AA 52 00 00
+				29 01 00 00 00 00 02 53 2C];
+		qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00
+					05 01 00 00 78 00 02 10 00];
+		qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+		qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+		qcom,mdss-dsi-h-sync-pulse = <1>;
+		qcom,mdss-dsi-traffic-mode = <2>;
+		qcom,mdss-dsi-lane-map = <0>;
+		qcom,mdss-dsi-bllp-eof-power-mode;
+		qcom,mdss-dsi-bllp-power-mode;
+		qcom,mdss-dsi-lane-0-state;
+		qcom,mdss-dsi-lane-1-state;
+		qcom,mdss-dsi-lane-2-state;
+		qcom,mdss-dsi-lane-3-state;
+		qcom,mdss-dsi-panel-timings = [93 1F 17 00 2F 2E 1C 21 26 03 04 00];
+		qcom,mdss-dsi-t-clk-post = <0x20>;
+		qcom,mdss-dsi-t-clk-pre = <0x2D>;
+		qcom,mdss-dsi-bl-min-level = <1>;
+		qcom,mdss-dsi-bl-max-level = <255>;
+		qcom,mdss-dsi-dma-trigger = <4>;
+		qcom,mdss-dsi-mdp-trigger = <0>;
+		qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs";
+
+	};
+};
diff --git a/arch/arm/boot/dts/mpq8092.dtsi b/arch/arm/boot/dts/mpq8092.dtsi
index 52bcb2c..9a37316 100644
--- a/arch/arm/boot/dts/mpq8092.dtsi
+++ b/arch/arm/boot/dts/mpq8092.dtsi
@@ -229,6 +229,15 @@
 		qcom,current-limit = <800>;
 	};
 
+	qcom,sps@f9980000 {
+		compatible = "qcom,msm_sps";
+		reg = <0xf9984000 0x15000>,
+		      <0xf9999000 0xb000>;
+		reg-names = "bam_mem", "core_mem";
+		interrupts = <0 94 0>;
+		qcom,pipe-attr-ee;
+	};
+
 	sata: sata@fc580000 {
 		compatible = "qcom,msm-ahci";
 		reg = <0xfc580000 0x17c>;
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi
index d4b605b..f807814 100644
--- a/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi
@@ -68,6 +68,47 @@
 		qcom,cci-master = <0>;
 	};
 
+    qcom,camera@20 {
+		compatible = "qcom,imx135";
+		reg = <0x20>;
+		qcom,slave-id = <0x20 0x0016 0x0135>;
+		qcom,csiphy-sd-index = <0>;
+		qcom,csid-sd-index = <0>;
+		qcom,mount-angle = <90>;
+		qcom,sensor-name = "imx135";
+		cam_vdig-supply = <&pm8226_l5>;
+		cam_vana-supply = <&pm8226_l19>;
+		cam_vio-supply = <&pm8226_lvs1>;
+		cam_vaf-supply = <&pm8226_l15>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+				     "cam_vaf";
+		qcom,cam-vreg-type = <0 1 0 0>;
+		qcom,cam-vreg-min-voltage = <1200000 0 2850000 2800000>;
+		qcom,cam-vreg-max-voltage = <1200000 0 2850000 2800000>;
+		qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+		qcom,gpio-no-mux = <0>;
+		gpios = <&msmgpio 26 0>,
+			<&msmgpio 37 0>,
+			<&msmgpio 36 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+			"CAM_RESET1",
+			"CAM_STANDBY";
+		qcom,gpio-set-tbl-num = <1 1>;
+		qcom,gpio-set-tbl-flags = <0 2>;
+		qcom,gpio-set-tbl-delay = <1000 30000>;
+		qcom,csi-lane-assign = <0x4320>;
+		qcom,csi-lane-mask = <0x1F>;
+		qcom,sensor-position = <0>;
+		qcom,sensor-mode = <0>;
+	        qcom,sensor-type = <0>;
+		qcom,cci-master = <0>;
+		status = "ok";
+	};
+
 	qcom,camera@6d {
 		compatible = "qcom,ov9724";
 		reg = <0x6d>;
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
index 53860ac..56e8a09 100644
--- a/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
@@ -38,7 +38,7 @@
 		qcom,csid-sd-index = <0>;
 		qcom,actuator-src = <&actuator0>;
 		qcom,led-flash-src = <&led_flash0>;
-		qcom,mount-angle = <0>;
+		qcom,mount-angle = <90>;
 		qcom,sensor-name = "ov8825";
 		cam_vdig-supply = <&pm8226_l5>;
 		cam_vana-supply = <&pm8226_l19>;
diff --git a/arch/arm/boot/dts/msm8226-sim.dts b/arch/arm/boot/dts/msm8226-sim.dts
index 2405646..1da94b3 100644
--- a/arch/arm/boot/dts/msm8226-sim.dts
+++ b/arch/arm/boot/dts/msm8226-sim.dts
@@ -12,7 +12,6 @@
 
 /dts-v1/;
 /include/ "msm8226.dtsi"
-/include/ "msm8226-camera.dtsi"
 
 / {
 	model = "Qualcomm MSM 8226 Simulator";
diff --git a/arch/arm/boot/dts/msm8226-v1-mtp.dts b/arch/arm/boot/dts/msm8226-v1-mtp.dts
index b1d46b1..6f03dca 100644
--- a/arch/arm/boot/dts/msm8226-v1-mtp.dts
+++ b/arch/arm/boot/dts/msm8226-v1-mtp.dts
@@ -23,3 +23,10 @@
 		      <198 8 0>,
 		      <205 8 0>;
 };
+
+&cci {
+	/* Rotate rear camera to 0 degrees */
+	qcom,camera@6f {
+	qcom,mount-angle = <0>;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts b/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts
index 936f87f..3e0e4e4 100644
--- a/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts
+++ b/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts
@@ -13,7 +13,7 @@
 /dts-v1/;
 /include/ "msm8226-v1.dtsi"
 /include/ "msm8226-qrd.dtsi"
-/include/ "dsi-panel-nt35590-720p-video.dtsi"
+/include/ "dsi-panel-nt35521-720p-video.dtsi"
 
 / {
 	model = "Qualcomm MSM 8226 QRD";
@@ -26,9 +26,9 @@
 };
 
 &soc {
-	qcom,mdss_dsi_nt35590_720p_video {
+	qcom,mdss_dsi_nt35521_720p_video {
 		status = "ok";
-		qcom,mdss-pan-bl-ctrl = "bl_ctrl_dcs";
+		qcom,cont-splash-enabled;
 	};
 
 	sound {
diff --git a/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts b/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts
index b34fb94..0a4657d 100644
--- a/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts
+++ b/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts
@@ -13,7 +13,7 @@
 /dts-v1/;
 /include/ "msm8226-v2.dtsi"
 /include/ "msm8226-qrd.dtsi"
-/include/ "dsi-panel-nt35590-720p-video.dtsi"
+/include/ "dsi-panel-nt35521-720p-video.dtsi"
 
 / {
 	model = "Qualcomm MSM 8226v2 QRD";
@@ -27,9 +27,9 @@
 };
 
 &soc {
-	qcom,mdss_dsi_nt35590_720p_video {
+	qcom,mdss_dsi_nt35521_720p_video {
 		status = "ok";
-		qcom,mdss-pan-bl-ctrl = "bl_ctrl_dcs";
+		qcom,cont-splash-enabled;
 	};
 
 	sound {
diff --git a/arch/arm/boot/dts/msm8226-v2.dtsi b/arch/arm/boot/dts/msm8226-v2.dtsi
index 1dab78a..2b3b7c2 100644
--- a/arch/arm/boot/dts/msm8226-v2.dtsi
+++ b/arch/arm/boot/dts/msm8226-v2.dtsi
@@ -17,7 +17,6 @@
  */
 
 /include/ "msm8226.dtsi"
-/include/ "msm8226-camera.dtsi"
 
 &pm8226_l3 {
 	regulator-min-microvolt = <750000>;
diff --git a/arch/arm/boot/dts/msm8926.dtsi b/arch/arm/boot/dts/msm8926.dtsi
index f46b714..013da90a 100644
--- a/arch/arm/boot/dts/msm8926.dtsi
+++ b/arch/arm/boot/dts/msm8926.dtsi
@@ -17,7 +17,6 @@
  */
 
 /include/ "msm8226.dtsi"
-/include/ "msm8226-camera.dtsi"
 
 / {
 	model = "Qualcomm MSM 8926";
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index fa57244..9badf6d 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.dtsi
@@ -271,11 +271,11 @@
 			qcom,default-state = "on";
 			qcom,max-current = <25>;
 			qcom,ctrl-delay-us = <0>;
-			qcom,boost-curr-lim = <3>;
+			qcom,boost-curr-lim = <5>;
 			qcom,cp-sel = <0>;
 			qcom,switch-freq = <11>;
 			qcom,ovp-val = <2>;
-			qcom,num-strings = <1>;
+			qcom,num-strings = <3>;
 			qcom,id = <0>;
 		};
 	};
diff --git a/arch/arm/boot/dts/msm8974-fluid.dtsi b/arch/arm/boot/dts/msm8974-fluid.dtsi
index 3d20f7c..9c2509a 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-fluid.dtsi
@@ -269,11 +269,11 @@
 			qcom,default-state = "on";
 			qcom,max-current = <25>;
 			qcom,ctrl-delay-us = <0>;
-			qcom,boost-curr-lim = <3>;
+			qcom,boost-curr-lim = <5>;
 			qcom,cp-sel = <0>;
 			qcom,switch-freq = <11>;
 			qcom,ovp-val = <2>;
-			qcom,num-strings = <1>;
+			qcom,num-strings = <3>;
 			qcom,id = <0>;
 		};
 	};
diff --git a/arch/arm/boot/dts/msm8974-mtp.dtsi b/arch/arm/boot/dts/msm8974-mtp.dtsi
index c1a8792..6955597 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-mtp.dtsi
@@ -210,11 +210,11 @@
 			qcom,default-state = "on";
 			qcom,max-current = <25>;
 			qcom,ctrl-delay-us = <0>;
-			qcom,boost-curr-lim = <3>;
+			qcom,boost-curr-lim = <5>;
 			qcom,cp-sel = <0>;
 			qcom,switch-freq = <11>;
 			qcom,ovp-val = <2>;
-			qcom,num-strings = <1>;
+			qcom,num-strings = <3>;
 			qcom,id = <0>;
 		};
 	};
diff --git a/arch/arm/boot/dts/msmsamarium-regulator.dtsi b/arch/arm/boot/dts/msmsamarium-regulator.dtsi
new file mode 100644
index 0000000..ae4dc8d
--- /dev/null
+++ b/arch/arm/boot/dts/msmsamarium-regulator.dtsi
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+/* QPNP controlled regulators: */
+
+&spmi_bus {
+	qcom,pma8084@1 {
+		pma8084_s1: regulator@1400 {
+			regulator-min-microvolt = <1050000>;
+			regulator-max-microvolt = <1050000>;
+			qcom,enable-time = <500>;
+			qcom,pull-down-enable = <1>;
+			regulator-always-on;
+			qcom,system-load = <100000>;
+			status = "okay";
+		};
+
+		/* PMA8084 S2 + S12 = 2 phase VDD_CX supply */
+		pma8084_s2: regulator@1700 {
+			regulator-min-microvolt = <1050000>;
+			regulator-max-microvolt = <1050000>;
+			qcom,enable-time = <500>;
+			qcom,pull-down-enable = <1>;
+			regulator-always-on;
+			qcom,system-load = <100000>;
+			status = "okay";
+		};
+
+		pma8084_s3: regulator@1a00 {
+			regulator-min-microvolt = <1300000>;
+			regulator-max-microvolt = <1300000>;
+			qcom,enable-time = <500>;
+			qcom,pull-down-enable = <1>;
+			regulator-always-on;
+			qcom,system-load = <100000>;
+			status = "okay";
+		};
+
+		pma8084_s4: regulator@1d00 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,enable-time = <500>;
+			qcom,pull-down-enable = <1>;
+			regulator-always-on;
+			qcom,system-load = <100000>;
+			status = "okay";
+		};
+
+		/* Output of PMA8084 S5 and L25 is tied together. */
+		pma8084_s5: regulator@2000 {
+			regulator-min-microvolt = <2150000>;
+			regulator-max-microvolt = <2150000>;
+			qcom,enable-time = <500>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_s6: regulator@2300 {
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1050000>;
+			qcom,enable-time = <500>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_s7: regulator@2600 {
+			regulator-min-microvolt = <815000>;
+			regulator-max-microvolt = <900000>;
+			qcom,enable-time = <500>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_s8: regulator@2900 {
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1100000>;
+			qcom,enable-time = <500>;
+			qcom,pull-down-enable = <1>;
+			regulator-always-on;
+			qcom,system-load = <100000>;
+			status = "okay";
+		};
+
+		pma8084_s9: regulator@2c00 {
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1100000>;
+			qcom,enable-time = <500>;
+			qcom,pull-down-enable = <1>;
+			regulator-always-on;
+			qcom,system-load = <100000>;
+			status = "okay";
+		};
+
+		pma8084_s10: regulator@2f00 {
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1100000>;
+			qcom,enable-time = <500>;
+			qcom,pull-down-enable = <1>;
+			regulator-always-on;
+			qcom,system-load = <100000>;
+			status = "okay";
+		};
+
+		pma8084_s11: regulator@3200 {
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1100000>;
+			qcom,enable-time = <500>;
+			qcom,pull-down-enable = <1>;
+			regulator-always-on;
+			qcom,system-load = <100000>;
+			status = "okay";
+		};
+
+		pma8084_l1: regulator@4000 {
+			parent-supply = <&pma8084_s3>;
+			regulator-min-microvolt = <1225000>;
+			regulator-max-microvolt = <1225000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			regulator-always-on;
+			qcom,system-load = <10000>;
+			status = "okay";
+		};
+
+		pma8084_l2: regulator@4100 {
+			parent-supply = <&pma8084_s3>;
+			regulator-min-microvolt = <1175000>;
+			regulator-max-microvolt = <1175000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l3: regulator@4200 {
+			parent-supply = <&pma8084_s3>;
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l4: regulator@4300 {
+			parent-supply = <&pma8084_s3>;
+			regulator-min-microvolt = <1225000>;
+			regulator-max-microvolt = <1225000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l6: regulator@4500 {
+			parent-supply = <&pma8084_s5>;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l8: regulator@4700 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l9: regulator@4800 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l10: regulator@4900 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l11: regulator@4a00 {
+			parent-supply = <&pma8084_s3>;
+			regulator-min-microvolt = <1300000>;
+			regulator-max-microvolt = <1300000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l12: regulator@4b00 {
+			parent-supply = <&pma8084_s5>;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l13: regulator@4c00 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2950000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l14: regulator@4d00 {
+			parent-supply = <&pma8084_s5>;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l15: regulator@4e00 {
+			parent-supply = <&pma8084_s5>;
+			regulator-min-microvolt = <2050000>;
+			regulator-max-microvolt = <2050000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l16: regulator@4f00 {
+			regulator-min-microvolt = <2700000>;
+			regulator-max-microvolt = <2700000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l17: regulator@5000 {
+			regulator-min-microvolt = <2850000>;
+			regulator-max-microvolt = <2850000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l18: regulator@5100 {
+			regulator-min-microvolt = <2850000>;
+			regulator-max-microvolt = <2850000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l19: regulator@5200 {
+			regulator-min-microvolt = <2900000>;
+			regulator-max-microvolt = <2900000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l20: regulator@5300 {
+			regulator-min-microvolt = <2950000>;
+			regulator-max-microvolt = <2950000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l21: regulator@5400 {
+			regulator-min-microvolt = <2950000>;
+			regulator-max-microvolt = <2950000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l22: regulator@5500 {
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3000000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l23: regulator@5600 {
+			regulator-min-microvolt = <2850000>;
+			regulator-max-microvolt = <2850000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l24: regulator@5700 {
+			regulator-min-microvolt = <3075000>;
+			regulator-max-microvolt = <3075000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l26: regulator@5900 {
+			parent-supply = <&pma8084_s5>;
+			regulator-min-microvolt = <2050000>;
+			regulator-max-microvolt = <2050000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_l27: regulator@5a00 {
+			parent-supply = <&pma8084_s3>;
+			regulator-min-microvolt = <1050000>;
+			regulator-max-microvolt = <1050000>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_lvs1: regulator@8000 {
+			parent-supply = <&pma8084_s4>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_lvs2: regulator@8100 {
+			parent-supply = <&pma8084_s4>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_lvs3: regulator@8200 {
+			parent-supply = <&pma8084_s4>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_lvs4: regulator@8300 {
+			parent-supply = <&pma8084_s4>;
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+
+		pma8084_mvs1: regulator@8400 {
+			qcom,enable-time = <200>;
+			qcom,pull-down-enable = <1>;
+			status = "okay";
+		};
+	};
+};
+
+&soc {
+	pma8084_s2_corner: s2_corner_vreg {
+		compatible = "qcom,stub-regulator";
+		regulator-name = "8084_s2_corner";
+		regulator-min-microvolt = <1>;
+		regulator-max-microvolt = <7>;
+		qcom,hpm-min-load = <100000>;
+		qcom,consumer-supplies = "vdd_dig", "";
+	};
+};
diff --git a/arch/arm/boot/dts/msmsamarium.dtsi b/arch/arm/boot/dts/msmsamarium.dtsi
index d76c2c1..a492561 100644
--- a/arch/arm/boot/dts/msmsamarium.dtsi
+++ b/arch/arm/boot/dts/msmsamarium.dtsi
@@ -257,3 +257,4 @@
 };
 
 /include/ "msm-pma8084.dtsi"
+/include/ "msmsamarium-regulator.dtsi"
diff --git a/arch/arm/configs/apq8084_defconfig b/arch/arm/configs/apq8084_defconfig
index 4315d3f..f4ad0c4 100644
--- a/arch/arm/configs/apq8084_defconfig
+++ b/arch/arm/configs/apq8084_defconfig
@@ -402,9 +402,11 @@
 CONFIG_CRYPTO_DEV_QCEDEV=m
 CONFIG_CRC_CCITT=y
 CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_FUSE=y
 CONFIG_CORESIGHT_TMC=y
 CONFIG_CORESIGHT_FUNNEL=y
 CONFIG_CORESIGHT_REPLICATOR=y
 CONFIG_CORESIGHT_STM=y
+CONFIG_CORESIGHT_HWEVENT=y
 CONFIG_CORESIGHT_ETM=y
 CONFIG_USB_BAM=y
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index f2f6558..7901e93 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -480,3 +480,4 @@
 CONFIG_CRYPTO_DEV_QCE=y
 CONFIG_CRYPTO_DEV_QCEDEV=y
 CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y
+CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 71742a5..8520f23 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -514,3 +514,4 @@
 CONFIG_CRYPTO_DEV_QCE=y
 CONFIG_CRYPTO_DEV_QCEDEV=y
 CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y
+CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index cd71104..e4a647f 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -24,7 +24,7 @@
 
 obj-y += acpuclock.o
 obj-$(CONFIG_HW_PERF_EVENTS) += perf_trace_counters.o
-obj-$(CONFIG_ARCH_MSM_KRAIT) += acpuclock-krait.o
+obj-$(CONFIG_ARCH_MSM_KRAIT) += acpuclock-krait.o clock-krait.o
 ifdef CONFIG_ARCH_MSM_KRAIT
 obj-$(CONFIG_DEBUG_FS) += acpuclock-krait-debug.o
 endif
diff --git a/arch/arm/mach-msm/board-samarium.c b/arch/arm/mach-msm/board-samarium.c
index 9f865a9..52a947b 100644
--- a/arch/arm/mach-msm/board-samarium.c
+++ b/arch/arm/mach-msm/board-samarium.c
@@ -36,6 +36,10 @@
 #include "modem_notifier.h"
 
 static struct clk_lookup msm_clocks_dummy[] = {
+	CLK_DUMMY("xo",                CXO_CLK, "fc880000.qcom,mss", OFF),
+	CLK_DUMMY("bus_clk",   MSS_BIMC_Q6_CLK, "fc880000.qcom,mss", OFF),
+	CLK_DUMMY("iface_clk", MSS_CFG_AHB_CLK, "fc880000.qcom,mss", OFF),
+	CLK_DUMMY("mem_clk",  BOOT_ROM_AHB_CLK, "fc880000.qcom,mss", OFF),
 	CLK_DUMMY("core_clk",   BLSP1_UART_CLK, "f991f000.serial", OFF),
 	CLK_DUMMY("iface_clk",  BLSP1_UART_CLK, "f991f000.serial", OFF),
 	CLK_DUMMY("core_clk",	SDC1_CLK,	"msm_sdcc.1", OFF),
diff --git a/arch/arm/mach-msm/clock-8084.c b/arch/arm/mach-msm/clock-8084.c
index fd1714c..939a637 100644
--- a/arch/arm/mach-msm/clock-8084.c
+++ b/arch/arm/mach-msm/clock-8084.c
@@ -415,6 +415,7 @@
 	CLK_DUMMY("core_clk", qdss_clk.c, "fc342000.cti", OFF),
 	CLK_DUMMY("core_clk", qdss_clk.c, "fc343000.cti", OFF),
 	CLK_DUMMY("core_clk", qdss_clk.c, "fc344000.cti", OFF),
+	CLK_DUMMY("core_clk", qdss_clk.c, "fd828018.hwevent", OFF),
 
 	CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc326000.tmc", OFF),
 	CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc324000.replicator", OFF),
@@ -444,6 +445,10 @@
 	CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc342000.cti", OFF),
 	CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc343000.cti", OFF),
 	CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc344000.cti", OFF),
+	CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fd828018.hwevent", OFF),
+
+	CLK_DUMMY("core_mmss_clk", mmss_misc_ahb_clk.c, "fd828018.hwevent",
+		  OFF),
 
 	CLK_DUMMY("iface_clk", gcc_prng_ahb_clk.c,
 					"f9bff000.qcom,msm-rng", OFF),
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index 383af54..8a79687 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -3389,11 +3389,13 @@
 	CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6d.qcom,camera"),
 	CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6a.qcom,camera"),
 	CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6c.qcom,camera"),
+	CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "20.qcom,camera"),
 	CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6f.qcom,camera"),
 	CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "90.qcom,camera"),
 	CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6d.qcom,camera"),
 	CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6a.qcom,camera"),
 	CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6c.qcom,camera"),
+	CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "20.qcom,camera"),
 
 	/* eeprom clocks */
 	CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6c.qcom,eeprom"),
diff --git a/arch/arm/mach-msm/clock-krait.c b/arch/arm/mach-msm/clock-krait.c
new file mode 100644
index 0000000..b96ba62
--- /dev/null
+++ b/arch/arm/mach-msm/clock-krait.c
@@ -0,0 +1,521 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+
+#include <linux/clk.h>
+#include <mach/clk-provider.h>
+#include <mach/clk.h>
+#include <mach/clock-generic.h>
+#include <mach/msm-krait-l2-accessors.h>
+#include "clock-krait.h"
+#include "avs.h"
+
+static DEFINE_SPINLOCK(kpss_clock_reg_lock);
+
+static void __kpss_mux_set_sel(struct mux_clk *mux, int sel)
+{
+	unsigned long flags;
+	u32 regval;
+
+	spin_lock_irqsave(&kpss_clock_reg_lock, flags);
+	regval = get_l2_indirect_reg(mux->offset);
+	regval &= ~(mux->mask << mux->shift);
+	regval |= (sel & mux->mask) << mux->shift;
+	set_l2_indirect_reg(mux->offset, regval);
+	spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);
+
+	/* Wait for switch to complete. */
+	mb();
+	udelay(1);
+}
+static int kpss_mux_set_sel(struct mux_clk *mux, int sel)
+{
+	mux->en_mask = sel;
+	if (mux->c.count)
+		__kpss_mux_set_sel(mux, sel);
+	return 0;
+}
+
+static int kpss_mux_get_sel(struct mux_clk *mux)
+{
+	u32 sel;
+
+	sel = get_l2_indirect_reg(mux->offset);
+	sel >>= mux->shift;
+	sel &= mux->mask;
+	mux->en_mask = sel;
+
+	return sel;
+}
+
+static int kpss_mux_enable(struct mux_clk *mux)
+{
+	__kpss_mux_set_sel(mux, mux->en_mask);
+	return 0;
+}
+
+static void kpss_mux_disable(struct mux_clk *mux)
+{
+	__kpss_mux_set_sel(mux, mux->safe_sel);
+}
+
+struct clk_mux_ops clk_mux_ops_kpss = {
+	.enable = kpss_mux_enable,
+	.disable = kpss_mux_disable,
+	.set_mux_sel = kpss_mux_set_sel,
+	.get_mux_sel = kpss_mux_get_sel,
+};
+
+/*
+ * The divider can divide by 2, 4, 6 and 8. But we only really need div-2. So
+ * force it to div-2 during handoff and treat it like a fixed div-2 clock.
+ */
+static int kpss_div2_get_div(struct div_clk *div)
+{
+	unsigned long flags;
+	u32 regval;
+	int val;
+
+	spin_lock_irqsave(&kpss_clock_reg_lock, flags);
+	regval = get_l2_indirect_reg(div->offset);
+	val = (regval >> div->shift) && div->mask;
+	regval &= ~(div->mask << div->shift);
+	set_l2_indirect_reg(div->offset, regval);
+	spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);
+
+	val = (val + 1) * 2;
+	WARN(val != 2, "Divider %s was configured to div-%d instead of 2!\n",
+		div->c.dbg_name, val);
+
+	return 2;
+}
+
+struct clk_div_ops clk_div_ops_kpss_div2 = {
+	.get_div = kpss_div2_get_div,
+};
+
+#define LOCK_BIT	BIT(16)
+
+/* Initialize a HFPLL at a given rate and enable it. */
+static void __hfpll_clk_init_once(struct clk *c)
+{
+	struct hfpll_clk *h = to_hfpll_clk(c);
+	struct hfpll_data const *hd = h->d;
+
+	if (likely(h->init_done))
+		return;
+
+	/* Configure PLL parameters for integer mode. */
+	writel_relaxed(hd->config_val, h->base + hd->config_offset);
+	writel_relaxed(0, h->base + hd->m_offset);
+	writel_relaxed(1, h->base + hd->n_offset);
+
+	if (hd->user_offset) {
+		u32 regval = hd->user_val;
+		unsigned long rate;
+
+		rate = readl_relaxed(h->base + hd->l_offset) * h->src_rate;
+
+		/* Pick the right VCO. */
+		if (rate > hd->low_vco_max_rate)
+			regval |= hd->user_vco_mask;
+		writel_relaxed(regval, h->base + hd->user_offset);
+	}
+
+	if (hd->droop_offset)
+		writel_relaxed(hd->droop_val, h->base + hd->droop_offset);
+
+	h->init_done = true;
+}
+
+/* Enable an already-configured HFPLL. */
+static int hfpll_clk_enable(struct clk *c)
+{
+	struct hfpll_clk *h = to_hfpll_clk(c);
+	struct hfpll_data const *hd = h->d;
+
+	if (!h->base)
+		return -ENODEV;
+
+	__hfpll_clk_init_once(c);
+
+	/* Disable PLL bypass mode. */
+	writel_relaxed(0x2, h->base + hd->mode_offset);
+
+	/*
+	 * H/W requires a 5us delay between disabling the bypass and
+	 * de-asserting the reset. Delay 10us just to be safe.
+	 */
+	mb();
+	udelay(10);
+
+	/* De-assert active-low PLL reset. */
+	writel_relaxed(0x6, h->base + hd->mode_offset);
+
+	/* Wait for PLL to lock. */
+	if (hd->status_offset) {
+		while (!(readl_relaxed(h->base + hd->status_offset) & LOCK_BIT))
+			;
+	} else {
+		mb();
+		udelay(60);
+	}
+
+	/* Enable PLL output. */
+	writel_relaxed(0x7, h->base + hd->mode_offset);
+
+	/* Make sure the enable is done before returning. */
+	mb();
+
+	return 0;
+}
+
+static void hfpll_clk_disable(struct clk *c)
+{
+	struct hfpll_clk *h = to_hfpll_clk(c);
+	struct hfpll_data const *hd = h->d;
+
+	/*
+	 * Disable the PLL output, disable test mode, enable the bypass mode,
+	 * and assert the reset.
+	 */
+	writel_relaxed(0, h->base + hd->mode_offset);
+}
+
+static long hfpll_clk_round_rate(struct clk *c, unsigned long rate)
+{
+	struct hfpll_clk *h = to_hfpll_clk(c);
+	struct hfpll_data const *hd = h->d;
+	unsigned long rrate;
+
+	if (!h->src_rate)
+		return 0;
+
+	rate = max(rate, hd->min_rate);
+	rate = min(rate, hd->max_rate);
+
+	rrate = DIV_ROUND_UP(rate, h->src_rate) * h->src_rate;
+	if (rrate > hd->max_rate)
+		rrate -= h->src_rate;
+
+	return rrate;
+}
+
+/*
+ * For optimization reasons, assumes no downstream clocks are actively using
+ * it.
+ */
+static int hfpll_clk_set_rate(struct clk *c, unsigned long rate)
+{
+	struct hfpll_clk *h = to_hfpll_clk(c);
+	struct hfpll_data const *hd = h->d;
+	unsigned long flags;
+	u32 l_val;
+
+	if (!h->base)
+		return -ENODEV;
+
+	if (rate != hfpll_clk_round_rate(c, rate))
+		return -EINVAL;
+
+	l_val = rate / h->src_rate;
+
+	spin_lock_irqsave(&c->lock, flags);
+
+	if (c->count)
+		hfpll_clk_disable(c);
+
+	/* Pick the right VCO. */
+	if (hd->user_offset) {
+		u32 regval;
+		regval = readl_relaxed(h->base + hd->user_offset);
+		if (rate <= hd->low_vco_max_rate)
+			regval &= ~hd->user_vco_mask;
+		else
+			regval |= hd->user_vco_mask;
+		writel_relaxed(regval, h->base  + hd->user_offset);
+	}
+
+	writel_relaxed(l_val, h->base + hd->l_offset);
+
+	if (c->count)
+		hfpll_clk_enable(c);
+
+	spin_unlock_irqrestore(&c->lock, flags);
+
+	return 0;
+}
+
+static enum handoff hfpll_clk_handoff(struct clk *c)
+{
+	struct hfpll_clk *h = to_hfpll_clk(c);
+	struct hfpll_data const *hd = h->d;
+	u32 l_val, mode;
+
+	if (!hd)
+		return HANDOFF_DISABLED_CLK;
+
+	if (!h->base)
+		return HANDOFF_DISABLED_CLK;
+
+	/* Assume parent rate doesn't change and cache it. */
+	h->src_rate = clk_get_rate(c->parent);
+	l_val = readl_relaxed(h->base + hd->l_offset);
+	c->rate = l_val * h->src_rate;
+
+	mode = readl_relaxed(h->base + hd->mode_offset) & 0x7;
+	if (mode != 0x7) {
+		__hfpll_clk_init_once(c);
+		return HANDOFF_DISABLED_CLK;
+	}
+
+	if (hd->status_offset &&
+		!(readl_relaxed(h->base + hd->status_offset) & LOCK_BIT)) {
+		WARN(1, "HFPLL %s is ON, but not locked!\n", c->dbg_name);
+		hfpll_clk_disable(c);
+		__hfpll_clk_init_once(c);
+		return HANDOFF_DISABLED_CLK;
+	}
+
+	WARN(c->rate < hd->min_rate || c->rate > hd->max_rate,
+		"HFPLL %s rate %lu outside spec!\n", c->dbg_name, c->rate);
+
+	return HANDOFF_ENABLED_CLK;
+}
+
+struct clk_ops clk_ops_hfpll = {
+	.enable = hfpll_clk_enable,
+	.disable = hfpll_clk_disable,
+	.round_rate = hfpll_clk_round_rate,
+	.set_rate = hfpll_clk_set_rate,
+	.handoff = hfpll_clk_handoff,
+};
+
+struct cpu_hwcg_action {
+	bool read;
+	bool enable;
+};
+
+static void cpu_hwcg_rw(void *info)
+{
+	struct cpu_hwcg_action *action = info;
+
+	u32 val;
+	asm volatile ("mrc p15, 7, %[cpmr0], c15, c0, 5\n\t"
+			: [cpmr0]"=r" (val));
+
+	if (action->read) {
+		action->enable = !(val & BIT(0));
+		return;
+	}
+
+	if (action->enable)
+		val &= ~BIT(0);
+	else
+		val |= BIT(0);
+
+	asm volatile ("mcr p15, 7, %[cpmr0], c15, c0, 5\n\t"
+			: : [cpmr0]"r" (val));
+}
+
+static void kpss_cpu_enable_hwcg(struct clk *c)
+{
+	struct kpss_core_clk *cpu = to_kpss_core_clk(c);
+	struct cpu_hwcg_action action = { .enable = true };
+
+	smp_call_function_single(cpu->id, cpu_hwcg_rw, &action, 1);
+}
+
+static void kpss_cpu_disable_hwcg(struct clk *c)
+{
+	struct kpss_core_clk *cpu = to_kpss_core_clk(c);
+	struct cpu_hwcg_action action = { .enable = false };
+
+	smp_call_function_single(cpu->id, cpu_hwcg_rw, &action, 1);
+}
+
+static int kpss_cpu_in_hwcg_mode(struct clk *c)
+{
+	struct kpss_core_clk *cpu = to_kpss_core_clk(c);
+	struct cpu_hwcg_action action = { .read = true };
+
+	smp_call_function_single(cpu->id, cpu_hwcg_rw, &action, 1);
+	return action.enable;
+}
+
+static enum handoff kpss_cpu_handoff(struct clk *c)
+{
+	struct kpss_core_clk *cpu = to_kpss_core_clk(c);
+
+	c->rate = clk_get_rate(c->parent);
+
+	/*
+	 * Don't unnecessarily turn on the parents for an offline CPU and
+	 * then have them turned off at late init.
+	 */
+	return (cpu_online(cpu->id) ?
+		HANDOFF_ENABLED_CLK : HANDOFF_DISABLED_CLK);
+}
+
+u32 find_dscr(struct avs_data *t, unsigned long rate)
+{
+	int i;
+
+	if (!t)
+		return 0;
+
+	for (i = 0; i < t->num; i++) {
+		if (t->rate[i] == rate)
+			return t->dscr[i];
+	}
+
+	return 0;
+}
+
+static int kpss_cpu_pre_set_rate(struct clk *c, unsigned long new_rate)
+{
+	struct kpss_core_clk *cpu = to_kpss_core_clk(c);
+	u32 dscr = find_dscr(cpu->avs_tbl, c->rate);
+
+	if (!c->prepare_count)
+		return -ENODEV;
+
+	if (dscr)
+		AVS_DISABLE(cpu->id);
+	return 0;
+}
+
+static long kpss_core_round_rate(struct clk *c, unsigned long rate)
+{
+	if (c->fmax && c->num_fmax)
+		rate = min(rate, c->fmax[c->num_fmax-1]);
+
+	return clk_round_rate(c->parent, rate);
+}
+
+static int kpss_core_set_rate(struct clk *c, unsigned long rate)
+{
+	if (!c->prepare_count)
+		return -ENODEV;
+
+	return clk_set_rate(c->parent, rate);
+}
+
+static void kpss_cpu_post_set_rate(struct clk *c, unsigned long old_rate)
+{
+	struct kpss_core_clk *cpu = to_kpss_core_clk(c);
+	u32 dscr = find_dscr(cpu->avs_tbl, c->rate);
+
+	/*
+	 * FIXME: If AVS enable/disable needs to be done in the
+	 * enable/disable op to correctly handle power collapse, then might
+	 * need to grab the spinlock here.
+	 */
+	if (dscr)
+		AVS_ENABLE(cpu->id, dscr);
+}
+
+static unsigned long kpss_core_get_rate(struct clk *c)
+{
+	return clk_get_rate(c->parent);
+}
+
+static long kpss_core_list_rate(struct clk *c, unsigned n)
+{
+	if (!c->fmax || c->num_fmax <= n)
+		return -ENXIO;
+
+	return c->fmax[n];
+}
+
+struct clk_ops clk_ops_kpss_cpu = {
+	.enable_hwcg = kpss_cpu_enable_hwcg,
+	.disable_hwcg = kpss_cpu_disable_hwcg,
+	.in_hwcg_mode = kpss_cpu_in_hwcg_mode,
+	.pre_set_rate = kpss_cpu_pre_set_rate,
+	.round_rate = kpss_core_round_rate,
+	.set_rate = kpss_core_set_rate,
+	.post_set_rate = kpss_cpu_post_set_rate,
+	.get_rate = kpss_core_get_rate,
+	.list_rate = kpss_core_list_rate,
+	.handoff = kpss_cpu_handoff,
+};
+
+#define SLPDLY_SHIFT		10
+#define SLPDLY_MASK		0x3
+static void kpss_l2_enable_hwcg(struct clk *c)
+{
+	struct kpss_core_clk *l2 = to_kpss_core_clk(c);
+	u32 regval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&kpss_clock_reg_lock, flags);
+	regval = get_l2_indirect_reg(l2->cp15_iaddr);
+	regval &= ~(SLPDLY_MASK << SLPDLY_SHIFT);
+	regval |= l2->l2_slp_delay;
+	set_l2_indirect_reg(l2->cp15_iaddr, regval);
+	spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);
+}
+
+static void kpss_l2_disable_hwcg(struct clk *c)
+{
+	struct kpss_core_clk *l2 = to_kpss_core_clk(c);
+	u32 regval;
+	unsigned long flags;
+
+	/*
+	 * NOTE: Should not be called when HW clock gating is already
+	 * disabled.
+	 */
+	spin_lock_irqsave(&kpss_clock_reg_lock, flags);
+	regval = get_l2_indirect_reg(l2->cp15_iaddr);
+	l2->l2_slp_delay = regval & (SLPDLY_MASK << SLPDLY_SHIFT);
+	regval |= (SLPDLY_MASK << SLPDLY_SHIFT);
+	set_l2_indirect_reg(l2->cp15_iaddr, regval);
+	spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);
+}
+
+static int kpss_l2_in_hwcg_mode(struct clk *c)
+{
+	struct kpss_core_clk *l2 = to_kpss_core_clk(c);
+	u32 regval;
+
+	regval = get_l2_indirect_reg(l2->cp15_iaddr);
+	regval >>= SLPDLY_SHIFT;
+	regval &= SLPDLY_MASK;
+	return (regval != SLPDLY_MASK);
+}
+
+static enum handoff kpss_l2_handoff(struct clk *c)
+{
+	c->rate = clk_get_rate(c->parent);
+	return HANDOFF_ENABLED_CLK;
+}
+
+struct clk_ops clk_ops_kpss_l2 = {
+	.enable_hwcg = kpss_l2_enable_hwcg,
+	.disable_hwcg = kpss_l2_disable_hwcg,
+	.in_hwcg_mode = kpss_l2_in_hwcg_mode,
+	.round_rate = kpss_core_round_rate,
+	.set_rate = kpss_core_set_rate,
+	.get_rate = kpss_core_get_rate,
+	.list_rate = kpss_core_list_rate,
+	.handoff = kpss_l2_handoff,
+};
diff --git a/arch/arm/mach-msm/clock-krait.h b/arch/arm/mach-msm/clock-krait.h
new file mode 100644
index 0000000..2691a8c
--- /dev/null
+++ b/arch/arm/mach-msm/clock-krait.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_CLOCK_KRAIT_H
+#define __ARCH_ARM_MACH_MSM_CLOCK_KRAIT_H
+
+#include <mach/clk-provider.h>
+#include <mach/clock-generic.h>
+
+extern struct clk_mux_ops clk_mux_ops_kpss;
+extern struct clk_div_ops clk_div_ops_kpss_div2;
+
+#define DEFINE_KPSS_DIV2_CLK(clk_name, _parent, _offset) \
+static struct div_clk clk_name = {		\
+	.div = 2,				\
+	.min_div = 2,				\
+	.max_div = 2,				\
+	.ops = &clk_div_ops_kpss_div2,		\
+	.offset = _offset,			\
+	.mask = 0x3,				\
+	.shift = 6,				\
+	.c = {					\
+		.parent = _parent,		\
+		.dbg_name = #clk_name,		\
+		.ops = &clk_ops_div,		\
+		.flags = CLKFLAG_NO_RATE_CACHE,	\
+		CLK_INIT(clk_name.c),		\
+	}					\
+}
+
+struct hfpll_data {
+	const u32 mode_offset;
+	const u32 l_offset;
+	const u32 m_offset;
+	const u32 n_offset;
+	const u32 user_offset;
+	const u32 droop_offset;
+	const u32 config_offset;
+	const u32 status_offset;
+
+	const u32 droop_val;
+	const u32 config_val;
+	const u32 user_val;
+	const u32 user_vco_mask;
+	unsigned long low_vco_max_rate;
+
+	unsigned long min_rate;
+	unsigned long max_rate;
+};
+
+struct hfpll_clk {
+	void  * __iomem base;
+	struct hfpll_data const *d;
+	unsigned long	src_rate;
+	int		init_done;
+
+	struct clk	c;
+};
+
+static inline struct hfpll_clk *to_hfpll_clk(struct clk *c)
+{
+	return container_of(c, struct hfpll_clk, c);
+}
+
+extern struct clk_ops clk_ops_hfpll;
+
+struct avs_data {
+	unsigned long	*rate;
+	u32		*dscr;
+	int		num;
+};
+
+struct kpss_core_clk {
+	int		id;
+	u32		cp15_iaddr;
+	u32		l2_slp_delay;
+	struct avs_data	*avs_tbl;
+	struct clk	c;
+};
+
+static inline struct kpss_core_clk *to_kpss_core_clk(struct clk *c)
+{
+	return container_of(c, struct kpss_core_clk, c);
+}
+
+extern struct clk_ops clk_ops_kpss_cpu;
+extern struct clk_ops clk_ops_kpss_l2;
+
+#endif
diff --git a/arch/arm/mach-msm/clock-krypton.c b/arch/arm/mach-msm/clock-krypton.c
index 0b615cc..176dc32 100644
--- a/arch/arm/mach-msm/clock-krypton.c
+++ b/arch/arm/mach-msm/clock-krypton.c
@@ -18,12 +18,12 @@
 #include <linux/spinlock.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
-#include <linux/iopoll.h>
 #include <linux/regulator/consumer.h>
+#include <linux/iopoll.h>
 
+#include <mach/clk.h>
 #include <mach/rpm-regulator-smd.h>
 #include <mach/socinfo.h>
-#include <mach/rpm-smd.h>
 
 #include "clock-local2.h"
 #include "clock-pll.h"
@@ -31,97 +31,2051 @@
 #include "clock-voter.h"
 #include "clock.h"
 
-static struct clk_lookup msm_clocks_dummy[] = {
-	CLK_DUMMY("core_clk",   BLSP1_UART_CLK, "f991f000.serial", OFF),
-	CLK_DUMMY("iface_clk",  BLSP1_UART_CLK, "f991f000.serial", OFF),
-	CLK_DUMMY("core_clk",	SPI_CLK,	"f9928000.spi",  OFF),
-	CLK_DUMMY("iface_clk",	SPI_P_CLK,	"f9928000.spi",  OFF),
-
-	CLK_DUMMY("bus_clk", cnoc_msmbus_clk.c, "msm_config_noc", OFF),
-	CLK_DUMMY("bus_a_clk", cnoc_msmbus_a_clk.c, "msm_config_noc", OFF),
-	CLK_DUMMY("bus_clk", snoc_msmbus_clk.c, "msm_sys_noc", OFF),
-	CLK_DUMMY("bus_a_clk", snoc_msmbus_a_clk.c, "msm_sys_noc", OFF),
-	CLK_DUMMY("bus_clk", pnoc_msmbus_clk.c, "msm_periph_noc", OFF),
-	CLK_DUMMY("bus_a_clk", pnoc_msmbus_a_clk.c, "msm_periph_noc", OFF),
-	CLK_DUMMY("mem_clk", bimc_msmbus_clk.c, "msm_bimc", OFF),
-	CLK_DUMMY("mem_a_clk", bimc_msmbus_a_clk.c, "msm_bimc", OFF),
-	CLK_DUMMY("mem_clk", bimc_acpu_a_clk.c, "", OFF),
-	CLK_DUMMY("dfab_clk",	DFAB_CLK,	"msm_sps", OFF),
-	CLK_DUMMY("dma_bam_pclk",	DMA_BAM_P_CLK,	"msm_sps", OFF),
-
-	CLK_DUMMY("clktype", gcc_imem_axi_clk         , "drivername", OFF),
-	CLK_DUMMY("clktype", gcc_imem_cfg_ahb_clk     , "drivername", OFF),
-	CLK_DUMMY("clktype", gcc_mss_cfg_ahb_clk      , "drivername", OFF),
-	CLK_DUMMY("clktype", gcc_mss_q6_bimc_axi_clk  , "drivername", OFF),
-	CLK_DUMMY("mem_clk", gcc_usb30_master_clk     , "drivername", OFF),
-	CLK_DUMMY("sleep_clk", gcc_usb30_sleep_clk    , "drivername", OFF),
-	CLK_DUMMY("utmi_clk", gcc_usb30_mock_utmi_clk , "drivername", OFF),
-	CLK_DUMMY("iface_clk", gcc_usb_hsic_ahb_clk   , "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_usb_hsic_system_clk , "drivername", OFF),
-	CLK_DUMMY("phyclk", gcc_usb_hsic_clk         , "drivername", OFF),
-	CLK_DUMMY("cal_clk", gcc_usb_hsic_io_cal_clk  , "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_usb_hs_system_clk   , "drivername", OFF),
-	CLK_DUMMY("iface_clk", gcc_usb_hs_ahb_clk     , "drivername", OFF),
-	CLK_DUMMY("sleep_a_clk", gcc_usb2a_phy_sleep_clk  , "drivername", OFF),
-	CLK_DUMMY("sleep_b_clk", gcc_usb2b_phy_sleep_clk  , "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_sdcc2_apps_clk      , "drivername", OFF),
-	CLK_DUMMY("iface_clk", gcc_sdcc2_ahb_clk      , "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_sdcc3_apps_clk      , "drivername", OFF),
-	CLK_DUMMY("iface_clk", gcc_sdcc3_ahb_clk      , "drivername", OFF),
-	CLK_DUMMY("core_clk", sdcc3_apps_clk_src      , "drivername", OFF),
-	CLK_DUMMY("iface_clk", gcc_blsp1_ahb_clk      , "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_blsp1_qup1_spi_apps_clk, "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_blsp1_qup1_i2c_apps_clk, "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_blsp1_uart1_apps_clk , "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_blsp1_qup2_spi_apps_clk, "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_blsp1_qup2_i2c_apps_clk, "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_blsp1_uart2_apps_clk , "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_blsp1_qup3_spi_apps_clk, "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_blsp1_qup3_i2c_apps_clk, "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_blsp1_uart3_apps_clk , "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_blsp1_qup4_spi_apps_clk, "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_blsp1_qup4_i2c_apps_clk, "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_blsp1_uart4_apps_clk , "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_blsp1_qup5_spi_apps_clk, "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_blsp1_qup5_i2c_apps_clk, "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_blsp1_uart5_apps_clk , "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_blsp1_qup6_spi_apps_clk, "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_blsp1_qup6_i2c_apps_clk, "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_blsp1_uart6_apps_clk , "drivername", OFF),
-	CLK_DUMMY("core_clk", blsp1_uart6_apps_clk_src , "drivername", OFF),
-	CLK_DUMMY("iface_clk", gcc_pdm_ahb_clk        , "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_pdm2_clk            , "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_prng_ahb_clk        , "drivername", OFF),
-	CLK_DUMMY("dma_bam_pclk", gcc_bam_dma_ahb_clk , "drivername", OFF),
-	CLK_DUMMY("mem_clk", gcc_boot_rom_ahb_clk     , "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_ce1_clk             , "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_ce1_axi_clk         , "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_ce1_ahb_clk         , "drivername", OFF),
-	CLK_DUMMY("core_clk_src", ce1_clk_src         , "drivername", OFF),
-	CLK_DUMMY("bus_clk", gcc_lpass_q6_axi_clk     , "drivername", OFF),
-	CLK_DUMMY("clktype", pcie_pipe_clk            , "drivername", OFF),
-	CLK_DUMMY("clktype", gcc_gp1_clk              , "drivername", OFF),
-	CLK_DUMMY("clktype", gp1_clk_src              , "drivername", OFF),
-	CLK_DUMMY("clktype", gcc_gp2_clk              , "drivername", OFF),
-	CLK_DUMMY("clktype", gp2_clk_src              , "drivername", OFF),
-	CLK_DUMMY("clktype", gcc_gp3_clk              , "drivername", OFF),
-	CLK_DUMMY("clktype", gp3_clk_src              , "drivername", OFF),
-	CLK_DUMMY("core_clk", gcc_ipa_clk             , "drivername", OFF),
-	CLK_DUMMY("iface_clk", gcc_ipa_cnoc_clk       , "drivername", OFF),
-	CLK_DUMMY("inactivity_clk", gcc_ipa_sleep_clk , "drivername", OFF),
-	CLK_DUMMY("core_clk_src", ipa_clk_src         , "drivername", OFF),
-	CLK_DUMMY("clktype", gcc_dcs_clk              , "drivername", OFF),
-	CLK_DUMMY("clktype", dcs_clk_src              , "drivername", OFF),
-	CLK_DUMMY("clktype", gcc_pcie_cfg_ahb_clk     , "drivername", OFF),
-	CLK_DUMMY("clktype", gcc_pcie_pipe_clk        , "drivername", OFF),
-	CLK_DUMMY("clktype", gcc_pcie_axi_clk         , "drivername", OFF),
-	CLK_DUMMY("clktype", gcc_pcie_sleep_clk       , "drivername", OFF),
-	CLK_DUMMY("clktype", gcc_pcie_axi_mstr_clk    , "drivername", OFF),
-	CLK_DUMMY("clktype", pcie_pipe_clk_src        , "drivername", OFF),
-	CLK_DUMMY("clktype", pcie_aux_clk_src         , "drivername", OFF),
+enum {
+	GCC_BASE,
+	LPASS_BASE,
+	APCS_GLB_BASE,
+	APCS_GCC_BASE,
+	APCS_ACC_BASE,
+	N_BASES,
 };
 
+static void __iomem *virt_bases[N_BASES];
+
+#define GCC_REG_BASE(x) (void __iomem *)(virt_bases[GCC_BASE] + (x))
+#define APCS_GCC_BASE(x) (void __iomem *)(virt_bases[APCS_GCC_BASE] + (x))
+
+/* Mux source select values */
+#define xo_source_val	0
+#define gpll0_source_val 1
+#define gpll1_source_val 4
+#define gnd_source_val	5
+
+#define usb3_pipe_clk_source_val	2
+#define pcie_pipe_clk_source_val	2
+
+/* Prevent a divider of -1 */
+#define FIXDIV(div) (div ? (2 * (div) - 1) : (0))
+
+#define F(f, s, div, m, n) \
+	{ \
+		.freq_hz = (f), \
+		.src_clk = &s.c, \
+		.m_val = (m), \
+		.n_val = ~((n)-(m)) * !!(n), \
+		.d_val = ~(n),\
+		.div_src_val = BVAL(4, 0, (int)(FIXDIV(div))) \
+			| BVAL(10, 8, s##_source_val), \
+	}
+
+#define F_EXT_SRC(f, s, div, m, n) \
+	{ \
+		.freq_hz = (f), \
+		.m_val = (m), \
+		.n_val = ~((n)-(m)) * !!(n), \
+		.d_val = ~(n),\
+		.div_src_val = BVAL(4, 0, (int)(FIXDIV(div))) \
+			| BVAL(10, 8, s##_source_val), \
+	}
+
+#define VDD_DIG_FMAX_MAP1(l1, f1) \
+	.vdd_class = &vdd_dig,			\
+	.fmax = (unsigned long[VDD_DIG_NUM]) {	\
+		[VDD_DIG_##l1] = (f1),		\
+	},					\
+	.num_fmax = VDD_DIG_NUM
+#define VDD_DIG_FMAX_MAP2(l1, f1, l2, f2) \
+	.vdd_class = &vdd_dig,			\
+	.fmax = (unsigned long[VDD_DIG_NUM]) {	\
+		[VDD_DIG_##l1] = (f1),		\
+		[VDD_DIG_##l2] = (f2),		\
+	},					\
+	.num_fmax = VDD_DIG_NUM
+#define VDD_DIG_FMAX_MAP3(l1, f1, l2, f2, l3, f3) \
+	.vdd_class = &vdd_dig,			\
+	.fmax = (unsigned long[VDD_DIG_NUM]) {	\
+		[VDD_DIG_##l1] = (f1),		\
+		[VDD_DIG_##l2] = (f2),		\
+		[VDD_DIG_##l3] = (f3),		\
+	},					\
+	.num_fmax = VDD_DIG_NUM
+
+enum vdd_dig_levels {
+	VDD_DIG_NONE,
+	VDD_DIG_LOW,
+	VDD_DIG_NOMINAL,
+	VDD_DIG_HIGH,
+	VDD_DIG_NUM
+};
+
+static int vdd_corner[] = {
+	RPM_REGULATOR_CORNER_NONE,		/* VDD_DIG_NONE */
+	RPM_REGULATOR_CORNER_SVS_SOC,		/* VDD_DIG_LOW */
+	RPM_REGULATOR_CORNER_NORMAL,		/* VDD_DIG_NOMINAL */
+	RPM_REGULATOR_CORNER_SUPER_TURBO,	/* VDD_DIG_HIGH */
+};
+
+static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner, NULL);
+
+#define RPM_MISC_CLK_TYPE	0x306b6c63
+#define RPM_BUS_CLK_TYPE	0x316b6c63
+#define RPM_MEM_CLK_TYPE	0x326b6c63
+#define RPM_QPIC_CLK_TYPE	0x63697071
+
+#define RPM_SMD_KEY_ENABLE	0x62616E45
+
+#define CXO_ID			0x0
+#define QDSS_ID			0x1
+
+#define PNOC_ID		0x0
+#define SNOC_ID		0x1
+#define CNOC_ID		0x2
+
+#define BIMC_ID		0x0
+#define QPIC_ID		0x0
+
+#define D0_ID		 1
+#define D1_ID		 2
+#define A0_ID		 3
+#define A1_ID		 4
+#define A2_ID		 5
+
+#define APCS_CLK_DIAG                                      (0x001C)
+#define GPLL0_MODE                                         (0x0000)
+#define GPLL1_MODE                                         (0x0040)
+#define SYS_NOC_USB3_AXI_CBCR                              (0x0108)
+#define MSS_CFG_AHB_CBCR                                   (0x0280)
+#define MSS_Q6_BIMC_AXI_CBCR                               (0x0284)
+#define USB_30_BCR                                         (0x03C0)
+#define USB30_MASTER_CBCR                                  (0x03C8)
+#define USB30_SLEEP_CBCR                                   (0x03CC)
+#define USB30_MOCK_UTMI_CBCR                               (0x03D0)
+#define USB30_MASTER_CMD_RCGR                              (0x03D4)
+#define USB30_MOCK_UTMI_CMD_RCGR                           (0x03E8)
+#define USB3_PIPE_CBCR                                     (0x1B90)
+#define USB3_AUX_CBCR                                      (0x1B94)
+#define USB3_PIPE_CMD_RCGR                                 (0x1B98)
+#define USB3_AUX_CMD_RCGR                                  (0x1BC0)
+#define USB_HS_HSIC_BCR                                    (0x0400)
+#define USB_HSIC_AHB_CBCR                                  (0x0408)
+#define USB_HSIC_SYSTEM_CMD_RCGR                           (0x041C)
+#define USB_HSIC_SYSTEM_CBCR                               (0x040C)
+#define USB_HSIC_CMD_RCGR                                  (0x0440)
+#define USB_HSIC_CBCR                                      (0x0410)
+#define USB_HSIC_IO_CAL_CMD_RCGR                           (0x0458)
+#define USB_HSIC_IO_CAL_CBCR                               (0x0414)
+#define USB_HSIC_IO_CAL_SLEEP_CBCR                         (0x0418)
+#define USB_HSIC_XCVR_FS_CMD_RCGR                          (0x0424)
+#define USB_HSIC_XCVR_FS_CBCR                              (0x042C)
+#define USB_HS_BCR                                         (0x0480)
+#define USB_HS_SYSTEM_CBCR                                 (0x0484)
+#define USB_HS_AHB_CBCR                                    (0x0488)
+#define USB_HS_SYSTEM_CMD_RCGR                             (0x0490)
+#define SDCC2_APPS_CMD_RCGR                                (0x0510)
+#define SDCC2_APPS_CBCR                                    (0x0504)
+#define SDCC2_AHB_CBCR                                     (0x0508)
+#define SDCC3_APPS_CMD_RCGR                                (0x0550)
+#define SDCC3_APPS_CBCR                                    (0x0544)
+#define SDCC3_AHB_CBCR                                     (0x0548)
+#define BLSP1_AHB_CBCR                                     (0x05C4)
+#define BLSP1_QUP1_SPI_APPS_CBCR                           (0x0644)
+#define BLSP1_QUP1_I2C_APPS_CBCR                           (0x0648)
+#define BLSP1_QUP1_I2C_APPS_CMD_RCGR                       (0x0660)
+#define BLSP1_QUP2_I2C_APPS_CMD_RCGR                       (0x06E0)
+#define BLSP1_QUP3_I2C_APPS_CMD_RCGR                       (0x0760)
+#define BLSP1_QUP4_I2C_APPS_CMD_RCGR                       (0x07E0)
+#define BLSP1_QUP5_I2C_APPS_CMD_RCGR                       (0x0860)
+#define BLSP1_QUP6_I2C_APPS_CMD_RCGR                       (0x08E0)
+#define BLSP1_QUP1_SPI_APPS_CMD_RCGR                       (0x064C)
+#define BLSP1_UART1_APPS_CBCR                              (0x0684)
+#define BLSP1_UART1_APPS_CMD_RCGR                          (0x068C)
+#define BLSP1_QUP2_SPI_APPS_CBCR                           (0x06C4)
+#define BLSP1_QUP2_I2C_APPS_CBCR                           (0x06C8)
+#define BLSP1_QUP2_SPI_APPS_CMD_RCGR                       (0x06CC)
+#define BLSP1_UART2_APPS_CBCR                              (0x0704)
+#define BLSP1_UART2_APPS_CMD_RCGR                          (0x070C)
+#define BLSP1_QUP3_SPI_APPS_CBCR                           (0x0744)
+#define BLSP1_QUP3_I2C_APPS_CBCR                           (0x0748)
+#define BLSP1_QUP3_SPI_APPS_CMD_RCGR                       (0x074C)
+#define BLSP1_UART3_APPS_CBCR                              (0x0784)
+#define BLSP1_UART3_APPS_CMD_RCGR                          (0x078C)
+#define BLSP1_QUP4_SPI_APPS_CBCR                           (0x07C4)
+#define BLSP1_QUP4_I2C_APPS_CBCR                           (0x07C8)
+#define BLSP1_QUP4_SPI_APPS_CMD_RCGR                       (0x07CC)
+#define BLSP1_UART4_APPS_CBCR                              (0x0804)
+#define BLSP1_UART4_APPS_CMD_RCGR                          (0x080C)
+#define BLSP1_QUP5_SPI_APPS_CBCR                           (0x0844)
+#define BLSP1_QUP5_I2C_APPS_CBCR                           (0x0848)
+#define BLSP1_QUP5_SPI_APPS_CMD_RCGR                       (0x084C)
+#define BLSP1_UART5_APPS_CBCR                              (0x0884)
+#define BLSP1_UART5_APPS_CMD_RCGR                          (0x088C)
+#define BLSP1_QUP6_SPI_APPS_CBCR                           (0x08C4)
+#define BLSP1_QUP6_I2C_APPS_CBCR                           (0x08C8)
+#define BLSP1_QUP6_SPI_APPS_CMD_RCGR                       (0x08CC)
+#define BLSP1_UART6_APPS_CBCR                              (0x0904)
+#define BLSP1_UART6_APPS_CMD_RCGR                          (0x090C)
+#define PDM_AHB_CBCR                                       (0x0CC4)
+#define PDM2_CBCR                                          (0x0CCC)
+#define PDM2_CMD_RCGR                                      (0x0CD0)
+#define PRNG_AHB_CBCR                                      (0x0D04)
+#define BAM_DMA_AHB_CBCR                                   (0x0D44)
+#define BAM_DMA_INACTIVITY_TIMERS_CBCR                     (0x0D48)
+#define BOOT_ROM_AHB_CBCR                                  (0x0E04)
+#define RPM_MISC                                           (0x0F24)
+#define CE1_CMD_RCGR                                       (0x1050)
+#define CE1_CBCR                                           (0x1044)
+#define CE1_AXI_CBCR                                       (0x1048)
+#define CE1_AHB_CBCR                                       (0x104C)
+#define GCC_XO_DIV4_CBCR                                   (0x10C8)
+#define LPASS_Q6_AXI_CBCR                                  (0x11C0)
+#define APCS_GPLL_ENA_VOTE                                 (0x1480)
+#define APCS_CLOCK_BRANCH_ENA_VOTE                         (0x1484)
+#define GCC_DEBUG_CLK_CTL                                  (0x1880)
+#define CLOCK_FRQ_MEASURE_CTL                              (0x1884)
+#define CLOCK_FRQ_MEASURE_STATUS                           (0x1888)
+#define PLLTEST_PAD_CFG                                    (0x188C)
+#define PCIE_CFG_AHB_CBCR                                  (0x1C04)
+#define PCIE_PIPE_CBCR                                     (0x1C08)
+#define PCIE_AXI_CBCR                                      (0x1C0C)
+#define PCIE_SLEEP_CBCR                                    (0x1C10)
+#define PCIE_AXI_MSTR_CBCR                                 (0x1C2C)
+#define PCIE_PIPE_CMD_RCGR                                 (0x1C14)
+#define PCIE_AUX_CMD_RCGR                                  (0x1E00)
+#define Q6SS_AHB_LFABIF_CBCR                               (0x22000)
+#define Q6SS_AHBM_CBCR                                     (0x22004)
+
+DEFINE_CLK_RPM_SMD_BRANCH(xo, xo_a_clk, RPM_MISC_CLK_TYPE, CXO_ID, 19200000);
+
+static unsigned int soft_vote_gpll0;
+
+static struct pll_vote_clk gpll0 = {
+	.en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE,
+	.en_mask = BIT(0),
+	.status_reg = (void __iomem *)GPLL0_MODE,
+	.status_mask = BIT(31),
+	.soft_vote = &soft_vote_gpll0,
+	.soft_vote_mask = PLL_SOFT_VOTE_PRIMARY,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.rate = 600000000,
+		.parent = &xo.c,
+		.dbg_name = "gpll0",
+		.ops = &clk_ops_pll_acpu_vote,
+		CLK_INIT(gpll0.c),
+	},
+};
+
+/* Don't vote for xo if using this clock to allow xo shutdown */
+static struct pll_vote_clk gpll0_ao = {
+	.en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE,
+	.en_mask = BIT(0),
+	.status_reg = (void __iomem *)GPLL0_MODE,
+	.status_mask = BIT(31),
+	.soft_vote = &soft_vote_gpll0,
+	.soft_vote_mask = PLL_SOFT_VOTE_ACPU,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.rate = 600000000,
+		.dbg_name = "gpll0_ao",
+		.ops = &clk_ops_pll_acpu_vote,
+		CLK_INIT(gpll0_ao.c),
+	},
+};
+
+static struct pll_vote_clk gpll1 = {
+	.en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE,
+	.en_mask = BIT(1),
+	.status_reg = (void __iomem *)GPLL1_MODE,
+	.status_mask = BIT(31),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.rate = 480000000,
+		.parent = &xo.c,
+		.dbg_name = "gpll1",
+		.ops = &clk_ops_pll_vote,
+		CLK_INIT(gpll1.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb30_master_clk[] = {
+	F( 125000000,      gpll0,    1,    5,    24),
+	F_END
+};
+
+static struct rcg_clk usb30_master_clk_src = {
+	.cmd_rcgr_reg = USB30_MASTER_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_usb30_master_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "usb30_master_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP1(LOW, 125000000),
+		CLK_INIT(usb30_master_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_blsp1_qup1_6_i2c_apps_clk[] = {
+	F(  19200000,         xo,    1,    0,     0),
+	F_END
+};
+
+static struct rcg_clk blsp1_qup1_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP1_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup1_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 19200000),
+		CLK_INIT(blsp1_qup1_i2c_apps_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_blsp1_qup1_6_spi_apps_clk[] = {
+	F(    960000,         xo,   10,    1,     2),
+	F(   4800000,         xo,    4,    0,     0),
+	F(   9600000,         xo,    2,    0,     0),
+	F(  15000000,      gpll0,   10,    1,     4),
+	F(  19200000,         xo,    1,    0,     0),
+	F(  25000000,      gpll0,   12,    1,     2),
+	F(  50000000,      gpll0,   12,    0,     0),
+	F_END
+};
+
+static struct rcg_clk blsp1_qup1_spi_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP1_SPI_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup1_spi_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+		CLK_INIT(blsp1_qup1_spi_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup2_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP2_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup2_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 19200000),
+		CLK_INIT(blsp1_qup2_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup2_spi_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP2_SPI_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup2_spi_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+		CLK_INIT(blsp1_qup2_spi_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup3_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP3_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup3_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 19200000),
+		CLK_INIT(blsp1_qup3_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup3_spi_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP3_SPI_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup3_spi_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+		CLK_INIT(blsp1_qup3_spi_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup4_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP4_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup4_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 19200000),
+		CLK_INIT(blsp1_qup4_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup4_spi_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP4_SPI_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup4_spi_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+		CLK_INIT(blsp1_qup4_spi_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup5_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP5_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup5_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 19200000),
+		CLK_INIT(blsp1_qup5_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup5_spi_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP5_SPI_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup5_spi_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+		CLK_INIT(blsp1_qup5_spi_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup6_i2c_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP6_I2C_APPS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup6_i2c_apps_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 19200000),
+		CLK_INIT(blsp1_qup6_i2c_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_qup6_spi_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_QUP6_SPI_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_qup6_spi_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+		CLK_INIT(blsp1_qup6_spi_apps_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_blsp1_uart1_6_apps_clk[] = {
+	F(   3686400,      gpll0,    1,   96, 15625),
+	F(   7372800,      gpll0,    1,  192, 15625),
+	F(  14745600,      gpll0,    1,  384, 15625),
+	F(  16000000,      gpll0,    5,    2,    15),
+	F(  19200000,         xo,    1,    0,     0),
+	F(  24000000,      gpll0,    5,    1,     5),
+	F(  32000000,      gpll0,    1,    4,    75),
+	F(  40000000,      gpll0,   15,    0,     0),
+	F(  46400000,      gpll0,    1,   29,   375),
+	F(  48000000,      gpll0, 12.5,    0,     0),
+	F(  51200000,      gpll0,    1,   32,   375),
+	F(  56000000,      gpll0,    1,    7,    75),
+	F(  58982400,      gpll0,    1, 1536, 15625),
+	F(  60000000,      gpll0,   10,    0,     0),
+	F_END
+};
+
+static struct rcg_clk blsp1_uart1_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_UART1_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_uart1_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+		CLK_INIT(blsp1_uart1_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_uart2_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_UART2_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_uart2_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+		CLK_INIT(blsp1_uart2_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_uart3_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_UART3_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_uart3_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+		CLK_INIT(blsp1_uart3_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_uart4_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_UART4_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_uart4_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+		CLK_INIT(blsp1_uart4_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_uart5_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_UART5_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_uart5_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+		CLK_INIT(blsp1_uart5_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk blsp1_uart6_apps_clk_src = {
+	.cmd_rcgr_reg = BLSP1_UART6_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "blsp1_uart6_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+		CLK_INIT(blsp1_uart6_apps_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_ce1_clk[] = {
+	F(  50000000,      gpll0,   12,    0,     0),
+	F(  85710000,      gpll0,    7,    0,     0),
+	F( 100000000,      gpll0,    6,    0,     0),
+	F( 171430000,      gpll0,  3.5,    0,     0),
+	F( 200000000,      gpll0,    3,    0,     0),
+	F_END
+};
+
+static struct rcg_clk ce1_clk_src = {
+	.cmd_rcgr_reg = CE1_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_ce1_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "ce1_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP3(LOW, 85710000, NOMINAL, 171430000, HIGH,
+			200000000),
+		CLK_INIT(ce1_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_pcie_sleep_clk[] = {
+	F(   1000000,         xo,    1,    5,    96),
+	F_END
+};
+
+static struct rcg_clk pcie_aux_clk_src = {
+	.cmd_rcgr_reg = PCIE_AUX_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_pcie_sleep_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "pcie_aux_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP1(LOW, 1000000),
+		CLK_INIT(pcie_aux_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_pcie_pipe_clk[] = {
+	F_EXT_SRC(  62500000, pcie_pipe_clk,    2,    0,     0),
+	F_EXT_SRC( 125000000, pcie_pipe_clk,    1,    0,     0),
+	F_END
+};
+
+static struct rcg_clk pcie_pipe_clk_src = {
+	.cmd_rcgr_reg = PCIE_PIPE_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_pcie_pipe_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "pcie_pipe_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 62500000, NOMINAL, 125000000),
+		CLK_INIT(pcie_pipe_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_pdm2_clk[] = {
+	F(  60000000,      gpll0,   10,    0,     0),
+	F_END
+};
+
+static struct rcg_clk pdm2_clk_src = {
+	.cmd_rcgr_reg = PDM2_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_pdm2_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "pdm2_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 60000000),
+		CLK_INIT(pdm2_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_sdcc2_3_apps_clk[] = {
+	F(    144000,         xo,   16,    3,    25),
+	F(    400000,         xo,   12,    1,     4),
+	F(  20000000,      gpll0,   15,    1,     2),
+	F(  25000000,      gpll0,   12,    1,     2),
+	F(  50000000,      gpll0,   12,    0,     0),
+	F( 100000000,      gpll0,    6,    0,     0),
+	F( 200000000,      gpll0,    3,    0,     0),
+	F_END
+};
+
+static struct rcg_clk sdcc2_apps_clk_src = {
+	.cmd_rcgr_reg = SDCC2_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_sdcc2_3_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "sdcc2_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+		CLK_INIT(sdcc2_apps_clk_src.c),
+	},
+};
+
+static struct rcg_clk sdcc3_apps_clk_src = {
+	.cmd_rcgr_reg = SDCC3_APPS_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_sdcc2_3_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "sdcc3_apps_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 100000000),
+		CLK_INIT(sdcc3_apps_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb3_aux_clk[] = {
+	F(   1000000,         xo,    1,    5,    96),
+	F_END
+};
+
+static struct rcg_clk usb3_aux_clk_src = {
+	.cmd_rcgr_reg = USB3_AUX_CMD_RCGR,
+	.set_rate = set_rate_mnd,
+	.freq_tbl = ftbl_gcc_usb3_aux_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "usb3_aux_clk_src",
+		.ops = &clk_ops_rcg_mnd,
+		VDD_DIG_FMAX_MAP1(LOW, 1000000),
+		CLK_INIT(usb3_aux_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb3_pipe_clk[] = {
+	F_EXT_SRC( 125000000, usb3_pipe_clk,    1,    0,     0),
+	F_END
+};
+
+static struct rcg_clk usb3_pipe_clk_src = {
+	.cmd_rcgr_reg = USB3_PIPE_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_usb3_pipe_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "usb3_pipe_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 125000000),
+		CLK_INIT(usb3_pipe_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb30_mock_utmi_clk[] = {
+	F(  60000000,      gpll0,   10,    0,     0),
+	F_END
+};
+
+static struct rcg_clk usb30_mock_utmi_clk_src = {
+	.cmd_rcgr_reg = USB30_MOCK_UTMI_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_usb30_mock_utmi_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "usb30_mock_utmi_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 60000000),
+		CLK_INIT(usb30_mock_utmi_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb_hs_system_clk[] = {
+	F(  60000000,      gpll0,   10,    0,     0),
+	F(  75000000,      gpll0,    8,    0,     0),
+	F_END
+};
+
+static struct rcg_clk usb_hs_system_clk_src = {
+	.cmd_rcgr_reg = USB_HS_SYSTEM_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_usb_hs_system_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "usb_hs_system_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 60000000, NOMINAL, 75000000),
+		CLK_INIT(usb_hs_system_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb_hsic_clk[] = {
+	F( 480000000,      gpll1,    1,    0,     0),
+	F_END
+};
+
+static struct rcg_clk usb_hsic_clk_src = {
+	.cmd_rcgr_reg = USB_HSIC_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_usb_hsic_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "usb_hsic_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 480000000),
+		CLK_INIT(usb_hsic_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb_hsic_io_cal_clk[] = {
+	F(   9600000,         xo,    2,    0,     0),
+	F_END
+};
+
+static struct rcg_clk usb_hsic_io_cal_clk_src = {
+	.cmd_rcgr_reg = USB_HSIC_IO_CAL_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_usb_hsic_io_cal_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "usb_hsic_io_cal_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 9600000),
+		CLK_INIT(usb_hsic_io_cal_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb_hsic_system_clk[] = {
+	F(  60000000,      gpll0,   10,    0,     0),
+	F(  75000000,      gpll0,    8,    0,     0),
+	F_END
+};
+
+static struct rcg_clk usb_hsic_system_clk_src = {
+	.cmd_rcgr_reg = USB_HSIC_SYSTEM_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_usb_hsic_system_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "usb_hsic_system_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP2(LOW, 60000000, NOMINAL, 75000000),
+		CLK_INIT(usb_hsic_system_clk_src.c),
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb_hsic_xcvr_fs_clk[] = {
+	F(  60000000,      gpll0,   10,    0,     0),
+	F_END
+};
+
+static struct rcg_clk usb_hsic_xcvr_fs_clk_src = {
+	.cmd_rcgr_reg = USB_HSIC_XCVR_FS_CMD_RCGR,
+	.set_rate = set_rate_hid,
+	.freq_tbl = ftbl_gcc_usb_hsic_xcvr_fs_clk,
+	.current_freq = &rcg_dummy_freq,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "usb_hsic_xcvr_fs_clk_src",
+		.ops = &clk_ops_rcg,
+		VDD_DIG_FMAX_MAP1(LOW, 60000000),
+		CLK_INIT(usb_hsic_xcvr_fs_clk_src.c),
+	},
+};
+
+DEFINE_CLK_RPM_SMD(bimc_clk, bimc_a_clk, RPM_MEM_CLK_TYPE, BIMC_ID, NULL);
+
+DEFINE_CLK_RPM_SMD(cnoc_clk, cnoc_a_clk, RPM_BUS_CLK_TYPE, CNOC_ID, NULL);
+
+DEFINE_CLK_RPM_SMD(pnoc_clk, pnoc_a_clk, RPM_BUS_CLK_TYPE, PNOC_ID, NULL);
+
+DEFINE_CLK_RPM_SMD_QDSS(qdss_clk, qdss_a_clk, RPM_MISC_CLK_TYPE, QDSS_ID);
+
+DEFINE_CLK_RPM_SMD(qpic_clk, qpic_a_clk, RPM_QPIC_CLK_TYPE, QPIC_ID, NULL);
+
+DEFINE_CLK_RPM_SMD(snoc_clk, snoc_a_clk, RPM_BUS_CLK_TYPE, SNOC_ID, NULL);
+
+static struct local_vote_clk gcc_bam_dma_ahb_clk = {
+	.cbcr_reg = BAM_DMA_AHB_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(12),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_bam_dma_ahb_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_bam_dma_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_bam_dma_inactivity_timers_clk = {
+	.cbcr_reg = BAM_DMA_INACTIVITY_TIMERS_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_bam_dma_inactivity_timers_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_bam_dma_inactivity_timers_clk.c),
+	},
+};
+
+static struct local_vote_clk gcc_blsp1_ahb_clk = {
+	.cbcr_reg = BLSP1_AHB_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(17),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_ahb_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_blsp1_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup1_i2c_apps_clk = {
+	.cbcr_reg = BLSP1_QUP1_I2C_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup1_i2c_apps_clk",
+		.parent = &blsp1_qup1_i2c_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup1_i2c_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup1_spi_apps_clk = {
+	.cbcr_reg = BLSP1_QUP1_SPI_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup1_spi_apps_clk",
+		.parent = &blsp1_qup1_spi_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup1_spi_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup2_i2c_apps_clk = {
+	.cbcr_reg = BLSP1_QUP2_I2C_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup2_i2c_apps_clk",
+		.parent = &blsp1_qup2_i2c_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup2_i2c_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup2_spi_apps_clk = {
+	.cbcr_reg = BLSP1_QUP2_SPI_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup2_spi_apps_clk",
+		.parent = &blsp1_qup2_spi_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup2_spi_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup3_i2c_apps_clk = {
+	.cbcr_reg = BLSP1_QUP3_I2C_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup3_i2c_apps_clk",
+		.parent = &blsp1_qup3_i2c_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup3_i2c_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup3_spi_apps_clk = {
+	.cbcr_reg = BLSP1_QUP3_SPI_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup3_spi_apps_clk",
+		.parent = &blsp1_qup3_spi_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup3_spi_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup4_i2c_apps_clk = {
+	.cbcr_reg = BLSP1_QUP4_I2C_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup4_i2c_apps_clk",
+		.parent = &blsp1_qup4_i2c_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup4_i2c_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup4_spi_apps_clk = {
+	.cbcr_reg = BLSP1_QUP4_SPI_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup4_spi_apps_clk",
+		.parent = &blsp1_qup4_spi_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup4_spi_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup5_i2c_apps_clk = {
+	.cbcr_reg = BLSP1_QUP5_I2C_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup5_i2c_apps_clk",
+		.parent = &blsp1_qup5_i2c_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup5_i2c_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup5_spi_apps_clk = {
+	.cbcr_reg = BLSP1_QUP5_SPI_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup5_spi_apps_clk",
+		.parent = &blsp1_qup5_spi_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup5_spi_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup6_i2c_apps_clk = {
+	.cbcr_reg = BLSP1_QUP6_I2C_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup6_i2c_apps_clk",
+		.parent = &blsp1_qup6_i2c_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup6_i2c_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup6_spi_apps_clk = {
+	.cbcr_reg = BLSP1_QUP6_SPI_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_qup6_spi_apps_clk",
+		.parent = &blsp1_qup6_spi_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_qup6_spi_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart1_apps_clk = {
+	.cbcr_reg = BLSP1_UART1_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_uart1_apps_clk",
+		.parent = &blsp1_uart1_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_uart1_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart2_apps_clk = {
+	.cbcr_reg = BLSP1_UART2_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_uart2_apps_clk",
+		.parent = &blsp1_uart2_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_uart2_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart3_apps_clk = {
+	.cbcr_reg = BLSP1_UART3_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_uart3_apps_clk",
+		.parent = &blsp1_uart3_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_uart3_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart4_apps_clk = {
+	.cbcr_reg = BLSP1_UART4_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_uart4_apps_clk",
+		.parent = &blsp1_uart4_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_uart4_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart5_apps_clk = {
+	.cbcr_reg = BLSP1_UART5_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_uart5_apps_clk",
+		.parent = &blsp1_uart5_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_uart5_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart6_apps_clk = {
+	.cbcr_reg = BLSP1_UART6_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_blsp1_uart6_apps_clk",
+		.parent = &blsp1_uart6_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_blsp1_uart6_apps_clk.c),
+	},
+};
+
+static struct local_vote_clk gcc_boot_rom_ahb_clk = {
+	.cbcr_reg = BOOT_ROM_AHB_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(10),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_boot_rom_ahb_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_boot_rom_ahb_clk.c),
+	},
+};
+
+static struct local_vote_clk gcc_ce1_ahb_clk = {
+	.cbcr_reg = CE1_AHB_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(3),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_ce1_ahb_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_ce1_ahb_clk.c),
+	},
+};
+
+static struct local_vote_clk gcc_ce1_axi_clk = {
+	.cbcr_reg = CE1_AXI_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(4),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_ce1_axi_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_ce1_axi_clk.c),
+	},
+};
+
+static struct local_vote_clk gcc_ce1_clk = {
+	.cbcr_reg = CE1_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(5),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_ce1_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_ce1_clk.c),
+	},
+};
+
+static struct branch_clk gcc_lpass_q6_axi_clk = {
+	.cbcr_reg = LPASS_Q6_AXI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_lpass_q6_axi_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_lpass_q6_axi_clk.c),
+	},
+};
+
+static struct branch_clk gcc_mss_cfg_ahb_clk = {
+	.cbcr_reg = MSS_CFG_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_mss_cfg_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_mss_cfg_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_mss_q6_bimc_axi_clk = {
+	.cbcr_reg = MSS_Q6_BIMC_AXI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_mss_q6_bimc_axi_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_mss_q6_bimc_axi_clk.c),
+	},
+};
+
+static struct branch_clk gcc_pcie_axi_clk = {
+	.cbcr_reg = PCIE_AXI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_pcie_axi_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_pcie_axi_clk.c),
+	},
+};
+
+static struct branch_clk gcc_pcie_axi_mstr_clk = {
+	.cbcr_reg = PCIE_AXI_MSTR_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_pcie_axi_mstr_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_pcie_axi_mstr_clk.c),
+	},
+};
+
+static struct branch_clk gcc_pcie_cfg_ahb_clk = {
+	.cbcr_reg = PCIE_CFG_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_pcie_cfg_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_pcie_cfg_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_pcie_pipe_clk = {
+	.cbcr_reg = PCIE_PIPE_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_pcie_pipe_clk",
+		.parent = &pcie_pipe_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_pcie_pipe_clk.c),
+	},
+};
+
+static struct branch_clk gcc_pcie_sleep_clk = {
+	.cbcr_reg = PCIE_SLEEP_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_pcie_sleep_clk",
+		.parent = &pcie_aux_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_pcie_sleep_clk.c),
+	},
+};
+
+static struct branch_clk gcc_pdm2_clk = {
+	.cbcr_reg = PDM2_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_pdm2_clk",
+		.parent = &pdm2_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_pdm2_clk.c),
+	},
+};
+
+static struct branch_clk gcc_pdm_ahb_clk = {
+	.cbcr_reg = PDM_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_pdm_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_pdm_ahb_clk.c),
+	},
+};
+
+static struct local_vote_clk gcc_prng_ahb_clk = {
+	.cbcr_reg = PRNG_AHB_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(13),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_prng_ahb_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_prng_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_sdcc2_ahb_clk = {
+	.cbcr_reg = SDCC2_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_sdcc2_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_sdcc2_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_sdcc2_apps_clk = {
+	.cbcr_reg = SDCC2_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_sdcc2_apps_clk",
+		.parent = &sdcc2_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_sdcc2_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_sdcc3_ahb_clk = {
+	.cbcr_reg = SDCC3_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_sdcc3_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_sdcc3_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_sdcc3_apps_clk = {
+	.cbcr_reg = SDCC3_APPS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_sdcc3_apps_clk",
+		.parent = &sdcc3_apps_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_sdcc3_apps_clk.c),
+	},
+};
+
+static struct branch_clk gcc_sys_noc_usb3_axi_clk = {
+	.cbcr_reg = SYS_NOC_USB3_AXI_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_sys_noc_usb3_axi_clk",
+		.parent = &usb30_master_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_sys_noc_usb3_axi_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb3_aux_clk = {
+	.cbcr_reg = USB3_AUX_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb3_aux_clk",
+		.parent = &usb3_aux_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb3_aux_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb3_pipe_clk = {
+	.cbcr_reg = USB3_PIPE_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb3_pipe_clk",
+		.parent = &usb3_pipe_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb3_pipe_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb30_master_clk = {
+	.cbcr_reg = USB30_MASTER_CBCR,
+	.bcr_reg = USB_30_BCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb30_master_clk",
+		.parent = &usb30_master_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb30_master_clk.c),
+		.depends = &gcc_sys_noc_usb3_axi_clk.c,
+	},
+};
+
+static struct branch_clk gcc_usb30_mock_utmi_clk = {
+	.cbcr_reg = USB30_MOCK_UTMI_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb30_mock_utmi_clk",
+		.parent = &usb30_mock_utmi_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb30_mock_utmi_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb30_sleep_clk = {
+	.cbcr_reg = USB30_SLEEP_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb30_sleep_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb30_sleep_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb_hs_ahb_clk = {
+	.cbcr_reg = USB_HS_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb_hs_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb_hs_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb_hs_system_clk = {
+	.cbcr_reg = USB_HS_SYSTEM_CBCR,
+	.has_sibling = 0,
+	.bcr_reg = USB_HS_BCR,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb_hs_system_clk",
+		.parent = &usb_hs_system_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb_hs_system_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb_hsic_ahb_clk = {
+	.cbcr_reg = USB_HSIC_AHB_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb_hsic_ahb_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb_hsic_ahb_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb_hsic_clk = {
+	.cbcr_reg = USB_HSIC_CBCR,
+	.has_sibling = 0,
+	.bcr_reg = USB_HS_HSIC_BCR,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb_hsic_clk",
+		.parent = &usb_hsic_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb_hsic_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb_hsic_io_cal_clk = {
+	.cbcr_reg = USB_HSIC_IO_CAL_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb_hsic_io_cal_clk",
+		.parent = &usb_hsic_io_cal_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb_hsic_io_cal_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb_hsic_io_cal_sleep_clk = {
+	.cbcr_reg = USB_HSIC_IO_CAL_SLEEP_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb_hsic_io_cal_sleep_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb_hsic_io_cal_sleep_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb_hsic_system_clk = {
+	.cbcr_reg = USB_HSIC_SYSTEM_CBCR,
+	.has_sibling = 0,
+	.bcr_reg = USB_HS_HSIC_BCR,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb_hsic_system_clk",
+		.parent = &usb_hsic_system_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb_hsic_system_clk.c),
+	},
+};
+
+static struct branch_clk gcc_usb_hsic_xcvr_fs_clk = {
+	.cbcr_reg = USB_HSIC_XCVR_FS_CBCR,
+	.has_sibling = 0,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb_hsic_xcvr_fs_clk",
+		.parent = &usb_hsic_xcvr_fs_clk_src.c,
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb_hsic_xcvr_fs_clk.c),
+	},
+};
+
+static struct branch_clk q6ss_ahb_lfabif_clk = {
+	.cbcr_reg = Q6SS_AHB_LFABIF_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "q6ss_ahb_lfabif_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(q6ss_ahb_lfabif_clk.c),
+	},
+};
+
+static struct branch_clk q6ss_ahbm_clk = {
+	.cbcr_reg = Q6SS_AHBM_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "q6ss_ahbm_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(q6ss_ahbm_clk.c),
+	},
+};
+
+static DEFINE_CLK_VOTER(pnoc_msmbus_clk, &pnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(snoc_msmbus_clk, &snoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(cnoc_msmbus_clk, &cnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(pnoc_msmbus_a_clk, &pnoc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(snoc_msmbus_a_clk, &snoc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(cnoc_msmbus_a_clk, &cnoc_a_clk.c, LONG_MAX);
+
+static DEFINE_CLK_VOTER(bimc_msmbus_clk, &bimc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(bimc_msmbus_a_clk, &bimc_a_clk.c, LONG_MAX);
+
+static DEFINE_CLK_VOTER(pnoc_sdcc2_clk, &pnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(pnoc_sdcc3_clk, &pnoc_clk.c, LONG_MAX);
+
+static DEFINE_CLK_VOTER(pnoc_sps_clk, &pnoc_clk.c, LONG_MAX);
+
+static DEFINE_CLK_BRANCH_VOTER(cxo_pil_lpass_clk, &xo.c);
+static DEFINE_CLK_BRANCH_VOTER(cxo_pil_mss_clk, &xo.c);
+
+static DEFINE_CLK_MEASURE(a7_m_clk);
+
+#ifdef CONFIG_DEBUG_FS
+
+struct measure_mux_entry {
+	struct clk *c;
+	int base;
+	u32 debug_mux;
+};
+
+struct measure_mux_entry measure_mux[] = {
+	{&gcc_mss_cfg_ahb_clk.c,               GCC_BASE, 0x0030},
+	{&gcc_mss_q6_bimc_axi_clk.c,           GCC_BASE, 0x0031},
+	{&gcc_usb30_master_clk.c,              GCC_BASE, 0x0050},
+	{&gcc_usb30_sleep_clk.c,               GCC_BASE, 0x0051},
+	{&gcc_usb30_mock_utmi_clk.c,           GCC_BASE, 0x0052},
+	{&gcc_usb3_pipe_clk.c,                 GCC_BASE, 0x0054},
+	{&gcc_usb3_aux_clk.c,                  GCC_BASE, 0x0055},
+	{&gcc_usb_hsic_ahb_clk.c,              GCC_BASE, 0x0058},
+	{&gcc_usb_hsic_system_clk.c,           GCC_BASE, 0x0059},
+	{&gcc_usb_hsic_clk.c,                  GCC_BASE, 0x005a},
+	{&gcc_usb_hsic_io_cal_clk.c,           GCC_BASE, 0x005b},
+	{&gcc_usb_hsic_io_cal_sleep_clk.c,     GCC_BASE, 0x005c},
+	{&gcc_usb_hsic_xcvr_fs_clk.c,          GCC_BASE, 0x005d},
+	{&gcc_usb_hs_system_clk.c,             GCC_BASE, 0x0060},
+	{&gcc_usb_hs_ahb_clk.c,                GCC_BASE, 0x0061},
+	{&gcc_sdcc2_apps_clk.c,                GCC_BASE, 0x0070},
+	{&gcc_sdcc2_ahb_clk.c,                 GCC_BASE, 0x0071},
+	{&gcc_sdcc3_apps_clk.c,                GCC_BASE, 0x0078},
+	{&gcc_sdcc3_ahb_clk.c,                 GCC_BASE, 0x0079},
+	{&gcc_blsp1_ahb_clk.c,                 GCC_BASE, 0x0088},
+	{&gcc_blsp1_qup1_spi_apps_clk.c,       GCC_BASE, 0x008a},
+	{&gcc_blsp1_qup1_i2c_apps_clk.c,       GCC_BASE, 0x008b},
+	{&gcc_blsp1_uart1_apps_clk.c,          GCC_BASE, 0x008c},
+	{&gcc_blsp1_qup2_spi_apps_clk.c,       GCC_BASE, 0x008e},
+	{&gcc_blsp1_qup2_i2c_apps_clk.c,       GCC_BASE, 0x0090},
+	{&gcc_blsp1_uart2_apps_clk.c,          GCC_BASE, 0x0091},
+	{&gcc_blsp1_qup3_spi_apps_clk.c,       GCC_BASE, 0x0093},
+	{&gcc_blsp1_qup3_i2c_apps_clk.c,       GCC_BASE, 0x0094},
+	{&gcc_blsp1_uart3_apps_clk.c,          GCC_BASE, 0x0095},
+	{&gcc_blsp1_qup4_spi_apps_clk.c,       GCC_BASE, 0x0098},
+	{&gcc_blsp1_qup4_i2c_apps_clk.c,       GCC_BASE, 0x0099},
+	{&gcc_blsp1_uart4_apps_clk.c,          GCC_BASE, 0x009a},
+	{&gcc_blsp1_qup5_spi_apps_clk.c,       GCC_BASE, 0x009c},
+	{&gcc_blsp1_qup5_i2c_apps_clk.c,       GCC_BASE, 0x009d},
+	{&gcc_blsp1_uart5_apps_clk.c,          GCC_BASE, 0x009e},
+	{&gcc_blsp1_qup6_spi_apps_clk.c,       GCC_BASE, 0x00a1},
+	{&gcc_blsp1_qup6_i2c_apps_clk.c,       GCC_BASE, 0x00a2},
+	{&gcc_blsp1_uart6_apps_clk.c,          GCC_BASE, 0x00a3},
+	{&gcc_pdm_ahb_clk.c,                   GCC_BASE, 0x00d0},
+	{&gcc_pdm2_clk.c,                      GCC_BASE, 0x00d2},
+	{&gcc_prng_ahb_clk.c,                  GCC_BASE, 0x00d8},
+	{&gcc_bam_dma_ahb_clk.c,               GCC_BASE, 0x00e0},
+	{&gcc_bam_dma_inactivity_timers_clk.c, GCC_BASE, 0x00e1},
+	{&gcc_boot_rom_ahb_clk.c,              GCC_BASE, 0x00f8},
+	{&gcc_ce1_clk.c,                       GCC_BASE, 0x0138},
+	{&gcc_ce1_axi_clk.c,                   GCC_BASE, 0x0139},
+	{&gcc_ce1_ahb_clk.c,                   GCC_BASE, 0x013a},
+	{&gcc_lpass_q6_axi_clk.c,              GCC_BASE, 0x0160},
+	{&gcc_pcie_cfg_ahb_clk.c,              GCC_BASE, 0x01f0},
+	{&gcc_pcie_pipe_clk.c,                 GCC_BASE, 0x01f1},
+	{&gcc_pcie_axi_clk.c,                  GCC_BASE, 0x01f2},
+	{&gcc_pcie_sleep_clk.c,                GCC_BASE, 0x01f3},
+	{&gcc_pcie_axi_mstr_clk.c,             GCC_BASE, 0x01f4},
+
+	{&bimc_clk.c,                          GCC_BASE, 0x0155},
+	{&cnoc_clk.c,                          GCC_BASE, 0x0008},
+	{&pnoc_clk.c,                          GCC_BASE, 0x0010},
+	{&snoc_clk.c,                          GCC_BASE, 0x0000},
+
+	{&q6ss_ahbm_clk.c,                   LPASS_BASE, 0x001d},
+	{&q6ss_ahb_lfabif_clk.c,             LPASS_BASE, 0x001e},
+
+	{&a7_m_clk,			  APCS_GCC_BASE,    0x3},
+	{&dummy_clk,				N_BASES, 0x0000},
+};
+
+static int measure_clk_set_parent(struct clk *c, struct clk *parent)
+{
+	struct measure_clk *clk = to_measure_clk(c);
+	unsigned long flags;
+	u32 regval, clk_sel, i;
+
+	if (!parent)
+		return -EINVAL;
+
+	for (i = 0; i < (ARRAY_SIZE(measure_mux) - 1); i++)
+		if (measure_mux[i].c == parent)
+			break;
+
+	if (measure_mux[i].c == &dummy_clk)
+		return -EINVAL;
+
+	spin_lock_irqsave(&local_clock_reg_lock, flags);
+	/*
+	 * Program the test vector, measurement period (sample_ticks)
+	 * and scaling multiplier.
+	 */
+	clk->sample_ticks = 0x10000;
+	clk->multiplier = 1;
+
+	writel_relaxed(0, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
+
+	switch (measure_mux[i].base) {
+
+	case GCC_BASE:
+		clk_sel = measure_mux[i].debug_mux;
+		break;
+
+	case APCS_GCC_BASE:
+		clk_sel = 0x16A;
+		regval = BVAL(5, 3, measure_mux[i].debug_mux);
+		writel_relaxed(regval, APCS_GCC_BASE(APCS_CLK_DIAG));
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	/* Set debug mux clock index */
+	regval = BVAL(9, 0, clk_sel);
+	writel_relaxed(regval, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
+
+	/* Activate debug clock output */
+	regval |= BIT(16);
+	writel_relaxed(regval, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
+
+	/* Make sure test vector is set before starting measurements. */
+	mb();
+	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
+
+	return 0;
+}
+
+/* Sample clock for 'ticks' reference clock ticks. */
+static u32 run_measurement(unsigned ticks)
+{
+	/* Stop counters and set the XO4 counter start value. */
+	writel_relaxed(ticks, GCC_REG_BASE(CLOCK_FRQ_MEASURE_CTL));
+
+	/* Wait for timer to become ready. */
+	while ((readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
+			BIT(25)) != 0)
+		cpu_relax();
+
+	/* Run measurement and wait for completion. */
+	writel_relaxed(BIT(20)|ticks, GCC_REG_BASE(CLOCK_FRQ_MEASURE_CTL));
+	while ((readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
+			BIT(25)) == 0)
+		cpu_relax();
+
+	/* Return measured ticks. */
+	return readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
+				BM(24, 0);
+}
+
+/*
+ * Perform a hardware rate measurement for a given clock.
+ * FOR DEBUG USE ONLY: Measurements take ~15 ms!
+ */
+static unsigned long measure_clk_get_rate(struct clk *c)
+{
+	unsigned long flags;
+	u32 gcc_xo4_reg_backup;
+	u64 raw_count_short, raw_count_full;
+	struct measure_clk *clk = to_measure_clk(c);
+	unsigned ret;
+
+	ret = clk_prepare_enable(&xo.c);
+	if (ret) {
+		pr_warning("CXO clock failed to enable. Can't measure\n");
+		return 0;
+	}
+
+	spin_lock_irqsave(&local_clock_reg_lock, flags);
+
+	/* Enable CXO/4 and RINGOSC branch. */
+	gcc_xo4_reg_backup = readl_relaxed(GCC_REG_BASE(GCC_XO_DIV4_CBCR));
+	writel_relaxed(0x1, GCC_REG_BASE(GCC_XO_DIV4_CBCR));
+
+	/*
+	 * The ring oscillator counter will not reset if the measured clock
+	 * is not running.  To detect this, run a short measurement before
+	 * the full measurement.  If the raw results of the two are the same
+	 * then the clock must be off.
+	 */
+
+	/* Run a short measurement. (~1 ms) */
+	raw_count_short = run_measurement(0x1000);
+	/* Run a full measurement. (~14 ms) */
+	raw_count_full = run_measurement(clk->sample_ticks);
+
+	writel_relaxed(gcc_xo4_reg_backup, GCC_REG_BASE(GCC_XO_DIV4_CBCR));
+
+	/* Return 0 if the clock is off. */
+	if (raw_count_full == raw_count_short) {
+		ret = 0;
+	} else {
+		/* Compute rate in Hz. */
+		raw_count_full = ((raw_count_full * 10) + 15) * 4800000;
+		do_div(raw_count_full, ((clk->sample_ticks * 10) + 35));
+		ret = (raw_count_full * clk->multiplier);
+	}
+
+	writel_relaxed(0x51A00, GCC_REG_BASE(PLLTEST_PAD_CFG));
+	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
+
+	clk_disable_unprepare(&xo.c);
+
+	return ret;
+}
+#else /* !CONFIG_DEBUG_FS */
+static int measure_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	return -EINVAL;
+}
+
+static unsigned long measure_clk_get_rate(struct clk *clk)
+{
+	return 0;
+}
+#endif /* CONFIG_DEBUG_FS */
+
+static struct clk_ops clk_ops_measure = {
+	.set_parent = measure_clk_set_parent,
+	.get_rate = measure_clk_get_rate,
+};
+
+static struct measure_clk measure_clk = {
+	.c = {
+		.dbg_name = "measure_clk",
+		.ops = &clk_ops_measure,
+		CLK_INIT(measure_clk.c),
+	},
+	.multiplier = 1,
+};
+
+static struct clk_lookup msm_clocks_krypton[] = {
+	CLK_LOOKUP("xo",	xo.c,	""),
+	CLK_LOOKUP("measure",	measure_clk.c,	"debug"),
+
+	/* PLLS */
+	CLK_LOOKUP("",	gpll0.c,	""),
+	CLK_LOOKUP("",	gpll1.c,	""),
+	CLK_LOOKUP("",  gpll0_ao.c,     ""),
+
+	/* PIL-LPASS */
+	CLK_LOOKUP("xo",          cxo_pil_lpass_clk.c, "fe200000.qcom,lpass"),
+	CLK_LOOKUP("bus_clk",  gcc_lpass_q6_axi_clk.c, "fe200000.qcom,lpass"),
+	CLK_LOOKUP("core_clk",    cxo_pil_lpass_clk.c, "fe200000.qcom,lpass"),
+	CLK_LOOKUP("iface_clk", q6ss_ahb_lfabif_clk.c, "fe200000.qcom,lpass"),
+	CLK_LOOKUP("reg_clk",         q6ss_ahbm_clk.c, "fe200000.qcom,lpass"),
+
+	/* PIL-MODEM */
+	CLK_LOOKUP("xo",              cxo_pil_mss_clk.c, "fc880000.qcom,mss"),
+	CLK_LOOKUP("bus_clk", gcc_mss_q6_bimc_axi_clk.c, "fc880000.qcom,mss"),
+	CLK_LOOKUP("iface_clk",   gcc_mss_cfg_ahb_clk.c, "fc880000.qcom,mss"),
+	CLK_LOOKUP("mem_clk",    gcc_boot_rom_ahb_clk.c, "fc880000.qcom,mss"),
+
+	/* SPS */
+	CLK_LOOKUP("dma_bam_pclk", gcc_bam_dma_ahb_clk.c, "msm_sps"),
+	CLK_LOOKUP("inactivity_clk", gcc_bam_dma_inactivity_timers_clk.c,
+								"msm_sps"),
+	CLK_LOOKUP("dfab_clk", pnoc_sps_clk.c, "msm_sps"),
+
+
+	CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f991f000.serial"),
+	CLK_LOOKUP("core_clk", gcc_blsp1_uart3_apps_clk.c, "f991f000.serial"),
+
+	CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f9928000.spi"),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup6_spi_apps_clk.c, "f9928000.spi"),
+
+	CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f9925000.i2c"),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup3_i2c_apps_clk.c, "f9925000.i2c"),
+
+	CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f991d000.uart"),
+	CLK_LOOKUP("core_clk", gcc_blsp1_uart1_apps_clk.c, "f991d000.uart"),
+
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup1_i2c_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup1_spi_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup2_i2c_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup2_spi_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup3_spi_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup4_i2c_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup4_spi_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup5_i2c_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup5_spi_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup6_i2c_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_qup6_spi_apps_clk.c, ""),
+
+	CLK_LOOKUP("core_clk", gcc_blsp1_uart2_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_uart4_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_uart5_apps_clk.c, ""),
+	CLK_LOOKUP("core_clk", gcc_blsp1_uart6_apps_clk.c, ""),
+
+	CLK_LOOKUP("iface_clk", gcc_prng_ahb_clk.c, "f9bff000.qcom,msm-rng"),
+
+	CLK_LOOKUP("core_clk", gcc_pdm2_clk.c, ""),
+	CLK_LOOKUP("iface_clk", gcc_pdm_ahb_clk.c, ""),
+
+	CLK_LOOKUP("iface_clk", gcc_sdcc2_ahb_clk.c, "msm_sdcc.2"),
+	CLK_LOOKUP("core_clk", gcc_sdcc2_apps_clk.c, "msm_sdcc.2"),
+	CLK_LOOKUP("bus_clk",  pnoc_sdcc2_clk.c, "msm_sdcc.2"),
+	CLK_LOOKUP("iface_clk", gcc_sdcc3_ahb_clk.c, "msm_sdcc.3"),
+	CLK_LOOKUP("core_clk", gcc_sdcc3_apps_clk.c, "msm_sdcc.3"),
+	CLK_LOOKUP("bus_clk", pnoc_sdcc3_clk.c, "msm_sdcc.3"),
+
+	CLK_LOOKUP("iface_clk", gcc_usb_hs_ahb_clk.c,     "f9a55000.usb"),
+	CLK_LOOKUP("core_clk", gcc_usb_hs_system_clk.c,   "f9a55000.usb"),
+	CLK_LOOKUP("iface_clk", gcc_usb_hsic_ahb_clk.c,	  "msm_hsic_host"),
+	CLK_LOOKUP("phy_clk", gcc_usb_hsic_clk.c,	  "msm_hsic_host"),
+	CLK_LOOKUP("cal_clk", gcc_usb_hsic_io_cal_clk.c,  "msm_hsic_host"),
+	CLK_LOOKUP("core_clk", gcc_usb_hsic_system_clk.c, "msm_hsic_host"),
+	CLK_LOOKUP("alt_core_clk", gcc_usb_hsic_xcvr_fs_clk.c, ""),
+	CLK_LOOKUP("inactivity_clk", gcc_usb_hsic_io_cal_sleep_clk.c,
+							"msm_hsic_host"),
+
+	CLK_LOOKUP("core_clk", gcc_ce1_clk.c, "fd400000.qcom,qcedev"),
+	CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, "fd400000.qcom,qcedev"),
+	CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, "fd400000.qcom,qcedev"),
+	CLK_LOOKUP("core_clk_src", ce1_clk_src.c, "fd400000.qcom,qcedev"),
+
+	CLK_LOOKUP("core_clk", gcc_ce1_clk.c, "fd400000.qcom,qcrypto"),
+	CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, "fd400000.qcom,qcrypto"),
+	CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, "fd400000.qcom,qcrypto"),
+	CLK_LOOKUP("core_clk_src", ce1_clk_src.c, "fd400000.qcom,qcrypto"),
+
+	/* RPM and voter clocks */
+	CLK_LOOKUP("bus_clk", snoc_clk.c, ""),
+	CLK_LOOKUP("bus_clk", pnoc_clk.c, ""),
+	CLK_LOOKUP("bus_clk", cnoc_clk.c, ""),
+	CLK_LOOKUP("mem_clk", bimc_clk.c, ""),
+	CLK_LOOKUP("bus_clk", snoc_a_clk.c, ""),
+	CLK_LOOKUP("bus_clk", pnoc_a_clk.c, ""),
+	CLK_LOOKUP("bus_clk", cnoc_a_clk.c, ""),
+	CLK_LOOKUP("mem_clk", bimc_a_clk.c, ""),
+
+	CLK_LOOKUP("bus_clk",	cnoc_msmbus_clk.c,	"msm_config_noc"),
+	CLK_LOOKUP("bus_a_clk",	cnoc_msmbus_a_clk.c,	"msm_config_noc"),
+	CLK_LOOKUP("bus_clk",	snoc_msmbus_clk.c,	"msm_sys_noc"),
+	CLK_LOOKUP("bus_a_clk",	snoc_msmbus_a_clk.c,	"msm_sys_noc"),
+	CLK_LOOKUP("bus_clk",	pnoc_msmbus_clk.c,	"msm_periph_noc"),
+	CLK_LOOKUP("bus_a_clk",	pnoc_msmbus_a_clk.c,	"msm_periph_noc"),
+	CLK_LOOKUP("mem_clk",	bimc_msmbus_clk.c,	"msm_bimc"),
+	CLK_LOOKUP("mem_a_clk",	bimc_msmbus_a_clk.c,	"msm_bimc"),
+
+	CLK_LOOKUP("a7_m_clk", a7_m_clk, ""),
+
+	/* CoreSight clocks */
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc322000.tmc"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc318000.tpiu"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc31c000.replicator"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc307000.tmc"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc31b000.funnel"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc319000.funnel"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc31a000.funnel"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc321000.stm"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc332000.etm"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc332000.jtagmm"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc308000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc309000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc30a000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc30b000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc30c000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc30d000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc30e000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc30f000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc310000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "fc333000.cti"),
+	CLK_LOOKUP("core_clk", qdss_clk.c, "f9011038.hwevent"),
+
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc322000.tmc"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc318000.tpiu"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc31c000.replicator"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc307000.tmc"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc31b000.funnel"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc319000.funnel"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc31a000.funnel"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc321000.stm"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc332000.etm"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc332000.jtagmm"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc308000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc309000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30a000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30b000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30c000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30d000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30e000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30f000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc310000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc333000.cti"),
+	CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "f9011038.hwevent"),
+
+	/* Misc rcgs without clients */
+	CLK_LOOKUP("",	usb30_master_clk_src.c,	""),
+	CLK_LOOKUP("",	blsp1_qup1_i2c_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	blsp1_qup1_spi_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	blsp1_qup2_i2c_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	blsp1_qup2_spi_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	blsp1_qup3_i2c_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	blsp1_qup3_spi_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	blsp1_qup4_i2c_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	blsp1_qup4_spi_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	blsp1_qup5_i2c_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	blsp1_qup5_spi_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	blsp1_qup6_i2c_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	blsp1_qup6_spi_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	blsp1_uart1_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	blsp1_uart2_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	blsp1_uart3_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	blsp1_uart4_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	blsp1_uart5_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	blsp1_uart6_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	pcie_aux_clk_src.c,	""),
+	CLK_LOOKUP("",	pcie_pipe_clk_src.c,	""),
+	CLK_LOOKUP("",	pdm2_clk_src.c,	""),
+	CLK_LOOKUP("",	sdcc2_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	sdcc3_apps_clk_src.c,	""),
+	CLK_LOOKUP("",	usb3_aux_clk_src.c,	""),
+	CLK_LOOKUP("",	usb3_pipe_clk_src.c,	""),
+	CLK_LOOKUP("",	usb30_mock_utmi_clk_src.c,	""),
+	CLK_LOOKUP("",	usb_hs_system_clk_src.c,	""),
+	CLK_LOOKUP("",	usb_hsic_clk_src.c,	""),
+	CLK_LOOKUP("",	usb_hsic_io_cal_clk_src.c,	""),
+	CLK_LOOKUP("",	usb_hsic_system_clk_src.c,	""),
+	CLK_LOOKUP("",	usb_hsic_xcvr_fs_clk_src.c,	""),
+
+	CLK_LOOKUP("",	gcc_pcie_axi_clk.c,	""),
+	CLK_LOOKUP("",	gcc_pcie_axi_mstr_clk.c,	""),
+	CLK_LOOKUP("",	gcc_pcie_cfg_ahb_clk.c,	""),
+	CLK_LOOKUP("",	gcc_pcie_pipe_clk.c,	""),
+	CLK_LOOKUP("",	gcc_pcie_sleep_clk.c,	""),
+	CLK_LOOKUP("",	gcc_sys_noc_usb3_axi_clk.c,	""),
+	CLK_LOOKUP("",	gcc_usb3_aux_clk.c,	""),
+	CLK_LOOKUP("",	gcc_usb3_pipe_clk.c,	""),
+	CLK_LOOKUP("",	gcc_usb30_master_clk.c,	""),
+	CLK_LOOKUP("",	gcc_usb30_mock_utmi_clk.c,	""),
+	CLK_LOOKUP("",	gcc_usb30_sleep_clk.c,	""),
+};
+
+static void __init reg_init(void)
+{
+	u32 regval;
+
+	/* Vote for GPLL0 to turn on. Needed by acpuclock. */
+	regval = readl_relaxed(GCC_REG_BASE(APCS_GPLL_ENA_VOTE));
+	regval |= BIT(0);
+	writel_relaxed(regval, GCC_REG_BASE(APCS_GPLL_ENA_VOTE));
+}
+
+static void __init msmkrypton_clock_post_init(void)
+{
+	/*
+	 * Hold an active set vote for CXO; this is because CXO is expected
+	 * to remain on whenever CPUs aren't power collapsed.
+	 */
+	clk_prepare_enable(&xo_a_clk.c);
+}
+
+#define GCC_CC_PHYS		0xFC400000
+#define GCC_CC_SIZE		SZ_8K
+
+#define LPASS_CC_PHYS		0xFE000000
+#define LPASS_CC_SIZE		SZ_256K
+
+#define APCS_GLB_PHYS		0xF9010000
+#define APCS_GLB_SIZE		0x38
+
+#define APCS_GCC_PHYS		0xF9011000
+#define APCS_GCC_SIZE		0x1C
+
+#define APCS_ACC_PHYS		0xF9008000
+#define APCS_ACC_SIZE		0x40
+
+static void __init msmkrypton_clock_pre_init(void)
+{
+	virt_bases[GCC_BASE] = ioremap(GCC_CC_PHYS, GCC_CC_SIZE);
+	if (!virt_bases[GCC_BASE])
+		panic("clock-krypton: Unable to ioremap GCC memory!");
+
+	virt_bases[LPASS_BASE] = ioremap(LPASS_CC_PHYS, LPASS_CC_SIZE);
+	if (!virt_bases[LPASS_BASE])
+		panic("clock-8226: Unable to ioremap LPASS_CC memory!");
+
+	virt_bases[APCS_GLB_BASE] = ioremap(APCS_GLB_PHYS, APCS_GLB_SIZE);
+	if (!virt_bases[APCS_GLB_BASE])
+		panic("clock-krypton: Unable to ioremap APCS_GLB memory!");
+
+	virt_bases[APCS_GCC_BASE] = ioremap(APCS_GCC_PHYS, APCS_GCC_SIZE);
+	if (!virt_bases[APCS_GCC_BASE])
+		panic("clock-krypton: Unable to ioremap APCS_GCC memory!");
+
+	virt_bases[APCS_ACC_BASE] = ioremap(APCS_ACC_PHYS, APCS_ACC_SIZE);
+	if (!virt_bases[APCS_ACC_BASE])
+		panic("clock-krypton: Unable to ioremap APCS_PLL memory!");
+
+	vdd_dig.regulator[0] = regulator_get(NULL, "vdd_dig");
+	if (IS_ERR(vdd_dig.regulator[0]))
+		panic("clock-krypton: Unable to get the vdd_dig regulator!");
+
+	enable_rpm_scaling();
+
+	reg_init();
+}
+
 struct clock_init_data msmkrypton_clock_init_data __initdata = {
-	.table = msm_clocks_dummy,
-	.size = ARRAY_SIZE(msm_clocks_dummy),
+	.table = msm_clocks_krypton,
+	.size = ARRAY_SIZE(msm_clocks_krypton),
+	.pre_init = msmkrypton_clock_pre_init,
+	.post_init = msmkrypton_clock_post_init,
 };
diff --git a/drivers/coresight/coresight-csr.c b/drivers/coresight/coresight-csr.c
index 6efab5b..16338a9 100644
--- a/drivers/coresight/coresight-csr.c
+++ b/drivers/coresight/coresight-csr.c
@@ -136,7 +136,7 @@
 }
 EXPORT_SYMBOL(msm_qdss_csr_disable_flush);
 
-int coresight_csr_hwctrl_set(phys_addr_t addr, uint32_t val)
+int coresight_csr_hwctrl_set(uint64_t addr, uint32_t val)
 {
 	struct csr_drvdata *drvdata = csrdrvdata;
 	int ret = 0;
diff --git a/drivers/coresight/coresight-hwevent.c b/drivers/coresight/coresight-hwevent.c
index 269d56e..4f75bcd 100644
--- a/drivers/coresight/coresight-hwevent.c
+++ b/drivers/coresight/coresight-hwevent.c
@@ -130,11 +130,11 @@
 {
 	struct hwevent_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	void *hwereg;
-	phys_addr_t addr;
-	uint32_t val;
+	unsigned long long addr;
+	unsigned long val;
 	int ret, i;
 
-	if (sscanf(buf, "%x %x", &addr, &val) != 2)
+	if (sscanf(buf, "%llx %lx", &addr, &val) != 2)
 		return -EINVAL;
 
 	mutex_lock(&drvdata->mutex);
@@ -153,7 +153,7 @@
 					      drvdata->hmux[i].end -
 					      drvdata->hmux[i].start);
 			if (!hwereg) {
-				dev_err(dev, "unable to map address 0x%x\n",
+				dev_err(dev, "unable to map address 0x%llx\n",
 					addr);
 				ret = -ENOMEM;
 				goto err;
diff --git a/drivers/coresight/coresight-priv.h b/drivers/coresight/coresight-priv.h
index 3ad1f34..fae1232 100644
--- a/drivers/coresight/coresight-priv.h
+++ b/drivers/coresight/coresight-priv.h
@@ -47,13 +47,13 @@
 extern void msm_qdss_csr_enable_bam_to_usb(void);
 extern void msm_qdss_csr_disable_bam_to_usb(void);
 extern void msm_qdss_csr_disable_flush(void);
-extern int coresight_csr_hwctrl_set(phys_addr_t addr, uint32_t val);
+extern int coresight_csr_hwctrl_set(uint64_t addr, uint32_t val);
 extern void coresight_csr_set_byte_cntr(uint32_t);
 #else
 static inline void msm_qdss_csr_enable_bam_to_usb(void) {}
 static inline void msm_qdss_csr_disable_bam_to_usb(void) {}
 static inline void msm_qdss_csr_disable_flush(void) {}
-static inline int coresight_csr_hwctrl_set(phys_addr_t addr,
+static inline int coresight_csr_hwctrl_set(uint64_t addr,
 					   uint32_t val) { return -ENOSYS; }
 static inline void coresight_csr_set_byte_cntr(uint32_t val) {}
 #endif
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index a052bd3..aaa2fc8 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -692,4 +692,16 @@
 	default "0"
 	help
 	  this provide the sensor position setting , value is between 0~7
+
+config SENSORS_STK3X1X
+	tristate "STK3X1X device driver"
+	depends on I2C
+	default n
+	help
+	  Say Y here you want to enable for the sitronix stk3x1x
+	  light and proximity sensors driver.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called stk3x1x.
+
 endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 4f29e05..445fba0 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -64,3 +64,4 @@
 obj-$(CONFIG_BMP18X)			+= bmp18x-core.o
 obj-$(CONFIG_BMP18X_I2C)		+= bmp18x-i2c.o
 obj-$(CONFIG_SENSORS_MMA8X5X)	  	+= mma8x5x.o
+obj-$(CONFIG_SENSORS_STK3X1X)		+= stk3x1x.o
diff --git a/drivers/input/misc/stk3x1x.c b/drivers/input/misc/stk3x1x.c
index 6e6b9ea..61f3530 100644
--- a/drivers/input/misc/stk3x1x.c
+++ b/drivers/input/misc/stk3x1x.c
@@ -43,6 +43,10 @@
 #include <linux/gpio.h>
 #include <linux/fs.h>
 #include <linux/uaccess.h>
+#include <linux/regulator/consumer.h>
+#ifdef CONFIG_OF
+#include <linux/of_gpio.h>
+#endif
 #ifdef CONFIG_HAS_EARLYSUSPEND
 #include <linux/earlysuspend.h>
 #endif
@@ -169,6 +173,12 @@
 #define ALS_NAME "lightsensor-level"
 #define PS_NAME "proximity"
 
+/* POWER SUPPLY VOLTAGE RANGE */
+#define STK3X1X_VDD_MIN_UV	2000000
+#define STK3X1X_VDD_MAX_UV	3300000
+#define STK3X1X_VIO_MIN_UV	1750000
+#define STK3X1X_VIO_MAX_UV	1950000
+
 struct stk3x1x_data {
 	struct i2c_client *client;
 #if (!defined(STK_POLL_PS) || !defined(STK_POLL_ALS))
@@ -205,6 +215,9 @@
     struct work_struct stk_als_work;
 	struct workqueue_struct *stk_als_wq;
 #endif
+	struct regulator *vdd;
+	struct regulator *vio;
+	bool power_enabled;
 };
 
 #if( !defined(CONFIG_STK_PS_ALS_USE_CHANGE_THRESHOLD))
@@ -1412,15 +1425,14 @@
 	return size;
 }
 
-
 static struct device_attribute als_enable_attribute = __ATTR(enable,0664,stk_als_enable_show,stk_als_enable_store);
 static struct device_attribute als_lux_attribute = __ATTR(lux,0664,stk_als_lux_show,stk_als_lux_store);
 static struct device_attribute als_code_attribute = __ATTR(code, 0444, stk_als_code_show, NULL);
 static struct device_attribute als_transmittance_attribute = __ATTR(transmittance,0664,stk_als_transmittance_show,stk_als_transmittance_store);
-static struct device_attribute als_poll_delay_attribute = __ATTR(delay,0664,stk_als_delay_show,stk_als_delay_store);
+static struct device_attribute als_poll_delay_attribute =
+	__ATTR(poll_delay, 0664, stk_als_delay_show, stk_als_delay_store);
 static struct device_attribute als_ir_code_attribute = __ATTR(ircode,0444,stk_als_ir_code_show,NULL);
 
-
 static struct attribute *stk_als_attrs [] =
 {
 	&als_enable_attribute.attr,
@@ -1433,7 +1445,6 @@
 };
 
 static struct attribute_group stk_als_attribute_group = {
-	.name = "driver",
 	.attrs = stk_als_attrs,
 };
 
@@ -1465,7 +1476,6 @@
 };
 
 static struct attribute_group stk_ps_attribute_group = {
-	.name = "driver",
 	.attrs = stk_ps_attrs,
 };
 
@@ -1793,6 +1803,205 @@
 }
 #endif	//#ifdef CONFIG_HAS_EARLYSUSPEND
 
+static int stk3x1x_power_on(struct stk3x1x_data *data, bool on)
+{
+	int ret = 0;
+
+	if (!on && data->power_enabled) {
+		ret = regulator_disable(data->vdd);
+		if (ret) {
+			dev_err(&data->client->dev,
+				"Regulator vdd disable failed ret=%d\n", ret);
+			return ret;
+		}
+
+		ret = regulator_disable(data->vio);
+		if (ret) {
+			dev_err(&data->client->dev,
+				"Regulator vio disable failed ret=%d\n", ret);
+			regulator_enable(data->vdd);
+		}
+	} else if (on && !data->power_enabled) {
+
+		ret = regulator_enable(data->vdd);
+		if (ret) {
+			dev_err(&data->client->dev,
+				"Regulator vdd enable failed ret=%d\n", ret);
+			return ret;
+		}
+
+		ret = regulator_enable(data->vio);
+		if (ret) {
+			dev_err(&data->client->dev,
+				"Regulator vio enable failed ret=%d\n", ret);
+			regulator_disable(data->vdd);
+		}
+	} else {
+		dev_warn(&data->client->dev,
+				"Power on=%d. enabled=%d\n",
+				on, data->power_enabled);
+	}
+
+	return ret;
+}
+
+static int stk3x1x_power_init(struct stk3x1x_data *data, bool on)
+{
+	int ret;
+
+	if (!on) {
+		if (regulator_count_voltages(data->vdd) > 0)
+			regulator_set_voltage(data->vdd,
+					0, STK3X1X_VDD_MAX_UV);
+
+		regulator_put(data->vdd);
+
+		if (regulator_count_voltages(data->vio) > 0)
+			regulator_set_voltage(data->vio,
+					0, STK3X1X_VIO_MAX_UV);
+
+		regulator_put(data->vio);
+	} else {
+		data->vdd = regulator_get(&data->client->dev, "vdd");
+		if (IS_ERR(data->vdd)) {
+			ret = PTR_ERR(data->vdd);
+			dev_err(&data->client->dev,
+				"Regulator get failed vdd ret=%d\n", ret);
+			return ret;
+		}
+
+		if (regulator_count_voltages(data->vdd) > 0) {
+			ret = regulator_set_voltage(data->vdd,
+					STK3X1X_VDD_MIN_UV,
+					STK3X1X_VDD_MAX_UV);
+			if (ret) {
+				dev_err(&data->client->dev,
+					"Regulator set failed vdd ret=%d\n",
+					ret);
+				goto reg_vdd_put;
+			}
+		}
+
+		data->vio = regulator_get(&data->client->dev, "vio");
+		if (IS_ERR(data->vio)) {
+			ret = PTR_ERR(data->vio);
+			dev_err(&data->client->dev,
+				"Regulator get failed vio ret=%d\n", ret);
+			goto reg_vdd_set;
+		}
+
+		if (regulator_count_voltages(data->vio) > 0) {
+			ret = regulator_set_voltage(data->vio,
+					STK3X1X_VIO_MIN_UV,
+					STK3X1X_VIO_MAX_UV);
+			if (ret) {
+				dev_err(&data->client->dev,
+				"Regulator set failed vio ret=%d\n", ret);
+				goto reg_vio_put;
+			}
+		}
+	}
+
+	return 0;
+
+reg_vio_put:
+	regulator_put(data->vio);
+reg_vdd_set:
+	if (regulator_count_voltages(data->vdd) > 0)
+		regulator_set_voltage(data->vdd, 0, STK3X1X_VDD_MAX_UV);
+reg_vdd_put:
+	regulator_put(data->vdd);
+	return ret;
+}
+
+#ifdef CONFIG_OF
+static int stk3x1x_parse_dt(struct device *dev,
+			struct stk3x1x_platform_data *pdata)
+{
+	int rc;
+	struct device_node *np = dev->of_node;
+	u32 temp_val;
+
+	pdata->int_pin = of_get_named_gpio_flags(np, "stk,irq-gpio",
+				0, &pdata->int_flags);
+	if (pdata->int_pin < 0) {
+		dev_err(dev, "Unable to read irq-gpio\n");
+		return pdata->int_pin;
+	}
+
+	rc = of_property_read_u32(np, "stk,transmittance", &temp_val);
+	if (!rc)
+		pdata->transmittance = temp_val;
+	else {
+		dev_err(dev, "Unable to read transmittance\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(np, "stk,state-reg", &temp_val);
+	if (!rc)
+		pdata->state_reg = temp_val;
+	else {
+		dev_err(dev, "Unable to read state-reg\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(np, "stk,psctrl-reg", &temp_val);
+	if (!rc)
+		pdata->psctrl_reg = (u8)temp_val;
+	else {
+		dev_err(dev, "Unable to read psctrl-reg\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(np, "stk,alsctrl-reg", &temp_val);
+	if (!rc)
+		pdata->alsctrl_reg = (u8)temp_val;
+	else {
+		dev_err(dev, "Unable to read alsctrl-reg\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(np, "stk,ledctrl-reg", &temp_val);
+	if (!rc)
+		pdata->ledctrl_reg = (u8)temp_val;
+	else {
+		dev_err(dev, "Unable to read ledctrl-reg\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(np, "stk,wait-reg", &temp_val);
+	if (!rc)
+		pdata->wait_reg = (u8)temp_val;
+	else {
+		dev_err(dev, "Unable to read wait-reg\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(np, "stk,ps-thdh", &temp_val);
+	if (!rc)
+		pdata->ps_thd_h = (u16)temp_val;
+	else {
+		dev_err(dev, "Unable to read ps-thdh\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(np, "stk,ps-thdl", &temp_val);
+	if (!rc)
+		pdata->ps_thd_l = (u16)temp_val;
+	else {
+		dev_err(dev, "Unable to read ps-thdl\n");
+		return rc;
+	}
+
+	return 0;
+}
+#else
+static int stk3x1x_parse_dt(struct device *dev,
+			struct stk3x1x_platform_data *pdata)
+{
+	return -ENODEV;
+}
+#endif /* !CONFIG_OF */
 
 static int stk3x1x_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
@@ -1827,20 +2036,33 @@
 #ifdef STK_POLL_PS
 	wake_lock_init(&ps_data->ps_nosuspend_wl,WAKE_LOCK_SUSPEND, "stk_nosuspend_wakelock");
 #endif
-	if(client->dev.platform_data != NULL)
-	{
-		plat_data = client->dev.platform_data;
-		ps_data->als_transmittance = plat_data->transmittance;
-		ps_data->int_pin = plat_data->int_pin;
-		if(ps_data->als_transmittance == 0)
-		{
-			printk(KERN_ERR "%s: Please set als_transmittance in platform data\n", __func__);
-			goto err_als_input_allocate;
+	if (client->dev.of_node) {
+		plat_data = devm_kzalloc(&client->dev,
+			sizeof(struct stk3x1x_platform_data), GFP_KERNEL);
+		if (!plat_data) {
+			dev_err(&client->dev, "Failed to allocate memory\n");
+			return -ENOMEM;
 		}
+
+		err = stk3x1x_parse_dt(&client->dev, plat_data);
+		dev_err(&client->dev,
+			"%s: stk3x1x_parse_dt ret=%d\n", __func__, err);
+		if (err)
+			return err;
+	} else
+		plat_data = client->dev.platform_data;
+
+	if (!plat_data) {
+		dev_err(&client->dev,
+			"%s: no stk3x1x platform data!\n", __func__);
+		goto err_als_input_allocate;
 	}
-	else
-	{
-		printk(KERN_ERR "%s: no stk3x1x platform data!\n", __func__);
+	ps_data->als_transmittance = plat_data->transmittance;
+	ps_data->int_pin = plat_data->int_pin;
+
+	if (ps_data->als_transmittance == 0) {
+		dev_err(&client->dev,
+			"%s: Please set als_transmittance\n", __func__);
 		goto err_als_input_allocate;
 	}
 
@@ -1913,6 +2135,14 @@
 		goto err_stk3x1x_setup_irq;
 #endif
 
+	err = stk3x1x_power_init(ps_data, true);
+	if (err)
+		goto err_power_init;
+
+	err = stk3x1x_power_on(ps_data, true);
+	if (err)
+		goto err_power_on;
+
 	err = stk3x1x_init_all_setting(client, plat_data);
 	if(err < 0)
 		goto err_init_all_setting;
@@ -1926,6 +2156,10 @@
 	return 0;
 
 err_init_all_setting:
+	stk3x1x_power_on(ps_data, false);
+err_power_on:
+	stk3x1x_power_init(ps_data, false);
+err_power_init:
 #ifndef STK_POLL_PS
 	free_irq(ps_data->irq, ps_data);
 	gpio_free(plat_data->int_pin);
@@ -2001,11 +2235,17 @@
 };
 MODULE_DEVICE_TABLE(i2c, stk_ps_id);
 
+static struct of_device_id stk_match_table[] = {
+	{ .compatible = "stk,stk3x1x", },
+	{ },
+};
+
 static struct i2c_driver stk_ps_driver =
 {
     .driver = {
         .name = DEVICE_NAME,
 		.owner = THIS_MODULE,
+		.of_match_table = stk_match_table,
     },
     .probe = stk3x1x_probe,
     .remove = stk3x1x_remove,
diff --git a/drivers/media/platform/msm/camera_v2/camera/camera.c b/drivers/media/platform/msm/camera_v2/camera/camera.c
index c70e151..0313161 100644
--- a/drivers/media/platform/msm/camera_v2/camera/camera.c
+++ b/drivers/media/platform/msm/camera_v2/camera/camera.c
@@ -353,6 +353,7 @@
 
 set_fmt_fail:
 	kzfree(sp->vb2_q.drv_priv);
+	sp->vb2_q.drv_priv = NULL;
 	return rc;
 }
 
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
index aa6f034..2ea4388 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
@@ -501,7 +501,8 @@
 		(int) buf_cmd.vaddr, buf_cmd.y_len);
 
 	buf_p->y_buffer_addr    = msm_jpeg_platform_v2p(pgmn_dev, buf_cmd.fd,
-		buf_cmd.y_len + buf_cmd.cbcr_len + buf_cmd.pln2_len,
+		buf_cmd.y_len + buf_cmd.cbcr_len +
+		buf_cmd.pln2_len + buf_cmd.offset,
 		&buf_p->file, &buf_p->handle, pgmn_dev->domain_num) +
 		buf_cmd.offset + buf_cmd.y_off;
 	buf_p->y_len          = buf_cmd.y_len;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
index 4fa3085..7f4f231 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
@@ -292,7 +292,7 @@
 static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd,
 	struct msm_camera_cci_ctrl *c_ctrl)
 {
-	uint32_t rc = 0;
+	int32_t rc = 0;
 	uint32_t val = 0;
 	int32_t read_words = 0, exp_words = 0;
 	int32_t index = 0, first_byte = 0;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h
index ac697fb..c713c85 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h
@@ -19,7 +19,7 @@
 #include <media/msm_cam_sensor.h>
 #include "msm_sd.h"
 
-#define MAX_LED_TRIGGERS 2
+#define MAX_LED_TRIGGERS 3
 
 struct msm_led_flash_ctrl_t;
 
@@ -38,10 +38,14 @@
 	struct msm_sd_subdev msm_sd;
 	struct platform_device *pdev;
 	struct msm_flash_fn_t *func_tbl;
-	const char *led_trigger_name[MAX_LED_TRIGGERS];
-	struct led_trigger *led_trigger[MAX_LED_TRIGGERS];
-	uint32_t op_current[MAX_LED_TRIGGERS];
+	const char *flash_trigger_name[MAX_LED_TRIGGERS];
+	struct led_trigger *flash_trigger[MAX_LED_TRIGGERS];
+	uint32_t flash_op_current[MAX_LED_TRIGGERS];
+	const char *torch_trigger_name;
+	struct led_trigger *torch_trigger;
+	uint32_t torch_op_current;
 	void *data;
+	uint32_t num_sources;
 };
 
 int32_t msm_led_flash_create_v4lsubdev(struct platform_device *pdev,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
index c6f1f72..1b0ec44 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
@@ -46,29 +46,45 @@
 {
 	int rc = 0;
 	struct msm_camera_led_cfg_t *cfg = (struct msm_camera_led_cfg_t *)data;
+	uint32_t i;
 	CDBG("called led_state %d\n", cfg->cfgtype);
 
-	if (!fctrl->led_trigger[0]) {
+	if (!fctrl) {
 		pr_err("failed\n");
 		return -EINVAL;
 	}
+
 	switch (cfg->cfgtype) {
 	case MSM_CAMERA_LED_OFF:
-		led_trigger_event(fctrl->led_trigger[0], 0);
+		for (i = 0; i < fctrl->num_sources; i++)
+			if (fctrl->flash_trigger[i])
+				led_trigger_event(fctrl->flash_trigger[i], 0);
+		if (fctrl->torch_trigger)
+			led_trigger_event(fctrl->torch_trigger, 0);
 		break;
 
 	case MSM_CAMERA_LED_LOW:
-		led_trigger_event(fctrl->led_trigger[0],
-			fctrl->op_current[0] / 2);
+		if (fctrl->torch_trigger)
+			led_trigger_event(fctrl->torch_trigger,
+				fctrl->torch_op_current);
 		break;
 
 	case MSM_CAMERA_LED_HIGH:
-		led_trigger_event(fctrl->led_trigger[0], fctrl->op_current[0]);
+		if (fctrl->torch_trigger)
+			led_trigger_event(fctrl->torch_trigger, 0);
+		for (i = 0; i < fctrl->num_sources; i++)
+			if (fctrl->flash_trigger[i])
+				led_trigger_event(fctrl->flash_trigger[i],
+					fctrl->flash_op_current[i]);
 		break;
 
 	case MSM_CAMERA_LED_INIT:
 	case MSM_CAMERA_LED_RELEASE:
-		led_trigger_event(fctrl->led_trigger[0], 0);
+		for (i = 0; i < fctrl->num_sources; i++)
+			if (fctrl->flash_trigger[i])
+				led_trigger_event(fctrl->flash_trigger[i], 0);
+		if (fctrl->torch_trigger)
+			led_trigger_event(fctrl->torch_trigger, 0);
 		break;
 
 	default:
@@ -109,6 +125,7 @@
 	}
 
 	fctrl.pdev = pdev;
+	fctrl.num_sources = 0;
 
 	rc = of_property_read_u32(of_node, "cell-index", &pdev->id);
 	if (rc < 0) {
@@ -124,6 +141,7 @@
 			pr_err("failed\n");
 			return -EINVAL;
 		}
+		fctrl.num_sources = count;
 		for (i = 0; i < count; i++) {
 			flash_src_node = of_parse_phandle(of_node,
 				"qcom,flash-source", i);
@@ -134,17 +152,18 @@
 
 			rc = of_property_read_string(flash_src_node,
 				"linux,default-trigger",
-				&fctrl.led_trigger_name[i]);
+				&fctrl.flash_trigger_name[i]);
 			if (rc < 0) {
 				pr_err("failed\n");
 				of_node_put(flash_src_node);
 				continue;
 			}
 
-			CDBG("default trigger %s\n", fctrl.led_trigger_name[i]);
+			CDBG("default trigger %s\n",
+				fctrl.flash_trigger_name[i]);
 
 			rc = of_property_read_u32(flash_src_node,
-				"qcom,current", &fctrl.op_current[i]);
+				"qcom,current", &fctrl.flash_op_current[i]);
 			if (rc < 0) {
 				pr_err("failed rc %d\n", rc);
 				of_node_put(flash_src_node);
@@ -153,10 +172,41 @@
 
 			of_node_put(flash_src_node);
 
-			CDBG("max_current[%d] %d\n", i, fctrl.op_current[i]);
+			CDBG("max_current[%d] %d\n",
+				i, fctrl.flash_op_current[i]);
 
-			led_trigger_register_simple(fctrl.led_trigger_name[i],
-				&fctrl.led_trigger[i]);
+			led_trigger_register_simple(fctrl.flash_trigger_name[i],
+				&fctrl.flash_trigger[i]);
+		}
+
+		/* Torch source */
+		flash_src_node = of_parse_phandle(of_node, "qcom,torch-source",
+			0);
+		if (flash_src_node) {
+			rc = of_property_read_string(flash_src_node,
+				"linux,default-trigger",
+				&fctrl.torch_trigger_name);
+			if (rc < 0) {
+				pr_err("failed\n");
+			} else {
+				CDBG("default trigger %s\n",
+					fctrl.torch_trigger_name);
+
+				rc = of_property_read_u32(flash_src_node,
+					"qcom,current",
+					&fctrl.torch_op_current);
+				if (rc < 0) {
+					pr_err("failed rc %d\n", rc);
+				} else {
+					CDBG("torch max_current %d\n",
+						fctrl.torch_op_current);
+
+					led_trigger_register_simple(
+						fctrl.torch_trigger_name,
+						&fctrl.torch_trigger);
+				}
+			}
+			of_node_put(flash_src_node);
 		}
 	}
 	rc = msm_led_flash_create_v4lsubdev(pdev, &fctrl);
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 7897068..cddca74 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -683,6 +683,18 @@
 		.qmenu = perf_level,
 		.step = 0,
 	},
+	{
+		.id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB,
+		.name = "Intra Refresh CIR MBS",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 0,
+		.maximum = MAX_INTRA_REFRESH_MBS,
+		.default_value = 0,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = MSM_VENC_CTRL_CLUSTER_INTRA_REFRESH,
+	}
 };
 
 #define NUM_CTRLS ARRAY_SIZE(msm_venc_ctrls)
@@ -1641,8 +1653,8 @@
 		air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
 		cir_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS);
 
-		property_id =
-			HAL_PARAM_VENC_INTRA_REFRESH;
+		property_id = HAL_PARAM_VENC_INTRA_REFRESH;
+
 		intra_refresh.air_mbs = ctrl->val;
 		intra_refresh.mode = ir_mode->val;
 		intra_refresh.air_ref = air_ref->val;
@@ -1658,8 +1670,8 @@
 		air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
 		cir_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS);
 
-		property_id =
-			HAL_PARAM_VENC_INTRA_REFRESH;
+		property_id = HAL_PARAM_VENC_INTRA_REFRESH;
+
 		intra_refresh.air_ref = ctrl->val;
 		intra_refresh.air_mbs = air_mbs->val;
 		intra_refresh.mode = ir_mode->val;
@@ -1676,8 +1688,7 @@
 		air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
 		air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
 
-		property_id =
-			HAL_PARAM_VENC_INTRA_REFRESH;
+		property_id = HAL_PARAM_VENC_INTRA_REFRESH;
 
 		intra_refresh.cir_mbs = ctrl->val;
 		intra_refresh.air_mbs = air_mbs->val;
@@ -1687,6 +1698,22 @@
 		pdata = &intra_refresh;
 		break;
 	}
+	case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: {
+		struct v4l2_ctrl *air_mbs, *air_ref;
+
+		air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
+		air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
+
+		property_id = HAL_PARAM_VENC_INTRA_REFRESH;
+
+		intra_refresh.cir_mbs = ctrl->val;
+		intra_refresh.air_mbs = air_mbs->val;
+		intra_refresh.air_ref = air_ref->val;
+		intra_refresh.mode = HAL_INTRA_REFRESH_CYCLIC;
+
+		pdata = &intra_refresh;
+		break;
+	}
 	case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
 		property_id =
 			HAL_PARAM_VENC_H264_DEBLOCK_CONTROL;
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index b9eb8f9..de6f1d5 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -126,6 +126,11 @@
 		struct rds_grp_data rds_buf);
 static void hci_ev_ert(struct iris_device *radio);
 static int update_spur_table(struct iris_device *radio);
+static int initialise_recv(struct iris_device *radio);
+static int initialise_trans(struct iris_device *radio);
+static int is_enable_rx_possible(struct iris_device *radio);
+static int is_enable_tx_possible(struct iris_device *radio);
+
 static struct v4l2_queryctrl iris_v4l2_queryctrl[] = {
 	{
 	.id	= V4L2_CID_AUDIO_VOLUME,
@@ -1633,13 +1638,16 @@
 	__u8 status = *((__u8 *) skb->data);
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 
-	if (status)
-		return;
-	if ((radio->mode != FM_CALIB) && (radio->mode != FM_OFF))
+	if ((radio->mode == FM_TURNING_OFF) && (status == 0)) {
 		iris_q_event(radio, IRIS_EVT_RADIO_DISABLED);
-	radio->mode = FM_OFF;
-
-	radio_hci_req_complete(hdev, status);
+		radio_hci_req_complete(hdev, status);
+		radio->mode = FM_OFF;
+	} else if (radio->mode == FM_CALIB) {
+		radio_hci_req_complete(hdev, status);
+	} else if ((radio->mode == FM_RECV) || (radio->mode == FM_TRANS)) {
+		iris_q_event(radio, IRIS_EVT_RADIO_DISABLED);
+		radio->mode = FM_OFF;
+	}
 }
 
 static void hci_cc_conf_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
@@ -1673,11 +1681,18 @@
 	struct hci_fm_conf_rsp  *rsp = (void *)skb->data;
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 
-	if (rsp->status)
+	if (rsp->status) {
+		radio_hci_req_complete(hdev, rsp->status);
 		return;
-	if (radio->mode != FM_CALIB)
-		iris_q_event(radio, IRIS_EVT_RADIO_READY);
+	}
 
+	if (radio->mode == FM_RECV_TURNING_ON) {
+		radio->mode = FM_RECV;
+		iris_q_event(radio, IRIS_EVT_RADIO_READY);
+	} else if (radio->mode == FM_TRANS_TURNING_ON) {
+		radio->mode = FM_TRANS;
+		iris_q_event(radio, IRIS_EVT_RADIO_READY);
+	}
 	radio_hci_req_complete(hdev, rsp->status);
 }
 
@@ -2695,7 +2710,9 @@
 			radio->fm_hdev);
 	if (retval < 0)
 		FMDERR("Disable Failed after calibration %d", retval);
-	radio->mode = FM_TURNING_OFF;
+	else
+		radio->mode = FM_OFF;
+
 	return retval;
 }
 static int iris_vidioc_g_ctrl(struct file *file, void *priv,
@@ -3177,82 +3194,60 @@
 	case V4L2_CID_PRIVATE_IRIS_STATE:
 		switch (ctrl->value) {
 		case FM_RECV:
+			if (is_enable_rx_possible(radio) != 0)
+				return -EINVAL;
+			radio->mode = FM_RECV_TURNING_ON;
 			retval = hci_cmd(HCI_FM_ENABLE_RECV_CMD,
 							 radio->fm_hdev);
 			if (retval < 0) {
 				FMDERR("Error while enabling RECV FM"
 							" %d\n", retval);
+				radio->mode = FM_OFF;
 				return retval;
+			} else {
+				initialise_recv(radio);
 			}
-			radio->mode = FM_RECV;
-			radio->mute_mode.soft_mute = CTRL_ON;
-			retval = hci_set_fm_mute_mode(
-						&radio->mute_mode,
-							radio->fm_hdev);
-			if (retval < 0) {
-				FMDERR("Failed to enable Smute\n");
-				return retval;
-			}
-			radio->stereo_mode.stereo_mode = CTRL_OFF;
-			radio->stereo_mode.sig_blend = CTRL_ON;
-			radio->stereo_mode.intf_blend = CTRL_ON;
-			radio->stereo_mode.most_switch = CTRL_ON;
-			retval = hci_set_fm_stereo_mode(
-						&radio->stereo_mode,
-							radio->fm_hdev);
-			if (retval < 0) {
-				FMDERR("Failed to set stereo mode\n");
-				return retval;
-			}
-			radio->event_mask = SIG_LEVEL_INTR |
-						RDS_SYNC_INTR | AUDIO_CTRL_INTR;
-			retval = hci_conf_event_mask(&radio->event_mask,
-							radio->fm_hdev);
-			if (retval < 0) {
-				FMDERR("Enable Async events failed");
-				return retval;
-			}
-			retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
-						radio->fm_hdev);
-			if (retval < 0)
-				FMDERR("Failed to get the Recv Config\n");
 			break;
 		case FM_TRANS:
+			if (!is_enable_tx_possible(radio) != 0)
+				return -EINVAL;
+			radio->mode = FM_TRANS_TURNING_ON;
 			retval = hci_cmd(HCI_FM_ENABLE_TRANS_CMD,
 							 radio->fm_hdev);
 			if (retval < 0) {
 				FMDERR("Error while enabling TRANS FM"
 							" %d\n", retval);
+				radio->mode = FM_OFF;
 				return retval;
+			} else {
+				initialise_trans(radio);
 			}
-			radio->mode = FM_TRANS;
-			retval = hci_cmd(HCI_FM_GET_TX_CONFIG, radio->fm_hdev);
-			if (retval < 0)
-				FMDERR("get frequency failed %d\n", retval);
 			break;
 		case FM_OFF:
 			radio->spur_table_size = 0;
 			switch (radio->mode) {
 			case FM_RECV:
+				radio->mode = FM_TURNING_OFF;
 				retval = hci_cmd(HCI_FM_DISABLE_RECV_CMD,
 						radio->fm_hdev);
 				if (retval < 0) {
 					FMDERR("Err on disable recv FM"
 						   " %d\n", retval);
+					radio->mode = FM_RECV;
 					return retval;
 				}
-				radio->mode = FM_TURNING_OFF;
 				break;
 			case FM_TRANS:
+				radio->mode = FM_TURNING_OFF;
 				retval = hci_cmd(HCI_FM_DISABLE_TRANS_CMD,
 						radio->fm_hdev);
 
 				if (retval < 0) {
 					FMDERR("Err disabling trans FM"
 						" %d\n", retval);
+					radio->mode = FM_TRANS;
 					return retval;
 				}
-				radio->mode = FM_TURNING_OFF;
 				break;
 			default:
 				retval = -EINVAL;
@@ -4132,6 +4127,73 @@
 	return 0;
 }
 
+static int initialise_recv(struct iris_device *radio)
+{
+	int retval;
+
+	radio->mute_mode.soft_mute = CTRL_ON;
+	retval = hci_set_fm_mute_mode(&radio->mute_mode,
+					radio->fm_hdev);
+
+	if (retval < 0) {
+		FMDERR("Failed to enable Smute\n");
+		return retval;
+	}
+
+	radio->stereo_mode.stereo_mode = CTRL_OFF;
+	radio->stereo_mode.sig_blend = CTRL_ON;
+	radio->stereo_mode.intf_blend = CTRL_ON;
+	radio->stereo_mode.most_switch = CTRL_ON;
+	retval = hci_set_fm_stereo_mode(&radio->stereo_mode,
+						radio->fm_hdev);
+
+	if (retval < 0) {
+		FMDERR("Failed to set stereo mode\n");
+		return retval;
+	}
+
+	radio->event_mask = SIG_LEVEL_INTR | RDS_SYNC_INTR | AUDIO_CTRL_INTR;
+	retval = hci_conf_event_mask(&radio->event_mask, radio->fm_hdev);
+	if (retval < 0) {
+		FMDERR("Enable Async events failed");
+		return retval;
+	}
+
+	retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD, radio->fm_hdev);
+	if (retval < 0)
+		FMDERR("Failed to get the Recv Config\n");
+	return retval;
+}
+
+static int initialise_trans(struct iris_device *radio)
+{
+
+	int retval = hci_cmd(HCI_FM_GET_TX_CONFIG, radio->fm_hdev);
+	if (retval < 0)
+		FMDERR("get frequency failed %d\n", retval);
+
+	return retval;
+}
+
+static int is_enable_rx_possible(struct iris_device *radio)
+{
+	int retval = 1;
+
+	if (radio->mode == FM_OFF || radio->mode == FM_RECV)
+		retval = 0;
+
+	return retval;
+}
+
+static int is_enable_tx_possible(struct iris_device *radio)
+{
+	int retval = 1;
+
+	if (radio->mode == FM_OFF || radio->mode == FM_TRANS)
+		retval = 0;
+
+	return retval;
+}
 
 static const struct v4l2_ioctl_ops iris_ioctl_ops = {
 	.vidioc_querycap              = iris_vidioc_querycap,
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 657fc2f..1262306 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -81,9 +81,16 @@
 
 #define PRONTO_PMU_SPARE_OFFSET       0x1088
 
-#define PRONTO_PMU_GDSCR_OFFSET       0x0024
-#define PRONTO_PMU_GDSCR_SW_COLLAPSE  BIT(0)
-#define PRONTO_PMU_GDSCR_HW_CTRL      BIT(1)
+#define PRONTO_PMU_COM_GDSCR_OFFSET       0x0024
+#define PRONTO_PMU_COM_GDSCR_SW_COLLAPSE  BIT(0)
+#define PRONTO_PMU_COM_GDSCR_HW_CTRL      BIT(1)
+
+#define PRONTO_PMU_WLAN_BCR_OFFSET         0x0050
+#define PRONTO_PMU_WLAN_BCR_BLK_ARES       BIT(0)
+
+#define PRONTO_PMU_WLAN_GDSCR_OFFSET       0x0054
+#define PRONTO_PMU_WLAN_GDSCR_SW_COLLAPSE  BIT(0)
+
 
 #define PRONTO_PMU_CBCR_OFFSET        0x0008
 #define PRONTO_PMU_CBCR_CLK_EN        BIT(0)
@@ -118,6 +125,9 @@
 #define MSM_PRONTO_PLL_BASE				0xfb21b1c0
 #define PRONTO_PLL_STATUS_OFFSET		0x1c
 
+#define MSM_PRONTO_TXP_PHY_ABORT        0xfb080488
+#define MSM_PRONTO_BRDG_ERR_SRC         0xfb080fb0
+
 #define WCNSS_DEF_WLAN_RX_BUFF_COUNT		1024
 
 #define WCNSS_CTRL_CHANNEL			"WCNSS_CTRL"
@@ -296,6 +306,8 @@
 	void __iomem *pronto_ccpu_base;
 	void __iomem *pronto_saw2_base;
 	void __iomem *pronto_pll_base;
+	void __iomem *wlan_tx_phy_aborts;
+	void __iomem *wlan_brdg_err_source;
 	void __iomem *fiq_reg;
 	int	ssr_boot;
 	int	nv_downloaded;
@@ -435,14 +447,14 @@
 void wcnss_pronto_log_debug_regs(void)
 {
 	void __iomem *reg_addr, *tst_addr, *tst_ctrl_addr;
-	u32 reg = 0;
+	u32 reg = 0, reg2 = 0;
 
 
 	reg_addr = penv->msm_wcnss_base + PRONTO_PMU_SPARE_OFFSET;
 	reg = readl_relaxed(reg_addr);
 	pr_info_ratelimited("%s:  PRONTO_PMU_SPARE %08x\n", __func__, reg);
 
-	reg_addr = penv->msm_wcnss_base + PRONTO_PMU_GDSCR_OFFSET;
+	reg_addr = penv->msm_wcnss_base + PRONTO_PMU_COM_GDSCR_OFFSET;
 	reg = readl_relaxed(reg_addr);
 	reg >>= 31;
 
@@ -451,7 +463,8 @@
 				__func__);
 		return;
 	}
-	reg &= ~(PRONTO_PMU_GDSCR_SW_COLLAPSE | PRONTO_PMU_GDSCR_HW_CTRL);
+	reg &= ~(PRONTO_PMU_COM_GDSCR_SW_COLLAPSE
+			| PRONTO_PMU_COM_GDSCR_HW_CTRL);
 	writel_relaxed(reg, reg_addr);
 
 	reg_addr = penv->msm_wcnss_base + PRONTO_PMU_CBCR_OFFSET;
@@ -557,6 +570,26 @@
 	reg = readl_relaxed(tst_addr);
 	pr_info_ratelimited("%s:  CTRL SEL CFG1 testbus %08x\n", __func__, reg);
 
+
+	reg_addr = penv->msm_wcnss_base + PRONTO_PMU_WLAN_BCR_OFFSET;
+	reg = readl_relaxed(reg_addr);
+
+	reg_addr = penv->msm_wcnss_base + PRONTO_PMU_WLAN_GDSCR_OFFSET;
+	reg2 = readl_relaxed(reg_addr);
+
+	if ((reg & PRONTO_PMU_WLAN_BCR_BLK_ARES) ||
+			(reg2 & PRONTO_PMU_WLAN_GDSCR_SW_COLLAPSE)) {
+		pr_info_ratelimited("%s:  Cannot log, wlan domain is power collapsed\n",
+				__func__);
+		return;
+	}
+
+	reg = readl_relaxed(penv->wlan_tx_phy_aborts);
+	pr_info_ratelimited("%s: WLAN_TX_PHY_ABORTS %08x\n", __func__, reg);
+
+	reg = readl_relaxed(penv->wlan_brdg_err_source);
+	pr_info_ratelimited("%s: WLAN_BRDG_ERR_SOURCE %08x\n", __func__, reg);
+
 }
 EXPORT_SYMBOL(wcnss_pronto_log_debug_regs);
 
@@ -1716,6 +1749,21 @@
 			goto fail_ioremap6;
 		}
 
+		penv->wlan_tx_phy_aborts =  ioremap(MSM_PRONTO_TXP_PHY_ABORT,
+					SZ_8);
+		if (!penv->wlan_tx_phy_aborts) {
+			ret = -ENOMEM;
+			pr_err("%s: ioremap wlan TX PHY failed\n", __func__);
+			goto fail_ioremap7;
+		}
+		penv->wlan_brdg_err_source =  ioremap(MSM_PRONTO_BRDG_ERR_SRC,
+							SZ_8);
+		if (!penv->wlan_brdg_err_source) {
+			ret = -ENOMEM;
+			pr_err("%s: ioremap wlan BRDG ERR failed\n", __func__);
+			goto fail_ioremap8;
+		}
+
 	}
 
 	/* trigger initialization of the WCNSS */
@@ -1732,6 +1780,12 @@
 fail_pil:
 	if (penv->riva_ccu_base)
 		iounmap(penv->riva_ccu_base);
+	if (penv->wlan_brdg_err_source)
+		iounmap(penv->wlan_brdg_err_source);
+fail_ioremap8:
+	if (penv->wlan_tx_phy_aborts)
+		iounmap(penv->wlan_tx_phy_aborts);
+fail_ioremap7:
 	if (penv->pronto_pll_base)
 		iounmap(penv->pronto_pll_base);
 fail_ioremap6:
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index 408681c..8bb4f90 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -162,6 +162,11 @@
 	struct work_struct finish_suspend_work;
 };
 
+struct usb_bam_hsic_host_info {
+	struct device *dev;
+	bool in_lpm;
+};
+
 static spinlock_t usb_bam_ipa_handshake_info_lock;
 static struct usb_bam_ipa_handshake_info info;
 static spinlock_t usb_bam_peer_handshake_info_lock;
@@ -169,8 +174,7 @@
 static spinlock_t usb_bam_lock; /* Protect ctx and usb_bam_connections */
 static struct usb_bam_pipe_connect *usb_bam_connections;
 static struct usb_bam_ctx_type ctx;
-
-static struct device *hsic_host_dev;
+static struct usb_bam_hsic_host_info hsic_host_info;
 
 static int __usb_bam_register_wake_cb(u8 idx, int (*callback)(void *user),
 	void *param, bool trigger_cb_per_pipe);
@@ -184,15 +188,16 @@
 		pr_debug("%s: Getting hsic device %x\n", __func__,
 			(int)dev);
 		pm_runtime_get(dev);
-	} else if (hsic_host_dev) {
+	} else if (hsic_host_info.dev) {
 		pr_debug("%s: Putting hsic device %x\n", __func__,
-			(int)hsic_host_dev);
+			(int)hsic_host_info.dev);
 		/* Just free previous device*/
 		info.in_lpm[HSIC_BAM] = true;
-		pm_runtime_put(hsic_host_dev);
+		pm_runtime_put(hsic_host_info.dev);
 	}
 
-	hsic_host_dev = dev;
+	hsic_host_info.dev = dev;
+	hsic_host_info.in_lpm = false;
 }
 
 static int get_bam_type_from_core_name(const char *name)
@@ -847,18 +852,24 @@
 	return;
 }
 
+/**
+ * usb_bam_resume_hsic_host: vote for hsic host core resume.
+ * In addition also resume all hsic pipes that are connected to
+ * the ipa peer bam.
+ *
+ * NOTE: This function should be called in a context that hold
+ *	 usb_bam_lock.
+ */
 static void usb_bam_resume_hsic_host(void)
 {
 	int i;
 	struct usb_bam_pipe_connect *pipe_iter;
 
-	spin_lock(&usb_bam_lock);
-
 	/* Exit from "full suspend" in case of hsic host */
-	if (hsic_host_dev && info.in_lpm[HSIC_BAM]) {
+	if (hsic_host_info.dev && info.in_lpm[HSIC_BAM]) {
 		pr_debug("%s: Getting hsic device %x\n", __func__,
-			(int)hsic_host_dev);
-		pm_runtime_get(hsic_host_dev);
+			(int)hsic_host_info.dev);
+		pm_runtime_get(hsic_host_info.dev);
 		info.in_lpm[HSIC_BAM] = false;
 
 		for (i = 0; i < ctx.max_connections; i++) {
@@ -873,8 +884,6 @@
 			}
 		}
 	}
-
-	spin_unlock(&usb_bam_lock);
 }
 
 static int cons_request_resource(enum usb_bam cur_bam)
@@ -905,16 +914,26 @@
 
 		break;
 	case HSIC_BAM:
+		/*
+		 * Vote for hsic resume, however the core
+		 * resume may not be completed yet or on the other hand
+		 * hsic core might already be resumed, due to a vote
+		 * by other driver, in this case we will just renew our
+		 * vote here.
+		 */
+		usb_bam_resume_hsic_host();
 
-			usb_bam_resume_hsic_host();
+		/*
+		 * Return sucess if there are pipes connected
+		 * and hsic core is actually not in lpm.
+		 * If in lpm, grant will occur on resume
+		 * finish (see msm_bam_hsic_notify_on_resume)
+		 */
+		if (ctx.pipes_enabled_per_bam[cur_bam] &&
+		    !hsic_host_info.in_lpm) {
+			ret = 0;
+		}
 
-			/*
-			 * Return sucess if there are pipes connected
-			 * and not in lpm
-			 */
-			if (ctx.pipes_enabled_per_bam[cur_bam] &&
-			    !info.in_lpm[cur_bam])
-				ret = 0;
 		break;
 	case SSUSB_BAM:
 	default:
@@ -926,6 +945,7 @@
 
 	if (ret == -EINPROGRESS)
 		pr_debug("%s: EINPROGRESS on cons_request", __func__);
+
 	return ret;
 }
 
@@ -968,10 +988,10 @@
 		 * Allow to go to lpm for now. Actual state will be checked
 		 * in msm_bam_hsic_lpm_ok() just before going to lpm.
 		 */
-		if (hsic_host_dev && !info.in_lpm[HSIC_BAM]) {
+		if (hsic_host_info.dev && !info.in_lpm[HSIC_BAM]) {
 			pr_debug("%s: Putting hsic device %x\n", __func__,
-			(int)hsic_host_dev);
-			pm_runtime_put(hsic_host_dev);
+			(int)hsic_host_info.dev);
+			pm_runtime_put(hsic_host_info.dev);
 			info.in_lpm[HSIC_BAM] = true;
 		}
 	}
@@ -1315,6 +1335,8 @@
 
 void msm_bam_wait_for_hsic_prod_granted(void)
 {
+	spin_lock(&usb_bam_lock);
+
 	ctx.is_bam_inactivity[HSIC_BAM] = false;
 
 	/* Get back to resume state including wakeup ipa */
@@ -1322,10 +1344,19 @@
 
 	/* Ensure getting the producer resource */
 	wait_for_prod_granted(HSIC_BAM);
+
+	spin_unlock(&usb_bam_lock);
 }
 
 void msm_bam_hsic_notify_on_resume(void)
 {
+	spin_lock(&usb_bam_lock);
+
+	hsic_host_info.in_lpm = false;
+
+	/* HSIC resume completed. Notify CONS grant if CONS was requested */
+	notify_usb_connected(HSIC_BAM);
+
 	/*
 	 * This function is called to notify the usb bam driver
 	 * that the hsic core and hsic bam hw are fully resumed
@@ -1334,6 +1365,8 @@
 	 */
 	if (ctx.inactivity_timer_ms[HSIC_BAM])
 		usb_bam_set_inactivity_timer(HSIC_BAM);
+
+	spin_unlock(&usb_bam_lock);
 }
 
 bool msm_bam_hsic_lpm_ok(void)
@@ -1341,7 +1374,7 @@
 	int i;
 	struct usb_bam_pipe_connect *pipe_iter;
 
-	if (hsic_host_dev) {
+	if (hsic_host_info.dev) {
 
 		pr_debug("%s: Starting hsic full suspend sequence\n",
 			__func__);
@@ -1363,7 +1396,7 @@
 
 			/* HSIC host will go now to lpm */
 			pr_debug("%s: vote for suspend hsic %x\n",
-				__func__, (int)hsic_host_dev);
+				__func__, (int)hsic_host_info.dev);
 
 			for (i = 0; i < ctx.max_connections; i++) {
 				pipe_iter =
@@ -1379,6 +1412,8 @@
 				}
 			}
 
+			hsic_host_info.in_lpm = true;
+
 			spin_unlock(&usb_bam_lock);
 			return true;
 		}
@@ -1392,7 +1427,7 @@
 				info.cur_cons_state[HSIC_BAM],
 				info.cur_prod_state[HSIC_BAM],
 				info.in_lpm[HSIC_BAM]);
-			pm_runtime_get(hsic_host_dev);
+			pm_runtime_get(hsic_host_info.dev);
 			info.in_lpm[HSIC_BAM] = false;
 			spin_unlock(&usb_bam_lock);
 		} else
@@ -1469,11 +1504,11 @@
 		sps_device_reset(ctx.h_bam[cur_bam]);
 
 		/* On re-connect assume out from lpm for HSIC BAM */
-		if (cur_bam == HSIC_BAM && hsic_host_dev &&
+		if (cur_bam == HSIC_BAM && hsic_host_info.dev &&
 		    info.in_lpm[HSIC_BAM]) {
 			pr_debug("%s: Getting hsic device %x\n",
-					__func__, (int)hsic_host_dev);
-			pm_runtime_get(hsic_host_dev);
+					__func__, (int)hsic_host_info.dev);
+			pm_runtime_get(hsic_host_info.dev);
 		}
 
 		/* On re-connect assume out from lpm for all BAMs */
@@ -1583,8 +1618,10 @@
 		 * until we complete releasing the hsic consumer and producer
 		 * resources against the ipa resource manager.
 		 */
+		spin_lock(&usb_bam_lock);
 		if (pipe_connect->bam_type == HSIC_BAM)
 			usb_bam_resume_hsic_host();
+		spin_unlock(&usb_bam_lock);
 
 		/* Notify about wakeup / activity of the bam */
 		if (event_info->callback)
@@ -1660,12 +1697,12 @@
 		 * If consumer is up, we will wait to the release consumer
 		 * notification.
 		 */
-		if (hsic_host_dev &&
+		if (hsic_host_info.dev &&
 		    info.cur_cons_state[HSIC_BAM] ==
 		    IPA_RM_RESOURCE_RELEASED && !info.in_lpm[HSIC_BAM]) {
 			pr_debug("%s: Putting hsic device %x\n", __func__,
-			(int)hsic_host_dev);
-			pm_runtime_put(hsic_host_dev);
+			(int)hsic_host_info.dev);
+			pm_runtime_put(hsic_host_info.dev);
 			info.in_lpm[HSIC_BAM] = true;
 		}
 
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 43d17c2..b46bbaf 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -25,6 +25,14 @@
 	tristate "Android log driver"
 	default n
 
+config LOGCAT_SIZE
+	int "Adjust android log buffer sizes"
+	default 256
+	depends on ANDROID_LOGGER
+	help
+	  Set logger buffer size. Enter a number greater than zero.
+	  Any value less than 256 is recommended. Reduce value to save kernel static memory size.
+
 config ANDROID_PERSISTENT_RAM
 	bool
 	depends on HAVE_MEMBLOCK
diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c
index e1e886c..267a8ec 100644
--- a/drivers/staging/android/logger.c
+++ b/drivers/staging/android/logger.c
@@ -29,6 +29,10 @@
 
 #include <asm/ioctls.h>
 
+#ifndef CONFIG_LOGCAT_SIZE
+#define CONFIG_LOGCAT_SIZE 256
+#endif
+
 /*
  * struct logger_log - represents a specific log, such as 'main' or 'radio'
  *
@@ -728,10 +732,10 @@
 	.size = SIZE, \
 };
 
-DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, 64*1024)
-DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, 64*1024)
-DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, 64*1024)
-DEFINE_LOGGER_DEVICE(log_system, LOGGER_LOG_SYSTEM, 64*1024)
+DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, CONFIG_LOGCAT_SIZE*1024)
+DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, CONFIG_LOGCAT_SIZE*1024)
+DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, CONFIG_LOGCAT_SIZE*1024)
+DEFINE_LOGGER_DEVICE(log_system, LOGGER_LOG_SYSTEM, CONFIG_LOGCAT_SIZE*1024)
 
 static struct logger_log *get_log_from_minor(int minor)
 {
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index 974cadc..8c3b291 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -37,7 +37,8 @@
 #define MAX_RAILS 5
 
 static struct msm_thermal_data msm_thermal_info;
-static uint32_t limited_max_freq = MSM_CPUFREQ_NO_LIMIT;
+static uint32_t limited_max_freq = UINT_MAX;
+static uint32_t limited_min_freq;
 static struct delayed_work check_temp_work;
 static bool core_control_enabled;
 static uint32_t cpus_offlined;
@@ -139,6 +140,25 @@
 
 #define PSM_REG_MODE_FROM_ATTRIBS(attr) \
 	(container_of(attr, struct psm_rail, mode_attr));
+
+static int  msm_thermal_cpufreq_callback(struct notifier_block *nfb,
+		unsigned long event, void *data)
+{
+	struct cpufreq_policy *policy = data;
+
+	switch (event) {
+	case CPUFREQ_INCOMPATIBLE:
+		cpufreq_verify_within_limits(policy, limited_min_freq,
+				limited_max_freq);
+		break;
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block msm_thermal_cpufreq_notifier = {
+	.notifier_call = msm_thermal_cpufreq_callback,
+};
+
 /* If freq table exists, then we can send freq request */
 static int check_freq_table(void)
 {
@@ -159,37 +179,26 @@
 {
 	int cpu = 0;
 	int ret = 0;
-	struct cpufreq_policy *policy = NULL;
 
 	if (!freq_table_get) {
 		ret = check_freq_table();
 		if (ret) {
-			pr_err("%s:Fail to get freq table\n", __func__);
+			pr_err("%s:Fail to get freq table\n", KBUILD_MODNAME);
 			return ret;
 		}
 	}
 	/* If min is larger than allowed max */
-	if (min != MSM_CPUFREQ_NO_LIMIT &&
-			min > table[limit_idx_high].frequency)
-		min = table[limit_idx_high].frequency;
+	min = min(min, table[limit_idx_high].frequency);
 
-	for_each_possible_cpu(cpu) {
-		ret = msm_cpufreq_set_freq_limits(cpu, min, limited_max_freq);
-		if (ret) {
-			pr_err("%s:Fail to set limits for cpu%d\n",
-					__func__, cpu);
-			return ret;
-		}
+	limited_min_freq = min;
 
-		if (cpu_online(cpu)) {
-			policy = cpufreq_cpu_get(cpu);
-			if (!policy)
-				continue;
-			cpufreq_driver_target(policy, policy->cur,
-					CPUFREQ_RELATION_L);
-			cpufreq_cpu_put(policy);
-		}
+	get_online_cpus();
+	for_each_online_cpu(cpu) {
+		if (cpufreq_update_policy(cpu))
+			pr_info("%s: Unable to update policy for cpu:%d\n",
+				KBUILD_MODNAME, cpu);
 	}
+	put_online_cpus();
 
 	return ret;
 }
@@ -584,26 +593,19 @@
 {
 	int ret = 0;
 
-	ret = msm_cpufreq_set_freq_limits(cpu, MSM_CPUFREQ_NO_LIMIT, max_freq);
-	if (ret)
-		return ret;
-
-	limited_max_freq = max_freq;
-	if (max_freq != MSM_CPUFREQ_NO_LIMIT)
+	if (max_freq != UINT_MAX)
 		pr_info("%s: Limiting cpu%d max frequency to %d\n",
 				KBUILD_MODNAME, cpu, max_freq);
 	else
 		pr_info("%s: Max frequency reset for cpu%d\n",
 				KBUILD_MODNAME, cpu);
-
-	if (cpu_online(cpu)) {
-		struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
-		if (!policy)
-			return ret;
-		ret = cpufreq_driver_target(policy, policy->cur,
-				CPUFREQ_RELATION_H);
-		cpufreq_cpu_put(policy);
+	get_online_cpus();
+	for_each_online_cpu(cpu) {
+		if (cpufreq_update_policy(cpu))
+			pr_info("%s: Unable to update policy for cpu:%d\n",
+				KBUILD_MODNAME, cpu);
 	}
+	put_online_cpus();
 
 	return ret;
 }
@@ -764,7 +766,6 @@
 
 static void __ref do_freq_control(long temp)
 {
-	int ret = 0;
 	int cpu = 0;
 	uint32_t max_freq = limited_max_freq;
 
@@ -784,7 +785,7 @@
 		limit_idx += msm_thermal_info.freq_step;
 		if (limit_idx >= limit_idx_high) {
 			limit_idx = limit_idx_high;
-			max_freq = MSM_CPUFREQ_NO_LIMIT;
+			max_freq = UINT_MAX;
 		} else
 			max_freq = table[limit_idx].frequency;
 	}
@@ -792,17 +793,13 @@
 	if (max_freq == limited_max_freq)
 		return;
 
+	limited_max_freq = max_freq;
 	/* Update new limits */
 	for_each_possible_cpu(cpu) {
 		if (!(msm_thermal_info.freq_control_mask & BIT(cpu)))
 			continue;
-		ret = update_cpu_max_freq(cpu, max_freq);
-		if (ret)
-			pr_debug(
-			"%s: Unable to limit cpu%d max freq to %d\n",
-					KBUILD_MODNAME, cpu, max_freq);
+		update_cpu_max_freq(cpu, max_freq);
 	}
-
 }
 
 static void __ref check_temp(struct work_struct *work)
@@ -909,12 +906,17 @@
 	cancel_delayed_work(&check_temp_work);
 	flush_scheduled_work();
 
-	if (limited_max_freq == MSM_CPUFREQ_NO_LIMIT)
+	if (limited_max_freq == UINT_MAX)
 		return;
 
-	for_each_possible_cpu(cpu) {
-		update_cpu_max_freq(cpu, MSM_CPUFREQ_NO_LIMIT);
+	limited_max_freq = UINT_MAX;
+	get_online_cpus();
+	for_each_online_cpu(cpu) {
+		if (cpufreq_update_policy(cpu))
+			pr_info("%s: Unable to update policy for cpu:%d\n",
+				KBUILD_MODNAME, cpu);
 	}
+	put_online_cpus();
 }
 
 static int __ref set_enabled(const char *val, const struct kernel_param *kp)
@@ -926,7 +928,7 @@
 		disable_msm_thermal();
 	else
 		pr_info("%s: no action for enabled = %d\n",
-				KBUILD_MODNAME, enabled);
+			KBUILD_MODNAME, enabled);
 
 	pr_info("%s: enabled = %d\n", KBUILD_MODNAME, enabled);
 
@@ -1190,6 +1192,11 @@
 		return -EINVAL;
 
 	enabled = 1;
+	ret = cpufreq_register_notifier(&msm_thermal_cpufreq_notifier,
+			CPUFREQ_POLICY_NOTIFIER);
+	if (ret)
+		pr_err("%s: cannot register cpufreq notifier\n",
+			KBUILD_MODNAME);
 	if (num_possible_cpus() > 1)
 		core_control_enabled = 1;
 	INIT_DELAYED_WORK(&check_temp_work, check_temp);
@@ -1505,7 +1512,7 @@
 		key = "qcom,freq-req";
 		rails[i].freq_req = of_property_read_bool(child_node, key);
 		if (rails[i].freq_req)
-			rails[i].min_level = MSM_CPUFREQ_NO_LIMIT;
+			rails[i].min_level = 0;
 		else {
 			key = "qcom,min-level";
 			ret = of_property_read_u32(child_node, key,
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index d1b911a..bccc504 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -626,6 +626,7 @@
 		struct usb_function *f)
 {
 	struct diag_context *ctxt = func_to_diag(f);
+	unsigned long flags;
 
 	if (gadget_is_superspeed(c->cdev->gadget))
 		usb_free_descriptors(f->ss_descriptors);
@@ -643,7 +644,9 @@
 		ctxt->ch->priv_usb = NULL;
 	list_del(&ctxt->list_item);
 	/* Free any pending USB requests from last session */
+	spin_lock_irqsave(&ctxt->lock, flags);
 	free_reqs(ctxt);
+	spin_unlock_irqrestore(&ctxt->lock, flags);
 	kfree(ctxt);
 }
 
diff --git a/include/linux/stk3x1x.h b/include/linux/stk3x1x.h
index 33625bd..d9d2cf6 100644
--- a/include/linux/stk3x1x.h
+++ b/include/linux/stk3x1x.h
@@ -23,6 +23,7 @@
 	uint16_t ps_thd_l;
 	int int_pin;
 	uint32_t transmittance;
+	uint32_t int_flags;
 };
 
 #endif /* __STK3X1X_H__ */
diff --git a/include/media/radio-iris.h b/include/media/radio-iris.h
index 419e055..d28a8c0 100644
--- a/include/media/radio-iris.h
+++ b/include/media/radio-iris.h
@@ -627,7 +627,9 @@
 	FM_TRANS,
 	FM_RESET,
 	FM_CALIB,
-	FM_TURNING_OFF
+	FM_TURNING_OFF,
+	FM_RECV_TURNING_ON,
+	FM_TRANS_TURNING_ON,
 };
 
 enum emphasis_type {
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 0be6f11..b1dd350 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -266,6 +266,12 @@
 quiet_cmd_dtc = DTC     $@
 cmd_dtc = $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 $(DTC_FLAGS) -d $(depfile) $<
 
+# cat
+# ---------------------------------------------------------------------------
+# Concatentate multiple files together
+quiet_cmd_cat = CAT     $@
+cmd_cat = (cat $(filter-out FORCE,$^) > $@) || (rm -f $@; false)
+
 # Bzip2
 # ---------------------------------------------------------------------------
 
diff --git a/sound/soc/codecs/msm8x10-wcd.c b/sound/soc/codecs/msm8x10-wcd.c
index 46b0a91..8844b21 100644
--- a/sound/soc/codecs/msm8x10-wcd.c
+++ b/sound/soc/codecs/msm8x10-wcd.c
@@ -1157,6 +1157,16 @@
 	"ZERO", "DEC1", "DEC2", "RX1", "RX2", "RX3"
 };
 
+/*
+  * There is only one bit to select RX2 (0) or RX3 (1) so add 'ZERO' won't
+  * cause any issue to select the right input, but it eliminates that lineout
+  * is powered-up when HPH is enabled if the 'ZERO" is used in the disable
+  * sequence for lineout.
+  */
+static const char * const rx_rdac4_text[] = {
+	"ZERO", "RX3", "RX2"
+};
+
 static const struct soc_enum rx_mix1_inp1_chain_enum =
 	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_RX1_B1_CTL, 0, 6, rx_mix1_text);
 
@@ -1194,6 +1204,10 @@
 	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_EQ1_B1_CTL, 0, 6,
 	iir1_inp1_text);
 
+static const struct soc_enum rx_rdac4_enum  =
+	SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_LO_DAC_CTL, 0, 3,
+	rx_rdac4_text);
+
 static const struct snd_kcontrol_new rx_mix1_inp1_mux =
 	SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum);
 
@@ -1221,6 +1235,9 @@
 static const struct snd_kcontrol_new rx2_mix2_inp1_mux =
 	SOC_DAPM_ENUM("RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum);
 
+static const struct snd_kcontrol_new rx_dac4_mux =
+	SOC_DAPM_ENUM("RDAC4 MUX Mux", rx_rdac4_enum);
+
 static int msm8x10_wcd_put_dec_enum(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
@@ -1312,6 +1329,10 @@
 	SOC_DAPM_SINGLE("Switch", MSM8X10_WCD_A_RX_HPH_L_DAC_CTL, 6, 1, 0)
 };
 
+static const struct snd_kcontrol_new spkr_switch[] = {
+	SOC_DAPM_SINGLE("Switch", MSM8X10_WCD_A_SPKR_DRV_DAC_CTL, 2, 1, 0)
+};
+
 static void msm8x10_wcd_codec_enable_adc_block(struct snd_soc_codec *codec,
 					 int enable)
 {
@@ -1791,13 +1812,6 @@
 	return 0;
 }
 
-static int msm8x10_wcd_spk_dac_event(struct snd_soc_dapm_widget *w,
-	struct snd_kcontrol *kcontrol, int event)
-{
-	dev_dbg(w->codec->dev, "%s %s %d\n", __func__, w->name, event);
-	return 0;
-}
-
 static const struct snd_soc_dapm_route audio_map[] = {
 	{"RX_I2S_CLK", NULL, "CDC_CONN"},
 	{"I2S RX1", NULL, "RX_I2S_CLK"},
@@ -1837,11 +1851,15 @@
 
 	{"LINEOUT PA", NULL, "CP"},
 	{"LINEOUT PA", NULL, "LINEOUT DAC"},
+	{"LINEOUT DAC", NULL, "RDAC4 MUX"},
+
+	{"RDAC4 MUX", "RX2", "RX2 CHAIN"},
+	{"RDAC4 MUX", "RX3", "RX3 CHAIN"},
 
 	{"CP", NULL, "CP_REGULATOR"},
 	{"CP", NULL, "RX_BIAS"},
 	{"SPK PA", NULL, "SPK DAC"},
-	{"SPK DAC", NULL, "RX3 CHAIN"},
+	{"SPK DAC", "Switch", "RX3 CHAIN"},
 
 	{"RX1 CHAIN", NULL, "RX1 CLK"},
 	{"RX2 CHAIN", NULL, "RX2 CLK"},
@@ -2270,6 +2288,9 @@
 		msm8x10_wcd_hphr_dac_event,
 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
+	SND_SOC_DAPM_MIXER("SPK DAC", SND_SOC_NOPM, 0, 0,
+		spkr_switch, ARRAY_SIZE(spkr_switch)),
+
 	/* Speaker */
 	SND_SOC_DAPM_OUTPUT("LINEOUT"),
 	SND_SOC_DAPM_OUTPUT("SPK_OUT"),
@@ -2289,10 +2310,6 @@
 		msm8x10_wcd_lineout_dac_event,
 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
-	SND_SOC_DAPM_DAC_E("SPK DAC", NULL, SND_SOC_NOPM, 0, 0,
-			   msm8x10_wcd_spk_dac_event,
-			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
 	SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
 	SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
 
@@ -2340,6 +2357,8 @@
 		&rx1_mix2_inp1_mux),
 	SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0,
 		&rx2_mix2_inp1_mux),
+	SND_SOC_DAPM_MUX("RDAC4 MUX", SND_SOC_NOPM, 0, 0,
+		&rx_dac4_mux),
 
 	SND_SOC_DAPM_SUPPLY("MICBIAS_REGULATOR", SND_SOC_NOPM,
 		ON_DEMAND_MICBIAS, 0,
@@ -2512,6 +2531,8 @@
 	/* config DMIC clk to CLK_MODE_1 (3.2Mhz@9.6Mhz mclk) */
 	{MSM8X10_WCD_A_CDC_CLK_DMIC_B1_CTL, 0xEE, 0x22},
 
+	/* Disable REF_EN for MSM8X10_WCD_A_SPKR_DRV_DAC_CTL */
+	{MSM8X10_WCD_A_SPKR_DRV_DAC_CTL, 0x04, 0x00},
 };
 
 static void msm8x10_wcd_codec_init_reg(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c
index ff190cd..af2c53e 100644
--- a/sound/soc/codecs/wcd9306.c
+++ b/sound/soc/codecs/wcd9306.c
@@ -4589,7 +4589,7 @@
 					   struct wcd9xxx_mbhc *mbhc)
 {
 	snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL,
-			    0x0C, 0x04);
+			    0x04, 0x04);
 	snd_soc_update_bits(codec, WCD9XXX_A_TX_7_MBHC_EN, 0xE0, 0xE0);
 }
 
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index f09e643..7820cd0 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -91,6 +91,22 @@
 #define WCD9XXX_MEAS_DELTA_MAX_MV 50
 #define WCD9XXX_MEAS_INVALD_RANGE_LOW_MV 20
 #define WCD9XXX_MEAS_INVALD_RANGE_HIGH_MV 80
+
+/*
+ * Invalid voltage range for the detection
+ * of plug type with current source
+ */
+#define WCD9XXX_CS_MEAS_INVALD_RANGE_LOW_MV 110
+#define WCD9XXX_CS_MEAS_INVALD_RANGE_HIGH_MV 265
+
+/*
+ * Threshold used to detect euro headset
+ * with current source
+ */
+#define WCD9XXX_CS_GM_SWAP_THRES_MIN_MV 10
+#define WCD9XXX_CS_GM_SWAP_THRES_MAX_MV 40
+
+#define WCD9XXX_MBHC_NSC_CS 9
 #define WCD9XXX_GM_SWAP_THRES_MIN_MV 150
 #define WCD9XXX_GM_SWAP_THRES_MAX_MV 650
 #define WCD9XXX_THRESHOLD_MIC_THRESHOLD 200
@@ -102,6 +118,11 @@
 
 #define WCD9XXX_IRQ_MBHC_JACK_SWITCH_DEFAULT 28
 
+#define WCD9XXX_V_CS_HS_MAX 500
+#define WCD9XXX_V_CS_NO_MIC 5
+#define WCD9XXX_MB_MEAS_DELTA_MAX_MV 80
+#define WCD9XXX_CS_MEAS_DELTA_MAX_MV 10
+
 static bool detect_use_vddio_switch = true;
 
 struct wcd9xxx_mbhc_detect {
@@ -111,6 +132,7 @@
 	bool swap_gnd;
 	bool vddio;
 	bool hwvalue;
+	bool mic_bias;
 	/* internal purpose from here */
 	bool _above_no_mic;
 	bool _below_v_hs_max;
@@ -970,7 +992,7 @@
 }
 
 static s32 __wcd9xxx_codec_sta_dce_v(struct wcd9xxx_mbhc *mbhc, s8 dce,
-				     u16 bias_value, s16 z)
+				     u16 bias_value, s16 z, u32 micb_mv)
 {
 	s16 value, mb;
 	s32 mv;
@@ -978,10 +1000,10 @@
 	value = bias_value;
 	if (dce) {
 		mb = (mbhc->mbhc_data.dce_mb);
-		mv = (value - z) * (s32)mbhc->mbhc_data.micb_mv / (mb - z);
+		mv = (value - z) * (s32)micb_mv / (mb - z);
 	} else {
 		mb = (mbhc->mbhc_data.sta_mb);
-		mv = (value - z) * (s32)mbhc->mbhc_data.micb_mv / (mb - z);
+		mv = (value - z) * (s32)micb_mv / (mb - z);
 	}
 
 	return mv;
@@ -992,11 +1014,13 @@
 {
 	s16 z;
 	z = dce ? (s16)mbhc->mbhc_data.dce_z : (s16)mbhc->mbhc_data.sta_z;
-	return __wcd9xxx_codec_sta_dce_v(mbhc, dce, bias_value, z);
+	return __wcd9xxx_codec_sta_dce_v(mbhc, dce, bias_value, z,
+					 mbhc->mbhc_data.micb_mv);
 }
 
 /* called only from interrupt which is under codec_resource_lock acquisition */
-static short wcd9xxx_mbhc_setup_hs_polling(struct wcd9xxx_mbhc *mbhc)
+static short wcd9xxx_mbhc_setup_hs_polling(struct wcd9xxx_mbhc *mbhc,
+					   bool is_cs_enable)
 {
 	struct snd_soc_codec *codec = mbhc->codec;
 	short bias_value;
@@ -1048,7 +1072,8 @@
 	snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x2, 0x2);
 	snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x8, 0x8);
 
-	wcd9xxx_calibrate_hs_polling(mbhc);
+	if (!is_cs_enable)
+		wcd9xxx_calibrate_hs_polling(mbhc);
 
 	/* don't flip override */
 	bias_value = __wcd9xxx_codec_sta_dce(mbhc, 1, true, true);
@@ -1144,6 +1169,158 @@
 	return status;
 }
 
+static enum wcd9xxx_mbhc_plug_type
+wcd9xxx_cs_find_plug_type(struct wcd9xxx_mbhc *mbhc,
+			  struct wcd9xxx_mbhc_detect *dt, const int size,
+			  bool highhph,
+			  unsigned long event_state)
+{
+	int i;
+	int vdce, mb_mv;
+	int ch, sz, delta_thr;
+	int minv = 0, maxv = INT_MIN;
+	struct wcd9xxx_mbhc_detect *d = dt;
+	struct wcd9xxx_mbhc_detect *dprev = d, *dmicbias = NULL, *dgnd = NULL;
+	enum wcd9xxx_mbhc_plug_type type = PLUG_TYPE_INVALID;
+
+	const struct wcd9xxx_mbhc_plug_type_cfg *plug_type =
+	    WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration);
+	s16 hs_max, no_mic, dce_z;
+
+	pr_debug("%s: enter\n", __func__);
+	pr_debug("%s: event_state 0x%lx\n", __func__, event_state);
+
+	sz = size - 1;
+	for (i = 0, d = dt, ch = 0; i < sz; i++, d++) {
+		if (d->mic_bias) {
+			dce_z = mbhc->mbhc_data.dce_z;
+			mb_mv = mbhc->mbhc_data.micb_mv;
+			hs_max = plug_type->v_hs_max;
+			no_mic = plug_type->v_no_mic;
+		} else {
+			dce_z = mbhc->mbhc_data.dce_nsc_cs_z;
+			mb_mv = VDDIO_MICBIAS_MV;
+			hs_max = WCD9XXX_V_CS_HS_MAX;
+			no_mic = WCD9XXX_V_CS_NO_MIC;
+		}
+
+		vdce = __wcd9xxx_codec_sta_dce_v(mbhc, true, d->dce,
+						 dce_z, (u32)mb_mv);
+
+		d->_vdces = vdce;
+		if (d->_vdces < no_mic)
+			d->_type = PLUG_TYPE_HEADPHONE;
+		else if (d->_vdces >= hs_max)
+			d->_type = PLUG_TYPE_HIGH_HPH;
+		else
+			d->_type = PLUG_TYPE_HEADSET;
+
+		pr_debug("%s: DCE #%d, %04x, V %04d(%04d), HPHL %d TYPE %d\n",
+			 __func__, i, d->dce, vdce, d->_vdces,
+			 d->hphl_status & 0x01,
+			 d->_type);
+
+		ch += d->hphl_status & 0x01;
+		if (!d->swap_gnd && !d->mic_bias) {
+			if (maxv < d->_vdces)
+				maxv = d->_vdces;
+			if (!minv || minv > d->_vdces)
+				minv = d->_vdces;
+		}
+		if ((!d->mic_bias &&
+		    (d->_vdces >= WCD9XXX_CS_MEAS_INVALD_RANGE_LOW_MV &&
+		     d->_vdces <= WCD9XXX_CS_MEAS_INVALD_RANGE_HIGH_MV)) ||
+		    (d->mic_bias &&
+		    (d->_vdces >= WCD9XXX_MEAS_INVALD_RANGE_LOW_MV &&
+		     d->_vdces <= WCD9XXX_MEAS_INVALD_RANGE_HIGH_MV))) {
+			pr_debug("%s: within invalid range\n", __func__);
+			type = PLUG_TYPE_INVALID;
+			goto exit;
+		}
+	}
+
+	if (event_state & (1 << MBHC_EVENT_PA_HPHL)) {
+		pr_debug("%s: HPHL PA was ON\n", __func__);
+	} else if (ch != sz && ch > 0) {
+		pr_debug("%s: Invalid, inconsistent HPHL\n", __func__);
+		type = PLUG_TYPE_INVALID;
+		goto exit;
+	}
+
+	delta_thr = highhph ? WCD9XXX_MB_MEAS_DELTA_MAX_MV :
+			      WCD9XXX_CS_MEAS_DELTA_MAX_MV;
+
+	for (i = 0, d = dt; i < sz; i++, d++) {
+		if ((i > 0) && !d->mic_bias && !d->swap_gnd &&
+		    (d->_type != dprev->_type)) {
+			pr_debug("%s: Invalid, inconsistent types\n", __func__);
+			type = PLUG_TYPE_INVALID;
+			goto exit;
+		}
+
+		if (!d->swap_gnd && !d->mic_bias &&
+		    (abs(minv - d->_vdces) > delta_thr ||
+		     abs(maxv - d->_vdces) > delta_thr)) {
+			pr_debug("%s: Invalid, delta %dmv, %dmv and %dmv\n",
+				 __func__, d->_vdces, minv, maxv);
+			type = PLUG_TYPE_INVALID;
+			goto exit;
+		} else if (d->swap_gnd) {
+			dgnd = d;
+		}
+
+		if (!d->mic_bias && !d->swap_gnd)
+			dprev = d;
+		else if (d->mic_bias)
+			dmicbias = d;
+	}
+	if (dgnd && dt->_type != PLUG_TYPE_HEADSET &&
+	    dt->_type != dgnd->_type) {
+		pr_debug("%s: Invalid, inconsistent types\n", __func__);
+		type = PLUG_TYPE_INVALID;
+		goto exit;
+	}
+
+	type = dt->_type;
+	if (dmicbias) {
+		if (dmicbias->_type == PLUG_TYPE_HEADSET &&
+		    (dt->_type == PLUG_TYPE_HIGH_HPH ||
+		     dt->_type == PLUG_TYPE_HEADSET)) {
+			type = PLUG_TYPE_HEADSET;
+			if (dt->_type == PLUG_TYPE_HIGH_HPH) {
+				pr_debug("%s: Headset with threshold on MIC detected\n",
+					 __func__);
+				if (mbhc->mbhc_cfg->micbias_enable_flags &
+				 (1 << MBHC_MICBIAS_ENABLE_THRESHOLD_HEADSET))
+					mbhc->micbias_enable = true;
+			}
+		}
+	}
+
+	if (!(event_state & (1UL << MBHC_EVENT_PA_HPHL))) {
+		if (((type == PLUG_TYPE_HEADSET ||
+		      type == PLUG_TYPE_HEADPHONE) && ch != sz)) {
+			pr_debug("%s: Invalid, not fully inserted, TYPE %d\n",
+				 __func__, type);
+			type = PLUG_TYPE_INVALID;
+		}
+	}
+	if (type == PLUG_TYPE_HEADSET && dgnd && !dgnd->mic_bias) {
+		if ((dgnd->_vdces + WCD9XXX_CS_GM_SWAP_THRES_MIN_MV <
+		     minv) &&
+		    (dgnd->_vdces + WCD9XXX_CS_GM_SWAP_THRES_MAX_MV >
+		     maxv))
+			type = PLUG_TYPE_GND_MIC_SWAP;
+		else if (dgnd->_type != PLUG_TYPE_HEADSET) {
+			pr_debug("%s: Invalid, inconsistent types\n", __func__);
+			type = PLUG_TYPE_INVALID;
+		}
+	}
+exit:
+	pr_debug("%s: Plug type %d detected\n", __func__, type);
+	return type;
+}
+
 /*
  * wcd9xxx_find_plug_type : Find out and return the best plug type with given
  *			    list of wcd9xxx_mbhc_detect structure.
@@ -1329,6 +1506,112 @@
 	return 0;
 }
 
+void wcd9xxx_turn_onoff_current_source(struct wcd9xxx_mbhc *mbhc, bool on,
+				       bool highhph)
+{
+
+	struct snd_soc_codec *codec;
+	struct wcd9xxx_mbhc_btn_detect_cfg *btn_det;
+	const struct wcd9xxx_mbhc_plug_detect_cfg *plug_det =
+	    WCD9XXX_MBHC_CAL_PLUG_DET_PTR(mbhc->mbhc_cfg->calibration);
+
+	btn_det = WCD9XXX_MBHC_CAL_BTN_DET_PTR(mbhc->mbhc_cfg->calibration);
+	codec = mbhc->codec;
+
+	if (on) {
+		pr_debug("%s: enabling current source\n", __func__);
+		/* Nsc to 9 */
+		snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL,
+				    0x78, 0x48);
+		/* pull down diode bit to 0 */
+		snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg,
+				    0x01, 0x00);
+		/*
+		 * Keep the low power insertion/removal
+		 * detection (reg 0x3DD) disabled
+		 */
+		snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_INT_CTL,
+				    0x01, 0x00);
+		/*
+		 * Enable the Mic Bias current source
+		 * Write bits[6:5] of register MICB_2_MBHC to 0x3 (V_20_UA)
+		 * Write bit[7] of register MICB_2_MBHC to 1
+		 * (INS_DET_ISRC_EN__ENABLE)
+		 * MICB_2_MBHC__SCHT_TRIG_EN to 1
+		 */
+		snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg,
+				    0xF0, 0xF0);
+		/* Disconnect MBHC Override from MicBias and LDOH */
+		snd_soc_update_bits(codec, WCD9XXX_A_MAD_ANA_CTRL, 0x10, 0x00);
+	} else {
+		pr_debug("%s: disabling current source\n", __func__);
+		/* Connect MBHC Override from MicBias and LDOH */
+		snd_soc_update_bits(codec, WCD9XXX_A_MAD_ANA_CTRL, 0x10, 0x10);
+		/* INS_DET_ISRC_CTL to acdb value */
+		snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg,
+				    0x60, plug_det->mic_current << 5);
+		if (!highhph) {
+			/* INS_DET_ISRC_EN__ENABLE to 0 */
+			snd_soc_update_bits(codec,
+					    mbhc->mbhc_bias_regs.mbhc_reg,
+					    0x80, 0x00);
+			/* MICB_2_MBHC__SCHT_TRIG_EN  to 0 */
+			snd_soc_update_bits(codec,
+					    mbhc->mbhc_bias_regs.mbhc_reg,
+					    0x10, 0x00);
+		}
+		/* Nsc to acdb value */
+		snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x78,
+				    btn_det->mbhc_nsc << 3);
+	}
+}
+
+static enum wcd9xxx_mbhc_plug_type
+wcd9xxx_codec_cs_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph)
+{
+	struct snd_soc_codec *codec = mbhc->codec;
+	struct wcd9xxx_mbhc_detect rt[NUM_DCE_PLUG_INS_DETECT];
+	enum wcd9xxx_mbhc_plug_type type = PLUG_TYPE_INVALID;
+	int i;
+
+	pr_debug("%s: enter\n", __func__);
+	WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
+
+	BUG_ON(NUM_DCE_PLUG_INS_DETECT < 4);
+
+	rt[0].swap_gnd = false;
+	rt[0].vddio = false;
+	rt[0].hwvalue = true;
+	rt[0].hphl_status = wcd9xxx_hphl_status(mbhc);
+	rt[0].dce = wcd9xxx_mbhc_setup_hs_polling(mbhc, true);
+	rt[0].mic_bias = false;
+
+	for (i = 1; i < NUM_DCE_PLUG_INS_DETECT - 1; i++) {
+		rt[i].swap_gnd = (i == NUM_DCE_PLUG_INS_DETECT - 3);
+		rt[i].mic_bias = ((i == NUM_DCE_PLUG_INS_DETECT - 4) &&
+				   highhph);
+		rt[i].hphl_status = wcd9xxx_hphl_status(mbhc);
+		if (rt[i].swap_gnd)
+			wcd9xxx_codec_hphr_gnd_switch(codec, true);
+
+		if (rt[i].mic_bias)
+			wcd9xxx_turn_onoff_current_source(mbhc, false, false);
+
+		rt[i].dce = __wcd9xxx_codec_sta_dce(mbhc, 1, !highhph, true);
+		if (rt[i].mic_bias)
+			wcd9xxx_turn_onoff_current_source(mbhc, true, false);
+		if (rt[i].swap_gnd)
+			wcd9xxx_codec_hphr_gnd_switch(codec, false);
+	}
+
+	type = wcd9xxx_cs_find_plug_type(mbhc, rt, ARRAY_SIZE(rt), highhph,
+					 mbhc->event_state);
+
+	pr_debug("%s: plug_type:%d\n", __func__, type);
+
+	return type;
+}
+
 static enum wcd9xxx_mbhc_plug_type
 wcd9xxx_codec_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph)
 {
@@ -1365,7 +1648,7 @@
 	(void) wcd9xxx_pull_down_micbias(mbhc,
 					 WCD9XXX_MICBIAS_PULLDOWN_SETTLE_US);
 	rt[0].hphl_status = wcd9xxx_hphl_status(mbhc);
-	rt[0].dce = wcd9xxx_mbhc_setup_hs_polling(mbhc);
+	rt[0].dce = wcd9xxx_mbhc_setup_hs_polling(mbhc, false);
 	rt[0].swap_gnd = false;
 	rt[0].vddio = false;
 	rt[0].hwvalue = true;
@@ -1635,14 +1918,23 @@
 {
 	enum wcd9xxx_mbhc_plug_type plug_type;
 	struct snd_soc_codec *codec = mbhc->codec;
+	bool current_source_enable;
 
 	pr_debug("%s: enter\n", __func__);
 
 	WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
+	current_source_enable = ((mbhc->mbhc_cfg->cs_enable_flags &
+				  (1 << MBHC_CS_ENABLE_INSERTION)) != 0);
 
-	wcd9xxx_turn_onoff_override(codec, true);
-	plug_type = wcd9xxx_codec_get_plug_type(mbhc, true);
-	wcd9xxx_turn_onoff_override(codec, false);
+	if (current_source_enable) {
+		wcd9xxx_turn_onoff_current_source(mbhc, true, false);
+		plug_type = wcd9xxx_codec_cs_get_plug_type(mbhc, false);
+		wcd9xxx_turn_onoff_current_source(mbhc, false, false);
+	} else {
+		wcd9xxx_turn_onoff_override(codec, true);
+		plug_type = wcd9xxx_codec_get_plug_type(mbhc, true);
+		wcd9xxx_turn_onoff_override(codec, false);
+	}
 
 	if (wcd9xxx_swch_level_remove(mbhc)) {
 		pr_debug("%s: Switch level is low when determining plug\n",
@@ -1672,26 +1964,9 @@
 /* called under codec_resource_lock acquisition */
 static void wcd9xxx_mbhc_detect_plug_type(struct wcd9xxx_mbhc *mbhc)
 {
-	struct snd_soc_codec *codec = mbhc->codec;
-	const struct wcd9xxx_mbhc_plug_detect_cfg *plug_det =
-		WCD9XXX_MBHC_CAL_PLUG_DET_PTR(mbhc->mbhc_cfg->calibration);
-
 	pr_debug("%s: enter\n", __func__);
 	WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
 
-	/*
-	 * Turn on the override,
-	 * wcd9xxx_mbhc_setup_hs_polling requires override on
-	 */
-	wcd9xxx_turn_onoff_override(codec, true);
-	if (plug_det->t_ins_complete > 20)
-		msleep(plug_det->t_ins_complete);
-	else
-		usleep_range(plug_det->t_ins_complete * 1000,
-			     plug_det->t_ins_complete * 1000);
-	/* Turn off the override */
-	wcd9xxx_turn_onoff_override(codec, false);
-
 	if (wcd9xxx_swch_level_remove(mbhc))
 		pr_debug("%s: Switch level low when determining plug\n",
 			 __func__);
@@ -1740,14 +2015,21 @@
 	}
 }
 
-static bool is_valid_mic_voltage(struct wcd9xxx_mbhc *mbhc, s32 mic_mv)
+static bool is_valid_mic_voltage(struct wcd9xxx_mbhc *mbhc, s32 mic_mv,
+				 bool cs_enable)
 {
 	const struct wcd9xxx_mbhc_plug_type_cfg *plug_type =
 	    WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration);
 	const s16 v_hs_max = wcd9xxx_get_current_v_hs_max(mbhc);
 
-	return (!(mic_mv > 10 && mic_mv < 80) && (mic_mv > plug_type->v_no_mic)
-		&& (mic_mv < v_hs_max)) ? true : false;
+	if (cs_enable)
+		return ((mic_mv > WCD9XXX_V_CS_NO_MIC) &&
+			 (mic_mv < WCD9XXX_V_CS_HS_MAX)) ? true : false;
+	else
+		return (!(mic_mv > WCD9XXX_MEAS_INVALD_RANGE_LOW_MV &&
+			  mic_mv < WCD9XXX_MEAS_INVALD_RANGE_HIGH_MV) &&
+			(mic_mv > plug_type->v_no_mic) &&
+			(mic_mv < v_hs_max)) ? true : false;
 }
 
 /*
@@ -1762,6 +2044,13 @@
 	s32 mic_mv[NUM_DCE_PLUG_DETECT];
 	short mb_v[NUM_DCE_PLUG_DETECT];
 	unsigned long retry = 0, timeout;
+	bool cs_enable;
+
+	cs_enable = ((mbhc->mbhc_cfg->cs_enable_flags &
+		      (1 << MBHC_CS_ENABLE_REMOVAL)) != 0);
+
+	if (cs_enable)
+		wcd9xxx_turn_onoff_current_source(mbhc, true, false);
 
 	timeout = jiffies + msecs_to_jiffies(HS_DETECT_PLUG_TIME_MS);
 	while (!(timedout = time_after(jiffies, timeout))) {
@@ -1781,11 +2070,28 @@
 			break;
 		}
 
-		for (i = 0; i < NUM_DCE_PLUG_DETECT; i++) {
-			mb_v[i] = wcd9xxx_codec_sta_dce(mbhc, 1,  true);
-			mic_mv[i] = wcd9xxx_codec_sta_dce_v(mbhc, 1 , mb_v[i]);
-			pr_debug("%s : DCE run %lu, mic_mv = %d(%x)\n",
-				 __func__, retry, mic_mv[i], mb_v[i]);
+		if (cs_enable) {
+			for (i = 0; i < NUM_DCE_PLUG_DETECT; i++) {
+				mb_v[i] = __wcd9xxx_codec_sta_dce(mbhc, 1,
+								  true, true);
+				mic_mv[i] = __wcd9xxx_codec_sta_dce_v(mbhc,
+								      true,
+								      mb_v[i],
+						mbhc->mbhc_data.dce_nsc_cs_z,
+						(u32)VDDIO_MICBIAS_MV);
+				pr_debug("%s : DCE run %lu, mic_mv = %d(%x)\n",
+					 __func__, retry, mic_mv[i], mb_v[i]);
+			}
+		} else {
+			for (i = 0; i < NUM_DCE_PLUG_DETECT; i++) {
+				mb_v[i] = wcd9xxx_codec_sta_dce(mbhc, 1,
+								true);
+				mic_mv[i] = wcd9xxx_codec_sta_dce_v(mbhc, 1,
+								mb_v[i]);
+				pr_debug("%s : DCE run %lu, mic_mv = %d(%x)\n",
+					 __func__, retry, mic_mv[i],
+								mb_v[i]);
+			}
 		}
 
 		if (wcd9xxx_swch_level_remove(mbhc)) {
@@ -1800,7 +2106,7 @@
 		}
 
 		for (i = 0; i < NUM_DCE_PLUG_DETECT; i++)
-			if (!is_valid_mic_voltage(mbhc, mic_mv[i]))
+			if (!is_valid_mic_voltage(mbhc, mic_mv[i], cs_enable))
 				break;
 
 		if (i == NUM_DCE_PLUG_DETECT) {
@@ -1811,6 +2117,9 @@
 		}
 	}
 
+	if (cs_enable)
+		wcd9xxx_turn_onoff_current_source(mbhc, false, false);
+
 	if (timedout)
 		pr_debug("%s: Microphone did not settle in %d seconds\n",
 			 __func__, HS_DETECT_PLUG_TIME_MS);
@@ -1829,12 +2138,15 @@
 /* called only from interrupt which is under codec_resource_lock acquisition */
 static void wcd9xxx_hs_remove_irq_noswch(struct wcd9xxx_mbhc *mbhc)
 {
-	s16 dce;
+	s16 dce, dcez;
 	unsigned long timeout;
 	bool removed = true;
 	struct snd_soc_codec *codec = mbhc->codec;
 	const struct wcd9xxx_mbhc_general_cfg *generic =
 		WCD9XXX_MBHC_CAL_GENERAL_PTR(mbhc->mbhc_cfg->calibration);
+	bool cs_enable;
+	s16 cur_v_ins_h;
+	u32 mb_mv;
 
 	pr_debug("%s: enter\n", __func__);
 	if (mbhc->current_plug != PLUG_TYPE_HEADSET) {
@@ -1848,13 +2160,32 @@
 	usleep_range(generic->t_shutdown_plug_rem,
 		     generic->t_shutdown_plug_rem);
 
+	cs_enable = ((mbhc->mbhc_cfg->cs_enable_flags &
+		      (1 << MBHC_CS_ENABLE_REMOVAL)) != 0);
+	if (cs_enable)
+		wcd9xxx_turn_onoff_current_source(mbhc, true, false);
+
 	timeout = jiffies + msecs_to_jiffies(FAKE_REMOVAL_MIN_PERIOD_MS);
 	do {
-		dce = wcd9xxx_codec_sta_dce(mbhc, 1,  true);
+		if (cs_enable) {
+			dce = __wcd9xxx_codec_sta_dce(mbhc, 1,  true, true);
+			dcez = mbhc->mbhc_data.dce_nsc_cs_z;
+			mb_mv = VDDIO_MICBIAS_MV;
+		} else {
+			dce = wcd9xxx_codec_sta_dce(mbhc, 1,  true);
+			dcez = mbhc->mbhc_data.dce_z;
+			mb_mv = mbhc->mbhc_data.micb_mv;
+		}
+
 		pr_debug("%s: DCE 0x%x,%d\n", __func__, dce,
-			 wcd9xxx_codec_sta_dce_v(mbhc, 1, dce));
-		if (dce <
-		    wcd9xxx_get_current_v(mbhc, WCD9XXX_CURRENT_V_INS_H)) {
+			  __wcd9xxx_codec_sta_dce_v(mbhc, true, dce,
+						    dcez, mb_mv));
+
+		cur_v_ins_h = cs_enable ? (s16) mbhc->mbhc_data.v_cs_ins_h :
+					  (wcd9xxx_get_current_v(mbhc,
+					   WCD9XXX_CURRENT_V_INS_H));
+
+		if (dce < cur_v_ins_h) {
 			removed = false;
 			break;
 		}
@@ -1862,6 +2193,9 @@
 	pr_debug("%s: headset %sactually removed\n", __func__,
 		  removed ? "" : "not ");
 
+	if (cs_enable)
+		wcd9xxx_turn_onoff_current_source(mbhc, false, false);
+
 	if (removed) {
 		if (mbhc->mbhc_cfg->detect_extn_cable) {
 			if (!wcd9xxx_swch_level_remove(mbhc)) {
@@ -2070,22 +2404,29 @@
 }
 
 static u16 wcd9xxx_codec_v_sta_dce(struct wcd9xxx_mbhc *mbhc,
-				   enum meas_type dce, s16 vin_mv)
+				   enum meas_type dce, s16 vin_mv,
+				   bool cs_enable)
 {
 	s16 diff, zero;
 	u32 mb_mv, in;
 	u16 value;
+	s16 dce_z;
 
 	mb_mv = mbhc->mbhc_data.micb_mv;
+	dce_z = mbhc->mbhc_data.dce_z;
 
 	if (mb_mv == 0) {
 		pr_err("%s: Mic Bias voltage is set to zero\n", __func__);
 		return -EINVAL;
 	}
+	if (cs_enable) {
+		mb_mv = VDDIO_MICBIAS_MV;
+		dce_z = mbhc->mbhc_data.dce_nsc_cs_z;
+	}
 
 	if (dce) {
-		diff = (mbhc->mbhc_data.dce_mb) - (mbhc->mbhc_data.dce_z);
-		zero = (mbhc->mbhc_data.dce_z);
+		diff = (mbhc->mbhc_data.dce_mb) - (dce_z);
+		zero = (dce_z);
 	} else {
 		diff = (mbhc->mbhc_data.sta_mb) - (mbhc->mbhc_data.sta_z);
 		zero = (mbhc->mbhc_data.sta_z);
@@ -2112,9 +2453,9 @@
 	plug_type = WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration);
 
 	mbhc->mbhc_data.v_ins_hu[MBHC_V_IDX_CFILT] =
-	    wcd9xxx_codec_v_sta_dce(mbhc, STA, plug_type->v_hs_max);
+	    wcd9xxx_codec_v_sta_dce(mbhc, STA, plug_type->v_hs_max, false);
 	mbhc->mbhc_data.v_ins_h[MBHC_V_IDX_CFILT] =
-	    wcd9xxx_codec_v_sta_dce(mbhc, DCE, plug_type->v_hs_max);
+	    wcd9xxx_codec_v_sta_dce(mbhc, DCE, plug_type->v_hs_max, false);
 
 	mbhc->mbhc_data.v_inval_ins_low = FAKE_INS_LOW;
 	mbhc->mbhc_data.v_inval_ins_high = FAKE_INS_HIGH;
@@ -2123,9 +2464,9 @@
 		adj_v_hs_max = scale_v_micb_vddio(mbhc, plug_type->v_hs_max,
 						  true);
 		mbhc->mbhc_data.v_ins_hu[MBHC_V_IDX_VDDIO] =
-		    wcd9xxx_codec_v_sta_dce(mbhc, STA, adj_v_hs_max);
+		    wcd9xxx_codec_v_sta_dce(mbhc, STA, adj_v_hs_max, false);
 		mbhc->mbhc_data.v_ins_h[MBHC_V_IDX_VDDIO] =
-		    wcd9xxx_codec_v_sta_dce(mbhc, DCE, adj_v_hs_max);
+		    wcd9xxx_codec_v_sta_dce(mbhc, DCE, adj_v_hs_max, false);
 		mbhc->mbhc_data.v_inval_ins_low =
 		    scale_v_micb_vddio(mbhc, mbhc->mbhc_data.v_inval_ins_low,
 				       false);
@@ -2133,6 +2474,11 @@
 		    scale_v_micb_vddio(mbhc, mbhc->mbhc_data.v_inval_ins_high,
 				       false);
 	}
+	mbhc->mbhc_data.v_cs_ins_h = wcd9xxx_codec_v_sta_dce(mbhc, DCE,
+							WCD9XXX_V_CS_HS_MAX,
+							true);
+	pr_debug("%s: v_ins_h for current source: 0x%x\n", __func__,
+		  mbhc->mbhc_data.v_cs_ins_h);
 
 	btn_high = wcd9xxx_mbhc_cal_btn_det_mp(btn_det,
 					       MBHC_BTN_DET_V_BTN_HIGH);
@@ -2147,13 +2493,17 @@
 	    scale_v_micb_vddio(mbhc, btn_mv_dce[MBHC_V_IDX_CFILT], true);
 
 	mbhc->mbhc_data.v_b1_hu[MBHC_V_IDX_CFILT] =
-	    wcd9xxx_codec_v_sta_dce(mbhc, STA, btn_mv_sta[MBHC_V_IDX_CFILT]);
+	    wcd9xxx_codec_v_sta_dce(mbhc, STA, btn_mv_sta[MBHC_V_IDX_CFILT],
+				    false);
 	mbhc->mbhc_data.v_b1_h[MBHC_V_IDX_CFILT] =
-	    wcd9xxx_codec_v_sta_dce(mbhc, DCE, btn_mv_dce[MBHC_V_IDX_CFILT]);
+	    wcd9xxx_codec_v_sta_dce(mbhc, DCE, btn_mv_dce[MBHC_V_IDX_CFILT],
+				    false);
 	mbhc->mbhc_data.v_b1_hu[MBHC_V_IDX_VDDIO] =
-	    wcd9xxx_codec_v_sta_dce(mbhc, STA, btn_mv_sta[MBHC_V_IDX_VDDIO]);
+	    wcd9xxx_codec_v_sta_dce(mbhc, STA, btn_mv_sta[MBHC_V_IDX_VDDIO],
+				    false);
 	mbhc->mbhc_data.v_b1_h[MBHC_V_IDX_VDDIO] =
-	    wcd9xxx_codec_v_sta_dce(mbhc, DCE, btn_mv_dce[MBHC_V_IDX_VDDIO]);
+	    wcd9xxx_codec_v_sta_dce(mbhc, DCE, btn_mv_dce[MBHC_V_IDX_VDDIO],
+				    false);
 
 	mbhc->mbhc_data.v_brh[MBHC_V_IDX_CFILT] =
 	    mbhc->mbhc_data.v_b1_h[MBHC_V_IDX_CFILT];
@@ -2163,7 +2513,7 @@
 	mbhc->mbhc_data.v_brl = BUTTON_MIN;
 
 	mbhc->mbhc_data.v_no_mic =
-	    wcd9xxx_codec_v_sta_dce(mbhc, STA, plug_type->v_no_mic);
+	    wcd9xxx_codec_v_sta_dce(mbhc, STA, plug_type->v_no_mic, false);
 	pr_debug("%s: leave\n", __func__);
 }
 
@@ -2177,6 +2527,16 @@
 	 mbhc->mbhc_cfg->mclk_cb_fn(mbhc->codec, on, false);
 }
 
+/*
+ * Mic Bias Enable Decision
+ * Return true if high_hph_cnt is a power of 2 (!= 2)
+ * otherwise return false
+ */
+static bool wcd9xxx_mbhc_enable_mb_decision(int high_hph_cnt)
+{
+	return (high_hph_cnt > 2) && !(high_hph_cnt & (high_hph_cnt - 1));
+}
+
 static void wcd9xxx_correct_swch_plug(struct work_struct *work)
 {
 	struct wcd9xxx_mbhc *mbhc;
@@ -2184,13 +2544,17 @@
 	enum wcd9xxx_mbhc_plug_type plug_type = PLUG_TYPE_INVALID;
 	unsigned long timeout;
 	int retry = 0, pt_gnd_mic_swap_cnt = 0;
+	int highhph_cnt = 0;
 	bool correction = false;
-	bool wrk_complete = true;
+	bool current_source_enable;
+	bool wrk_complete = true, highhph = false;
 
 	pr_debug("%s: enter\n", __func__);
 
 	mbhc = container_of(work, struct wcd9xxx_mbhc, correct_plug_swch);
 	codec = mbhc->codec;
+	current_source_enable = ((mbhc->mbhc_cfg->cs_enable_flags &
+				  (1 << MBHC_CS_ENABLE_POLLING)) != 0);
 
 	wcd9xxx_onoff_ext_mclk(mbhc, true);
 
@@ -2204,7 +2568,11 @@
 	 * DAPM doesn't use any MBHC block as this work only runs with
 	 * headphone detection.
 	 */
-	wcd9xxx_turn_onoff_override(codec, true);
+	if (current_source_enable)
+		wcd9xxx_turn_onoff_current_source(mbhc, true,
+						  false);
+	else
+		wcd9xxx_turn_onoff_override(codec, true);
 
 	timeout = jiffies + msecs_to_jiffies(HS_DETECT_PLUG_TIME_MS);
 	while (!time_after(jiffies, timeout)) {
@@ -2225,11 +2593,20 @@
 
 		/* can race with removal interrupt */
 		WCD9XXX_BCL_LOCK(mbhc->resmgr);
-		plug_type = wcd9xxx_codec_get_plug_type(mbhc, true);
+		if (current_source_enable)
+			plug_type = wcd9xxx_codec_cs_get_plug_type(mbhc,
+								   highhph);
+		else
+			plug_type = wcd9xxx_codec_get_plug_type(mbhc, true);
 		WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
 
 		pr_debug("%s: attempt(%d) current_plug(%d) new_plug(%d)\n",
 			 __func__, retry, mbhc->current_plug, plug_type);
+
+		highhph_cnt = (plug_type == PLUG_TYPE_HIGH_HPH) ?
+					(highhph_cnt + 1) :
+					0;
+		highhph = wcd9xxx_mbhc_enable_mb_decision(highhph_cnt);
 		if (plug_type == PLUG_TYPE_INVALID) {
 			pr_debug("Invalid plug in attempt # %d\n", retry);
 			if (!mbhc->mbhc_cfg->detect_extn_cable &&
@@ -2275,8 +2652,12 @@
 				pt_gnd_mic_swap_cnt = 0;
 
 			WCD9XXX_BCL_LOCK(mbhc->resmgr);
-			/* Turn off override */
-			wcd9xxx_turn_onoff_override(codec, false);
+			/* Turn off override/current source */
+			if (current_source_enable)
+				wcd9xxx_turn_onoff_current_source(mbhc, false,
+								  false);
+			else
+				wcd9xxx_turn_onoff_override(codec, false);
 			/*
 			 * The valid plug also includes PLUG_TYPE_GND_MIC_SWAP
 			 */
@@ -2289,15 +2670,19 @@
 		}
 	}
 
-	if (plug_type == PLUG_TYPE_HIGH_HPH) {
+	highhph = false;
+	if (wrk_complete && plug_type == PLUG_TYPE_HIGH_HPH) {
 		pr_debug("%s: polling is done, still HPH, so enabling MIC trigger\n",
 			 __func__);
 		WCD9XXX_BCL_LOCK(mbhc->resmgr);
 		wcd9xxx_find_plug_and_report(mbhc, plug_type);
+		highhph = true;
 		WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
 	}
-	/* Turn off override */
-	if (!correction)
+
+	if (!correction && current_source_enable)
+		wcd9xxx_turn_onoff_current_source(mbhc, false, highhph);
+	else if (!correction)
 		wcd9xxx_turn_onoff_override(codec, false);
 
 	wcd9xxx_onoff_ext_mclk(mbhc, false);
@@ -2566,11 +2951,11 @@
 	pr_debug("%s: reprogram vb1hu/vbrh to %dmv\n", __func__, mv);
 
 	/* update LSB first so mbhc hardware block doesn't see too low value */
-	v_b1_hu = wcd9xxx_codec_v_sta_dce(mbhc, STA, mv);
+	v_b1_hu = wcd9xxx_codec_v_sta_dce(mbhc, STA, mv, false);
 	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL, v_b1_hu & 0xFF);
 	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
 		      (v_b1_hu >> 8) & 0xFF);
-	v_brh = wcd9xxx_codec_v_sta_dce(mbhc, DCE, mv);
+	v_brh = wcd9xxx_codec_v_sta_dce(mbhc, DCE, mv, false);
 	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL, v_brh & 0xFF);
 	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
 		      (v_brh >> 8) & 0xFF);
@@ -2642,14 +3027,15 @@
 			pr_debug("%s: Button is released without resume",
 				 __func__);
 			wcd9xxx_get_z(mbhc, &dce_z, &sta_z);
-			stamv = __wcd9xxx_codec_sta_dce_v(mbhc, 0, sta, sta_z);
+			stamv = __wcd9xxx_codec_sta_dce_v(mbhc, 0, sta, sta_z,
+						mbhc->mbhc_data.micb_mv);
 			if (vddio)
 				stamv_s = scale_v_micb_vddio(mbhc, stamv,
 							     false);
 			else
 				stamv_s = stamv;
 			mv[0] = __wcd9xxx_codec_sta_dce_v(mbhc, 1, dce[0],
-							  dce_z);
+					  dce_z, mbhc->mbhc_data.micb_mv);
 			mv_s[0] = vddio ? scale_v_micb_vddio(mbhc, mv[0],
 							     false) : mv[0];
 			btn = wcd9xxx_determine_button(mbhc, mv_s[0]);
@@ -2665,7 +3051,8 @@
 
 	wcd9xxx_get_z(mbhc, &dce_z, &sta_z);
 
-	stamv = __wcd9xxx_codec_sta_dce_v(mbhc, 0, sta, sta_z);
+	stamv = __wcd9xxx_codec_sta_dce_v(mbhc, 0, sta, sta_z,
+					  mbhc->mbhc_data.micb_mv);
 	if (vddio)
 		stamv_s = scale_v_micb_vddio(mbhc, stamv, false);
 	else
@@ -2674,7 +3061,8 @@
 		 sta & 0xFFFF, stamv, stamv_s);
 
 	/* determine pressed button */
-	mv[0] = __wcd9xxx_codec_sta_dce_v(mbhc, 1, dce[0], dce_z);
+	mv[0] = __wcd9xxx_codec_sta_dce_v(mbhc, 1, dce[0], dce_z,
+					  mbhc->mbhc_data.micb_mv);
 	mv_s[0] = vddio ? scale_v_micb_vddio(mbhc, mv[0], false) : mv[0];
 	btnmeas[0] = wcd9xxx_determine_button(mbhc, mv_s[0]);
 	pr_debug("%s: Meas HW - DCE 0x%x,%d,%d button %d\n", __func__,
@@ -2683,7 +3071,8 @@
 		btn = btnmeas[0];
 	for (meas = 1; (n_btn_meas && d->n_btn_meas &&
 			(meas < (d->n_btn_meas + 1))); meas++) {
-		mv[meas] = __wcd9xxx_codec_sta_dce_v(mbhc, 1, dce[meas], dce_z);
+		mv[meas] = __wcd9xxx_codec_sta_dce_v(mbhc, 1, dce[meas], dce_z,
+						     mbhc->mbhc_data.micb_mv);
 		mv_s[meas] = vddio ? scale_v_micb_vddio(mbhc, mv[meas], false) :
 				     mv[meas];
 		btnmeas[meas] = wcd9xxx_determine_button(mbhc, mv_s[meas]);
@@ -2925,7 +3314,7 @@
 static void wcd9xxx_mbhc_cal(struct wcd9xxx_mbhc *mbhc)
 {
 	u8 cfilt_mode;
-	u16 reg0, reg1;
+	u16 reg0, reg1, reg2;
 	struct snd_soc_codec *codec = mbhc->codec;
 
 	pr_debug("%s: enter\n", __func__);
@@ -2988,10 +3377,26 @@
 	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
 	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
 	mbhc->mbhc_data.dce_z = __wcd9xxx_codec_sta_dce(mbhc, 1, true, false);
+
+	/* compute dce_z for current source */
+	reg2 = snd_soc_read(codec, WCD9XXX_A_CDC_MBHC_B1_CTL);
+	snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x78,
+			    WCD9XXX_MBHC_NSC_CS << 3);
+
+	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
+	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
+	mbhc->mbhc_data.dce_nsc_cs_z = __wcd9xxx_codec_sta_dce(mbhc, 1, true,
+							       false);
+	pr_debug("%s: dce_z with nsc cs: 0x%x\n", __func__,
+						 mbhc->mbhc_data.dce_nsc_cs_z);
+
+	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, reg2);
+
 	/* STA measurement for 0 voltage */
 	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
 	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
 	mbhc->mbhc_data.sta_z = __wcd9xxx_codec_sta_dce(mbhc, 0, true, false);
+
 	/* Restore registers */
 	snd_soc_write(codec, mbhc->mbhc_bias_regs.ctl_reg, reg0);
 	snd_soc_write(codec, WCD9XXX_A_MAD_ANA_CTRL, reg1);
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.h b/sound/soc/codecs/wcd9xxx-mbhc.h
index 0599ccb..88c911f 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.h
+++ b/sound/soc/codecs/wcd9xxx-mbhc.h
@@ -43,6 +43,7 @@
 /* Data used by MBHC */
 struct mbhc_internal_cal_data {
 	u16 dce_z;
+	u16 dce_nsc_cs_z;
 	u16 dce_mb;
 	u16 sta_z;
 	u16 sta_mb;
@@ -59,6 +60,7 @@
 	u16 v_no_mic;
 	s16 v_inval_ins_low;
 	s16 v_inval_ins_high;
+	u16 v_cs_ins_h;
 };
 
 enum wcd9xxx_mbhc_plug_type {
@@ -83,6 +85,12 @@
 	MBHC_MICBIAS_ENABLE_REGULAR_HEADSET,
 };
 
+enum wcd9xx_mbhc_cs_enable_bits {
+	MBHC_CS_ENABLE_POLLING,
+	MBHC_CS_ENABLE_INSERTION,
+	MBHC_CS_ENABLE_REMOVAL,
+};
+
 enum wcd9xxx_mbhc_state {
 	MBHC_STATE_NONE = -1,
 	MBHC_STATE_POTENTIAL,
@@ -210,6 +218,7 @@
 	unsigned long micbias_enable_flags;
 	/* swap_gnd_mic returns true if extern GND/MIC swap switch toggled */
 	bool (*swap_gnd_mic) (struct snd_soc_codec *);
+	unsigned long cs_enable_flags;
 };
 
 struct wcd9xxx_cfilt_mode {
diff --git a/sound/soc/msm/msm8226.c b/sound/soc/msm/msm8226.c
index 85ed869..19d717e 100644
--- a/sound/soc/msm/msm8226.c
+++ b/sound/soc/msm/msm8226.c
@@ -83,6 +83,9 @@
 	.micbias_enable_flags = 1 << MBHC_MICBIAS_ENABLE_THRESHOLD_HEADSET,
 	.insert_detect = true,
 	.swap_gnd_mic = NULL,
+	.cs_enable_flags = (1 << MBHC_CS_ENABLE_POLLING |
+			    1 << MBHC_CS_ENABLE_INSERTION |
+			    1 << MBHC_CS_ENABLE_REMOVAL),
 };
 
 struct msm_auxpcm_gpio {
@@ -788,7 +791,7 @@
 	S(c[1], 124);
 	S(nc, 1);
 	S(n_meas, 5);
-	S(mbhc_nsc, 11);
+	S(mbhc_nsc, 10);
 	S(n_btn_meas, 1);
 	S(n_btn_con, 2);
 	S(num_btn, WCD9XXX_MBHC_DEF_BUTTONS);
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index b28f0f49..769b8eb 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -133,6 +133,9 @@
 	.micbias_enable_flags = 1 << MBHC_MICBIAS_ENABLE_THRESHOLD_HEADSET,
 	.insert_detect = true,
 	.swap_gnd_mic = NULL,
+	.cs_enable_flags = (1 << MBHC_CS_ENABLE_POLLING |
+			    1 << MBHC_CS_ENABLE_INSERTION |
+			    1 << MBHC_CS_ENABLE_REMOVAL),
 };
 
 struct msm_auxpcm_gpio {
diff --git a/sound/soc/msm/msm8x10.c b/sound/soc/msm/msm8x10.c
index 340d3db..9150751 100644
--- a/sound/soc/msm/msm8x10.c
+++ b/sound/soc/msm/msm8x10.c
@@ -180,6 +180,39 @@
 	return 0;
 }
 
+static const char *const btsco_rate_text[] = {"8000", "16000"};
+static const struct soc_enum msm_btsco_enum[] = {
+	SOC_ENUM_SINGLE_EXT(2, btsco_rate_text),
+};
+
+static int msm_btsco_rate_get(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s: msm_btsco_rate  = %d", __func__, msm_btsco_rate);
+
+	ucontrol->value.integer.value[0] = msm_btsco_rate;
+	return 0;
+}
+
+static int msm_btsco_rate_put(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	switch (ucontrol->value.integer.value[0]) {
+	case 8000:
+		msm_btsco_rate = BTSCO_RATE_8KHZ;
+		break;
+	case 16000:
+		msm_btsco_rate = BTSCO_RATE_16KHZ;
+		break;
+	default:
+		msm_btsco_rate = BTSCO_RATE_8KHZ;
+		break;
+	}
+
+	pr_debug("%s: msm_btsco_rate = %d\n", __func__, msm_btsco_rate);
+	return 0;
+}
+
 static int msm_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 					struct snd_pcm_hw_params *params)
 {
@@ -318,6 +351,11 @@
 	return ret;
 }
 
+static const struct snd_kcontrol_new msm_snd_controls[] = {
+	SOC_ENUM_EXT("Internal BTSCO SampleRate", msm_btsco_enum[0],
+		     msm_btsco_rate_get, msm_btsco_rate_put),
+};
+
 static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
 {
 
@@ -334,6 +372,11 @@
 	snd_soc_dapm_enable_pin(dapm, "Lineout amp");
 	snd_soc_dapm_sync(dapm);
 
+	ret = snd_soc_add_codec_controls(codec, msm_snd_controls,
+					 ARRAY_SIZE(msm_snd_controls));
+	if (ret < 0)
+		return ret;
+
 	ret = snd_soc_jack_new(codec, "Headset Jack",
 			SND_JACK_HEADSET, &hs_jack);
 	if (ret) {
diff --git a/sound/soc/msm/qdsp6v2/audio_acdb.h b/sound/soc/msm/qdsp6v2/audio_acdb.h
index 1685894..d9c1210 100644
--- a/sound/soc/msm/qdsp6v2/audio_acdb.h
+++ b/sound/soc/msm/qdsp6v2/audio_acdb.h
@@ -19,7 +19,6 @@
 enum {
 	RX_CAL,
 	TX_CAL,
-	AANC_TX_CAL,
 	MAX_AUDPROC_TYPES
 };
 
diff --git a/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h b/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h
index 58ea36d..113d85f 100644
--- a/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h
+++ b/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h
@@ -223,7 +223,7 @@
 					DOLBY_PARAM_VEN_LENGTH)
 
 #define DOLBY_PARAM_INT_ENDP_LENGTH		1
-#define DOLBY_PARAM_PAYLOAD_SIZE		4
+#define DOLBY_PARAM_PAYLOAD_SIZE		3
 #define DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM	329
 
 #define DOLBY_NUM_ENDP_DEPENDENT_PARAMS		1
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index df0fa6a..b1f968d 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -35,6 +35,16 @@
 #define INVALID_COPP_ID 0xFF
 #define ADM_GET_PARAMETER_LENGTH 350
 
+
+enum {
+	ADM_RX_AUDPROC_CAL,
+	ADM_TX_AUDPROC_CAL,
+	ADM_RX_AUDVOL_CAL,
+	ADM_TX_AUDVOL_CAL,
+	ADM_CUSTOM_TOP_CAL,
+	ADM_MAX_CAL_TYPES
+};
+
 struct adm_ctl {
 	void *apr;
 	atomic_t copp_id[AFE_MAX_PORTS];
@@ -48,10 +58,7 @@
 	struct acdb_cal_block mem_addr_audproc[MAX_AUDPROC_TYPES];
 	struct acdb_cal_block mem_addr_audvol[MAX_AUDPROC_TYPES];
 
-/* 0 - (MAX_AUDPROC_TYPES -1):				audproc handles */
-/* (MAX_AUDPROC_TYPES -1) - (2 * MAX_AUDPROC_TYPES -1):	audvol handles */
-/* + 1 for custom ADM topology */
-	atomic_t mem_map_cal_handles[(2 * MAX_AUDPROC_TYPES) + 1];
+	atomic_t mem_map_cal_handles[ADM_MAX_CAL_TYPES];
 	atomic_t mem_map_cal_index;
 
 	int set_custom_topology;
@@ -626,7 +633,7 @@
 
 	if (this_adm.set_custom_topology) {
 		/* specific index 4 for adm topology memory */
-		atomic_set(&this_adm.mem_map_cal_index, 4);
+		atomic_set(&this_adm.mem_map_cal_index, ADM_CUSTOM_TOP_CAL);
 
 		/* Only call this once */
 		this_adm.set_custom_topology = 0;
@@ -656,7 +663,8 @@
 	adm_top.hdr.opcode = ADM_CMD_ADD_TOPOLOGIES;
 	adm_top.payload_addr_lsw = cal_block.cal_paddr;
 	adm_top.payload_addr_msw = 0;
-	adm_top.mem_map_handle = atomic_read(&this_adm.mem_map_cal_handles[4]);
+	adm_top.mem_map_handle =
+		atomic_read(&this_adm.mem_map_cal_handles[ADM_CUSTOM_TOP_CAL]);
 	adm_top.payload_size = cal_block.cal_size;
 
 	atomic_set(&this_adm.copp_stat[index], 0);
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index 1810770..6dfe5b3 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -25,6 +25,14 @@
 
 #include "audio_acdb.h"
 
+enum {
+	AFE_RX_CAL,
+	AFE_TX_CAL,
+	AFE_AANC_TX_CAL,
+	MAX_AFE_CAL_TYPES
+};
+
+
 struct afe_ctl {
 	void *apr;
 	atomic_t state;
@@ -39,8 +47,8 @@
 	void *rx_private_data;
 	uint32_t mmap_handle;
 
-	struct acdb_cal_block afe_cal_addr[MAX_AUDPROC_TYPES];
-	atomic_t mem_map_cal_handles[MAX_AUDPROC_TYPES];
+	struct acdb_cal_block afe_cal_addr[MAX_AFE_CAL_TYPES];
+	atomic_t mem_map_cal_handles[MAX_AFE_CAL_TYPES];
 	atomic_t mem_map_cal_index;
 	u16 dtmf_gen_rx_portid;
 	struct afe_spkr_prot_calib_get_resp calib_data;
@@ -94,7 +102,7 @@
 		pr_debug("q6afe: reset event = %d %d apr[%p]\n",
 			data->reset_event, data->reset_proc, this_afe.apr);
 
-		for (i = 0; i < MAX_AUDPROC_TYPES; i++) {
+		for (i = 0; i < MAX_AFE_CAL_TYPES; i++) {
 			this_afe.afe_cal_addr[i].cal_paddr = 0;
 			this_afe.afe_cal_addr[i].cal_size = 0;
 		}
@@ -384,7 +392,7 @@
 	u32 handle;
 
 	pr_debug("%s: path %d\n", __func__, path);
-	if (path == AANC_TX_CAL) {
+	if (path == AFE_AANC_TX_CAL) {
 		get_aanc_cal(&cal_block);
 	} else {
 		get_afe_cal(path, &cal_block);
@@ -600,10 +608,10 @@
 
 	if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX) {
 		afe_send_cal_spkr_prot_tx(port_id);
-		afe_send_cal_block(TX_CAL, port_id);
+		afe_send_cal_block(AFE_TX_CAL, port_id);
 	} else if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) {
 		afe_send_cal_spkr_prot_rx(port_id);
-		afe_send_cal_block(RX_CAL, port_id);
+		afe_send_cal_block(AFE_RX_CAL, port_id);
 	}
 }
 
@@ -1149,7 +1157,7 @@
 			__func__, ret);
 		goto fail_cmd;
 	}
-	afe_send_cal_block(AANC_TX_CAL, tx_port_id);
+	afe_send_cal_block(AFE_AANC_TX_CAL, tx_port_id);
 
 fail_cmd:
 	return ret;
diff --git a/sound/soc/msm/qdsp6v2/q6lsm.c b/sound/soc/msm/qdsp6v2/q6lsm.c
index c5483ee..aec048e 100644
--- a/sound/soc/msm/qdsp6v2/q6lsm.c
+++ b/sound/soc/msm/qdsp6v2/q6lsm.c
@@ -735,7 +735,7 @@
 	int rc = -EINVAL;
 
 	if (!client)
-		goto fail;
+		return rc;
 
 	mutex_lock(&client->cmd_lock);
 	if (!client->sound_model.data) {
@@ -744,7 +744,6 @@
 		if (IS_ERR_OR_NULL(client->sound_model.client)) {
 			pr_err("%s: ION create client for AUDIO failed\n",
 			       __func__);
-			mutex_unlock(&client->cmd_lock);
 			goto fail;
 		}
 		client->sound_model.handle =
@@ -753,7 +752,6 @@
 		if (IS_ERR_OR_NULL(client->sound_model.handle)) {
 			pr_err("%s: ION memory allocation for AUDIO failed\n",
 			       __func__);
-			mutex_unlock(&client->cmd_lock);
 			goto fail;
 		}
 
@@ -764,7 +762,6 @@
 		if (rc) {
 			pr_err("%s: ION get physical mem failed, rc%d\n",
 			       __func__, rc);
-			mutex_unlock(&client->cmd_lock);
 			goto fail;
 		}
 
@@ -773,7 +770,6 @@
 				   client->sound_model.handle);
 		if (IS_ERR_OR_NULL(client->sound_model.data)) {
 			pr_err("%s: ION memory mapping failed\n", __func__);
-			mutex_unlock(&client->cmd_lock);
 			goto fail;
 		}
 		memset(client->sound_model.data, 0, len);
@@ -789,11 +785,13 @@
 				      &client->sound_model.mem_map_handle);
 	if (rc < 0) {
 		pr_err("%s:CMD Memory_map_regions failed\n", __func__);
-		goto fail;
+		goto exit;
 	}
 
 	return 0;
 fail:
+	mutex_unlock(&client->cmd_lock);
+exit:
 	q6lsm_snd_model_buf_free(client);
 	return rc;
 }