Merge "power: pm8921-bms: Fix SOC fluctuations at 100%"
diff --git a/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt b/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt
index 04310ec..b489f7a 100644
--- a/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt
+++ b/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt
@@ -13,21 +13,17 @@
 Required properties:
 - compatible:			Must be "qcom,cpr-regulator"
 - reg:				Register addresses for RBCPR, RBCPR clock
-				select, PVS eFuse and CPR eFuse
+				select, PVS and CPR eFuse address
 - reg-names:			Register names. Must be "rbcpr", "rbcpr_clk",
-				"pvs_efuse" and "cpr_efuse"
+				"efuse_addr"
 - regulator-name:		A string used to describe the regulator
 - interrupts:			Interrupt line from RBCPR to interrupt controller.
 - regulator-min-microvolt:	Minimum corner value as min constraint, which
 				should be 1 for SVS corner
 - regulator-max-microvolt:	Maximum corner value as max constraint, which
 				should be 4 for SUPER_TURBO or 3 for TURBO
-- qcom,num-efuse-bits:		The number of bits used in efuse memory to
-				represent total number of PVS bins. It should
-				not exceed a maximum of 5 for total number of
-				32 bins.
 - qcom,pvs-bin-process:		A list of integers whose length is equal to 2 to
-				the power of qcom,num-efuse-bits. The location or
+				the power of qcom,pvs-fuse[num-of-bits]. The location or
 				0-based index of an element in the list corresponds
 				to the bin number. The value of each integer
 				corresponds to the PVS process speed of the APC
@@ -54,7 +50,7 @@
 - qcom,cpr-timer-cons-down:	Consecutive number of timer interval (qcom,cpr-timer-delay)
 				occurred before issuing DOWN interrupt.
 - qcom,cpr-irq-line:		Internal interrupt route signal of RBCPR, one of 0, 1 or 2.
-- qcom,cpr-step-quotient:	Number of CPR quotient (RO count) per vdd-apc-supply step
+- qcom,cpr-step-quotient:	Number of CPR quotient (Ring Oscillator(RO) count) per vdd-apc-supply step
 				to issue error_steps.
 - qcom,cpr-up-threshold:	The threshold for CPR to issue interrupt when
 				error_steps is greater than it when stepping up.
@@ -64,6 +60,62 @@
 - qcom,cpr-gcnt-time:		The time for gate count in microseconds.
 - qcom,cpr-apc-volt-step:	The voltage in microvolt per CPR step, such as 5000uV.
 
+- qcom,pvs-fuse-redun-sel:	Array of 4 elements to indicate where to read the bits and what value to
+				compare with in order to decide if the redundant PVS fuse bits would be
+				used instead of the original bits. The 4 elements with index [0..3] are:
+				  [0] => the fuse row number of the selector
+				  [1] => LSB bit position of the bits
+				  [2] => number of bits
+				  [3] => the value to indicate redundant selection
+				When the value of the fuse bits specified by first 3 elements equals to
+				the value in 4th element, redundant PVS fuse bits should be selected.
+				Otherwise, the original PVS bits should be selected.
+- qcom,pvs-fuse:		Array of three elements to indicate the bits for PVS fuse. The array
+				should have index and value like this:
+				  [0] => the PVS fuse row number
+				  [1] => LSB bit position of the bits
+				  [2] => number of bits
+- qcom,pvs-fuse-redun:		Array of three elements to indicate the bits for redundant PVS fuse.
+				The array should have index and value like this:
+				  [0] => the redundant PVS fuse row number
+				  [1] => LSB bit position of the bits
+				  [2] => number of bits
+
+- qcom,cpr-fuse-redun-sel:	Array of 4 elements to indicate where to read the bits and what value to
+				compare with in order to decide if the redundant CPR fuse bits would be
+				used instead of the original bits. The 4 elements with index [0..3] are:
+				  [0] => the fuse row number of the selector
+				  [1] => LSB bit position of the bits
+				  [2] => number of bits
+				  [3] => the value to indicate redundant selection
+				When the value of the fuse bits specified by first 3 elements equals to
+				the value in 4th element, redundant CPR fuse bits should be selected.
+				Otherwise, the original CPR bits should be selected.
+- qcom,cpr-fuse-row:		Row number of CPR fuse
+- qcom,cpr-fuse-bp-cpr-disable:	Bit position of the bit to indicate if CPR should be disable
+- qcom,cpr-fuse-bp-scheme:	Bit position of the bit to indicate if it's a global/local scheme
+- qcom,cpr-fuse-target-quot:	Array of bit positions in fuse for Target Quotient of all corners.
+				It should have index and value like this:
+				  [0] => bit position of the LSB bit for SVS target quotient
+				  [1] => bit position of the LSB bit for NOMINAL target quotient
+				  [2] => bit position of the LSB bit for TURBO target quotient
+- qcom,cpr-fuse-ro-sel:		Array of bit positions in fuse for RO select of all corners.
+				It should have index and value like this:
+				  [0] => bit position of the LSB bit for SVS RO select bits
+				  [1] => bit position of the LSB bit for NOMINAL RO select bits
+				  [2] => bit position of the LSB bit for TURBO RO select bits
+- qcom,cpr-fuse-redun-row:	Row number of the redundant CPR fuse
+- qcom,cpr-fuse-redun-target-quot:	Array of bit positions in fuse for redundant Target Quotient of all corners.
+				It should have index and value like this:
+				  [0] => bit position of the LSB bit for redundant SVS target quotient
+				  [1] => bit position of the LSB bit for redundant NOMINAL target quotient
+				  [2] => bit position of the LSB bit for redundant TURBO target quotient
+- qcom,cpr-fuse-redun-ro-sel:	Array of bit positions in eFuse for redundant RO select.
+				It should have index and value like this:
+				  [0] => bit position of the LSB bit for redundant SVS RO select bits
+				  [1] => bit position of the LSB bit for redundant NOMINAL RO select bits
+				  [2] => bit position of the LSB bit for redundant TURBO RO select bits
+
 
 Optional properties:
 - vdd-mx-supply:		Regulator to supply memory power as dependency
@@ -78,6 +130,10 @@
 				  2 => equal to slow speed corner ceiling
 				  3 => equal to qcom,vdd-mx-vmax
 				This is required when vdd-mx-supply is present.
+- qcom,cpr-fuse-redun-bp-cpr-disable:	Redundant bit position of the bit to indicate if CPR should be disable
+- qcom,cpr-fuse-redun-bp-scheme:	Redundant bit position of the bit to indicate if it's a global/local scheme
+					This property is required if cpr-fuse-redun-bp-cpr-disable
+					is present, and vise versa.
 - qcom,cpr-enable:		Present: CPR enabled by default.
 				Not Present: CPR disable by default.
 
@@ -86,13 +142,17 @@
 	apc_vreg_corner: regulator@f9018000 {
 		status = "okay";
 		compatible = "qcom,cpr-regulator";
-		reg = <0xf9018000 0x1000>, <0xfc4b80b0 8>, <0xfc4bc450 16>;
-		reg-names = "rbcpr", "pvs_efuse", "cpr_efuse";
+		reg = <0xf9018000 0x1000>, <0xfc4b8000 0x1000>;
+		reg-names = "rbcpr", "efuse_addr";
 		interrupts = <0 15 0>;
 		regulator-name = "apc_corner";
 		regulator-min-microvolt = <1>;
 		regulator-max-microvolt = <3>;
-		qcom,num-efuse-bits = <5>;
+
+		qcom,pvs-fuse = <22 6 5>;
+		qcom,pvs-fuse-redun-sel = <22 24 3 2>;
+		qcom,pvs-fuse-redun = <22 27 5>;
+
 		qcom,pvs-bin-process = <0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 2
 					2 2 2 2 3 3 3 3 3 3 3 3 0 0 0 0>;
 		qcom,pvs-corner-ceiling-slow = <1050000 1160000 1275000>;
@@ -115,5 +175,15 @@
 		qcom,cpr-idle-clocks = <5>;
 		qcom,cpr-gcnt-time = <1>;
 		qcom,cpr-apc-volt-step = <5000>;
+
+		qcom,cpr-fuse-row = <138>;
+		qcom,cpr-fuse-bp-cpr-disable = <36>;
+		qcom,cpr-fuse-bp-scheme = <37>;
+		qcom,cpr-fuse-target-quot = <24 12 0>;
+		qcom,cpr-fuse-ro-sel = <54 38 41>;
+		qcom,cpr-fuse-redun-sel = <138 57 1 1>;
+		qcom,cpr-fuse-redun-row = <139>;
+		qcom,cpr-fuse-redun-target-quot = <24 12 0>;
+		qcom,cpr-fuse-redun-ro-sel = <46 36 39>;
 	};
 
diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
index 514160e..7093fb8 100644
--- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
@@ -126,6 +126,11 @@
 - qcom,mdss-has-wfd-blk: Boolean property to indicate the presence of dedicated
 			writeback wfd block in MDSS as opposed to writeback
 			block that is shared between rotator and wfd.
+- qcom,mdss-smp-mb-per-pipe:	Maximum number of shared memory pool blocks
+				restricted for a source surface pipe. If this
+				property is not specified, no such restriction
+				would be applied.
+
 Optional subnodes:
 Child nodes representing the frame buffer virtual devices.
 
@@ -161,6 +166,7 @@
 		qcom,mdss-pipe-dma-fetch-id = <10 13>;
 		qcom,mdss-smp-data = <22 4096>;
 		qcom,mdss-rot-block-size = <64>;
+		qcom,mdss-smp-mb-per-pipe = <2>;
 		qcom,mdss-has-bwc;
 		qcom,mdss-has-decimation;
 		qcom,mdss-has-wfd-blk;
diff --git a/Documentation/devicetree/bindings/input/misc/mpu3050.txt b/Documentation/devicetree/bindings/input/misc/mpu3050.txt
new file mode 100644
index 0000000..edbe147
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/misc/mpu3050.txt
@@ -0,0 +1,31 @@
+InvenSense MPU30X0-series gyrometer driver
+
+Required properties:
+
+ - compatible		: Should be "invn,mpu3050".
+ - reg				: i2c slave address of the device.
+ - interrupt-parent	: Parent of interrupt.
+ - interrupts		: Gyrometer sample interrupt to indicate new data ready.
+ - vdd-supply		: Analog power supply needed to power device.
+ - vlogic-supply	: Digital IO power supply needed for IO and I2C.
+ - invn,gpio-int	: GPIO used for interrupt.
+ - invn,gpio-en		: GPIO used for power enabling.
+ - invn,poll-interval	: Initial data polling interval in milliseconds.
+
+Example:
+	i2c@f9925000 {
+		mpu3050@68 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "okay";
+			reg = <0x68>;
+			compatible = "invn,mpu3050";
+			interrupt-parent = <&msmgpio>;
+			interrupts = <84 0x2>;
+			vlogic-supply = <&pm8110_l14>;
+			vdd-supply = <&pm8110_l19>;
+			invn,gpio-int = <&msmgpio 84 0x2>;
+			invn,gpio-en = <&pm8110_gpios 2 0x2>;
+			invn,poll-interval = <200>;
+		};
+	};
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
new file mode 100644
index 0000000..2d730e3
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
@@ -0,0 +1,186 @@
+== Introduction ==
+
+Hardware modules that control pin multiplexing or configuration parameters
+such as pull-up/down, tri-state, drive-strength etc are designated as pin
+controllers. Each pin controller must be represented as a node in device tree,
+just like any other hardware module.
+
+Hardware modules whose signals are affected by pin configuration are
+designated client devices. Again, each client device must be represented as a
+node in device tree, just like any other hardware module.
+
+For a client device to operate correctly, certain pin controllers must
+set up certain specific pin configurations. Some client devices need a
+single static pin configuration, e.g. set up during initialization. Others
+need to reconfigure pins at run-time, for example to tri-state pins when the
+device is inactive. Hence, each client device can define a set of named
+states. The number and names of those states is defined by the client device's
+own binding.
+
+The common pinctrl bindings defined in this file provide an infrastructure
+for client device device tree nodes to map those state names to the pin
+configuration used by those states.
+
+Note that pin controllers themselves may also be client devices of themselves.
+For example, a pin controller may set up its own "active" state when the
+driver loads. This would allow representing a board's static pin configuration
+in a single place, rather than splitting it across multiple client device
+nodes. The decision to do this or not somewhat rests with the author of
+individual board device tree files, and any requirements imposed by the
+bindings for the individual client devices in use by that board, i.e. whether
+they require certain specific named states for dynamic pin configuration.
+
+== Pinctrl client devices ==
+
+For each client device individually, every pin state is assigned an integer
+ID. These numbers start at 0, and are contiguous. For each state ID, a unique
+property exists to define the pin configuration. Each state may also be
+assigned a name. When names are used, another property exists to map from
+those names to the integer IDs.
+
+Each client device's own binding determines the set of states the must be
+defined in its device tree node, and whether to define the set of state
+IDs that must be provided, or whether to define the set of state names that
+must be provided.
+
+Required properties:
+pinctrl-0:	List of phandles, each pointing at a pin configuration
+		node. These referenced pin configuration nodes must be child
+		nodes of the pin controller that they configure. Multiple
+		entries may exist in this list so that multiple pin
+		controllers may be configured, or so that a state may be built
+		from multiple nodes for a single pin controller, each
+		contributing part of the overall configuration. See the next
+		section of this document for details of the format of these
+		pin configuration nodes.
+
+		In some cases, it may be useful to define a state, but for it
+		to be empty. This may be required when a common IP block is
+		used in an SoC either without a pin controller, or where the
+		pin controller does not affect the HW module in question. If
+		the binding for that IP block requires certain pin states to
+		exist, they must still be defined, but may be left empty.
+
+Optional properties:
+pinctrl-1:	List of phandles, each pointing at a pin configuration
+		node within a pin controller.
+...
+pinctrl-n:	List of phandles, each pointing at a pin configuration
+		node within a pin controller.
+pinctrl-names:	The list of names to assign states. List entry 0 defines the
+		name for integer state ID 0, list entry 1 for state ID 1, and
+		so on.
+
+For example:
+
+	/* For a client device requiring named states */
+	device {
+		pinctrl-names = "active", "idle";
+		pinctrl-0 = <&state_0_node_a>;
+		pinctrl-1 = <&state_1_node_a &state_1_node_b>;
+	};
+
+	/* For the same device if using state IDs */
+	device {
+		pinctrl-0 = <&state_0_node_a>;
+		pinctrl-1 = <&state_1_node_a &state_1_node_b>;
+	};
+
+	/*
+	 * For an IP block whose binding supports pin configuration,
+	 * but in use on an SoC that doesn't have any pin control hardware
+	 */
+	device {
+		pinctrl-names = "active", "idle";
+		pinctrl-0 = <>;
+		pinctrl-1 = <>;
+	};
+
+== Pin controller devices ==
+
+Pin controller devices should contain the pin configuration nodes that client
+devices reference.
+
+For example:
+
+	pincontroller {
+		... /* Standard DT properties for the device itself elided */
+
+		state_0_node_a {
+			...
+		};
+		state_1_node_a {
+			...
+		};
+		state_1_node_b {
+			...
+		};
+	}
+
+The contents of each of those pin configuration child nodes is defined
+entirely by the binding for the individual pin controller device. There
+exists no common standard for this content.
+
+The pin configuration nodes need not be direct children of the pin controller
+device; they may be grandchildren, for example. Whether this is legal, and
+whether there is any interaction between the child and intermediate parent
+nodes, is again defined entirely by the binding for the individual pin
+controller device.
+
+== Using generic pinconfig options ==
+
+Generic pinconfig parameters can be used by defining a separate node containing
+the applicable parameters (and optional values), like:
+
+pcfg_pull_up: pcfg_pull_up {
+	bias-pull-up;
+	drive-strength = <20>;
+};
+
+This node should then be referenced in the appropriate pinctrl node as a phandle
+and parsed in the driver using the pinconf_generic_parse_dt_config function.
+
+Supported configuration parameters are:
+
+bias-disable		- disable any pin bias
+bias-high-impedance	- high impedance mode ("third-state", "floating")
+bias-bus-hold		- latch weakly
+bias-pull-up		- pull up the pin
+bias-pull-down		- pull down the pin
+bias-pull-pin-default	- use pin-default pull state
+drive-push-pull		- drive actively high and low
+drive-open-drain	- drive with open drain
+drive-open-source	- drive with open source
+drive-strength		- sink or source at most X mA
+input-schmitt-enable	- enable schmitt-trigger mode
+input-schmitt-disable	- disable schmitt-trigger mode
+input-schmitt		- run in schmitt-trigger mode with hysteresis X
+input-debounce		- debounce mode with debound time X
+power-source		- select power source X
+slew-rate		- use slew-rate X
+low-power-enable	- enable low power mode
+low-power-disable	- disable low power mode
+output-low		- set the pin to output mode with low level
+output-high		- set the pin to output mode with high level
+
+Arguments for parameters:
+
+- bias-pull-up, -down and -pin-default take as optional argument 0 to disable
+  the pull, on hardware supporting it the pull strength in Ohm. bias-disable
+  will also disable any active pull.
+
+- drive-strength takes as argument the target strength in mA.
+
+- input-schmitt takes as argument the adjustable hysteresis in a
+  driver-specific format
+
+- input-debounce takes the debounce time as argument or 0 to disable debouncing
+
+- power-source argument is the custom value describing the source to select
+
+- slew-rate takes as argument the target rate in a driver-specific format
+
+All parameters not listed here, do not take an argument.
+
+More in-depth documentation on these parameters can be found in
+<include/linux/pinctrl/pinconfig-generic.h>
diff --git a/Documentation/devicetree/bindings/power/qpnp-charger.txt b/Documentation/devicetree/bindings/power/qpnp-charger.txt
index 66949af..e3c3555 100644
--- a/Documentation/devicetree/bindings/power/qpnp-charger.txt
+++ b/Documentation/devicetree/bindings/power/qpnp-charger.txt
@@ -78,6 +78,8 @@
 					for the OTG regulator.
 - boost-parent-supply			Specify a phandle to a parent supply regulator
 					for the boost regulator.
+- qcom,resume-soc			Capacity in percent at which charging should resume
+					when a fully charged battery drops below this level.
 
 Sub node required structure:
 - A qcom,chg node must be a child of an SPMI node that has specified
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index c799ffb..b618597 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -661,7 +661,9 @@
 		 prim-gpio-tert : Primary AUXPCM shares GPIOs with Tertiary MI2S
 
 Optional Properties:
-- qcom,us-euro-gpios : GPIO on which gnd/mic swap signal is coming.
+- qcom,cdc-us-euro-gpios : GPIO on which gnd/mic swap signal is coming.
+- qcom,cdc-lineout-spkr-gpios : GPIO which controls external PAs to enable Lineout1/2 speaker
+- qcom,cdc-vdd-spkr-gpios : GPIO which controls PA for VDD speaker
 
 Example:
 
@@ -675,4 +677,6 @@
 	qcom,prim-auxpcm-gpio-dout = <&msmgpio 66 0>;
 	qcom,prim-auxpcm-gpio-set = "prim-gpio-prim";
 	qcom,cdc-us-euro-gpios = <&msmgpio 69 0>;
+	qcom,cdc-lineout-spkr-gpios = <&pm8226_gpios 2 0>;
+	qcom,cdc-vdd-spkr-gpios = <&pm8226_gpios 3 0>;
 };
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 0ebbe63..b4bcaf6 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -23,6 +23,7 @@
 ibm	International Business Machines (IBM)
 idt	Integrated Device Technologies, Inc.
 intercontrol	Inter Control Group
+invn	InvenSense Inc.
 linux	Linux-specific binding
 kionix	Kionix Inc.
 marvell	Marvell Technology Group Ltd.
diff --git a/arch/arm/boot/dts/apq8074-dragonboard.dtsi b/arch/arm/boot/dts/apq8074-dragonboard.dtsi
index 21e92ab..53e9b3b 100644
--- a/arch/arm/boot/dts/apq8074-dragonboard.dtsi
+++ b/arch/arm/boot/dts/apq8074-dragonboard.dtsi
@@ -191,10 +191,10 @@
 			"MIC BIAS2 External", "ANCRight Headset Mic",
 			"AMIC4", "MIC BIAS2 External",
 			"MIC BIAS2 External", "ANCLeft Headset Mic",
-			"AMIC5", "MIC BIAS1 External",
-			"MIC BIAS1 External", "Analog Mic6",
-			"AMIC6", "MIC BIAS1 External",
-			"MIC BIAS1 External", "Analog Mic7",
+			"AMIC5", "MIC BIAS4 External",
+			"MIC BIAS4 External", "Analog Mic6",
+			"AMIC6", "MIC BIAS3 External",
+			"MIC BIAS3 External", "Analog Mic7",
 			"DMIC1", "MIC BIAS3 External",
 			"MIC BIAS3 External", "Digital Mic1",
 			"DMIC2", "MIC BIAS3 External",
@@ -208,11 +208,14 @@
 			"DMIC6", "MIC BIAS4 External",
 			"MIC BIAS4 External", "Digital Mic6";
 
+
 		qcom,prim-auxpcm-gpio-clk  = <&msmgpio 74 0>;
 		qcom,prim-auxpcm-gpio-sync = <&msmgpio 75 0>;
 		qcom,prim-auxpcm-gpio-din  = <&msmgpio 76 0>;
 		qcom,prim-auxpcm-gpio-dout = <&msmgpio 77 0>;
 		qcom,prim-auxpcm-gpio-set = "prim-gpio-tert";
+
+		qcom,cdc-micbias2-headset-only;
 	};
 
 	qcom,pronto@fb21b000 {
@@ -287,6 +290,7 @@
 };
 
 &usb3 {
+	interrupts = <0>;	/* remove pmic_id_irq; used by &usb_otg */
 	qcom,charging-disabled;
 	vbus_dwc3-supply = <0>;
 	dwc3@f9200000 {
@@ -296,8 +300,17 @@
 
 &slim_msm {
 	taiko_codec {
+		qcom,cdc-micbias1-ext-cap;
 		qcom,cdc-micbias2-ext-cap;
 		qcom,cdc-micbias3-ext-cap;
+		qcom,cdc-micbias4-ext-cap;
+
+		/* If boot isn't available, vph_pwr_vreg can be used instead */
+		cdc-vdd-spkdrv-supply = <&pm8941_boost>;
+		qcom,cdc-vdd-spkdrv-voltage = <5000000 5000000>;
+		qcom,cdc-vdd-spkdrv-current = <1250000>;
+
+		qcom,cdc-on-demand-supplies = "cdc-vdd-spkdrv";
 	};
 };
 
@@ -542,34 +555,32 @@
 	status = "disabled";
 };
 
-&spmi_bus {
-	qcom,pm8941@1 {
-		qcom,leds@d000 {
-			qcom,rgb_2 {
-				status = "ok";
-				qcom,default-state = "on";
-				qcom,turn-off-delay-ms = <1000>;
-			};
+&pm8941_lsid1 {
+	qcom,leds@d000 {
+		qcom,rgb_2 {
+			status = "ok";
+			qcom,default-state = "on";
+			qcom,turn-off-delay-ms = <1000>;
 		};
+	};
 
-		qcom,leds@d800 {
-			status = "okay";
-			qcom,wled_0 {
-				label = "wled";
-				linux,name = "wled:backlight";
-				linux,default-trigger = "bkl-trigger";
-				qcom,cs-out-en;
-				qcom,op-fdbck = <1>;
-				qcom,default-state = "on";
-				qcom,max-current = <20>;
-				qcom,ctrl-delay-us = <0>;
-				qcom,boost-curr-lim = <3>;
-				qcom,cp-sel = <0>;
-				qcom,switch-freq = <2>;
-				qcom,ovp-val = <1>;
-				qcom,num-strings = <1>;
-				qcom,id = <0>;
-			};
+	qcom,leds@d800 {
+		status = "okay";
+		qcom,wled_0 {
+			label = "wled";
+			linux,name = "wled:backlight";
+			linux,default-trigger = "bkl-trigger";
+			qcom,cs-out-en;
+			qcom,op-fdbck = <1>;
+			qcom,default-state = "on";
+			qcom,max-current = <20>;
+			qcom,ctrl-delay-us = <0>;
+			qcom,boost-curr-lim = <3>;
+			qcom,cp-sel = <0>;
+			qcom,switch-freq = <2>;
+			qcom,ovp-val = <1>;
+			qcom,num-strings = <1>;
+			qcom,id = <0>;
 		};
 	};
 };
diff --git a/arch/arm/boot/dts/apq8074-v2-cdp.dts b/arch/arm/boot/dts/apq8074-v2-cdp.dts
new file mode 100644
index 0000000..1dc0912
--- /dev/null
+++ b/arch/arm/boot/dts/apq8074-v2-cdp.dts
@@ -0,0 +1,34 @@
+/* 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.
+ */
+
+/dts-v1/;
+
+/include/ "apq8074-v2.dtsi"
+/include/ "msm8974-cdp.dtsi"
+
+/ {
+	model = "Qualcomm APQ 8074v2 CDP";
+	compatible = "qcom,apq8074-cdp", "qcom,apq8074", "qcom,cdp";
+	qcom,msm-id = <184 1 0x20000>;
+};
+
+&usb3 {
+	interrupt-parent = <&usb3>;
+	interrupts = <0 1>;
+	#interrupt-cells = <1>;
+	interrupt-map-mask = <0x0 0xffffffff>;
+	interrupt-map = <0x0 0 &intc 0 133 0
+			 0x0 1 &spmi_bus 0x0 0x0 0x9 0x0>;
+	interrupt-names = "hs_phy_irq", "pmic_id_irq";
+
+	qcom,misc-ref = <&pm8941_misc>;
+};
diff --git a/arch/arm/boot/dts/apq8084-gpu.dtsi b/arch/arm/boot/dts/apq8084-gpu.dtsi
new file mode 100644
index 0000000..8570b4f
--- /dev/null
+++ b/arch/arm/boot/dts/apq8084-gpu.dtsi
@@ -0,0 +1,95 @@
+/* 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.
+ */
+
+&soc {
+	msm_gpu: qcom,kgsl-3d0@fdb00000 {
+		label = "kgsl-3d0";
+		compatible = "qcom,kgsl-3d0", "qcom,kgsl-3d";
+		reg = <0xfdb00000 0x10000
+		       0xfdb20000 0x20000>;
+		reg-names = "kgsl_3d0_reg_memory" , "kgsl_3d0_shader_memory";
+		interrupts = <0 33 0>;
+		interrupt-names = "kgsl_3d0_irq";
+		qcom,id = <0>;
+
+		qcom,chipid = <0x04020000>;
+
+		qcom,initial-pwrlevel = <2>;
+
+		qcom,idle-timeout = <8>; //<HZ/12>
+		qcom,strtstp-sleepwake;
+		qcom,clk-map = <0x00000016>; //KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM_IFACE
+
+		/* Bus Scale Settings */
+		qcom,msm-bus,name = "grp3d";
+		qcom,msm-bus,num-cases = <5>;
+		qcom,msm-bus,num-paths = <2>;
+		qcom,msm-bus,vectors-KBps =
+				<26 512 0 0>, <89 604 0 0>,
+				<26 512 0 3144000>, <89 604 0 3200000>,
+				<26 512 0 4800000>, <89 604 0 4800000>,
+				<26 512 0 6400000>, <89 604 0 6400000>,
+				<26 512 0 8528000>, <89 604 0 9600000>;
+
+		/* GDSC oxili regulators */
+		vddcx-supply = <&gdsc_oxili_cx>;
+		vdd-supply = <&gdsc_oxili_gx>;
+
+		/* IOMMU Data */
+		iommu = <&kgsl_iommu>;
+
+		/* Power levels */
+		qcom,gpu-pwrlevels {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			compatible = "qcom,gpu-pwrlevels";
+
+			qcom,gpu-pwrlevel@0 {
+				reg = <0>;
+				qcom,gpu-freq = <600000000>;
+				qcom,bus-freq = <4>;
+				qcom,io-fraction = <33>;
+			};
+
+			qcom,gpu-pwrlevel@1 {
+				reg = <1>;
+				qcom,gpu-freq = <400000000>;
+				qcom,bus-freq = <3>;
+				qcom,io-fraction = <66>;
+			};
+
+			qcom,gpu-pwrlevel@2 {
+				reg = <2>;
+				qcom,gpu-freq = <300000000>;
+				qcom,bus-freq = <2>;
+				qcom,io-fraction = <100>;
+			};
+
+			qcom,gpu-pwrlevel@3 {
+				reg = <3>;
+				qcom,gpu-freq = <200000000>;
+				qcom,bus-freq = <1>;
+				qcom,io-fraction = <100>;
+			};
+
+			qcom,gpu-pwrlevel@4 {
+				reg = <4>;
+				qcom,gpu-freq = <27000000>;
+				qcom,bus-freq = <0>;
+				qcom,io-fraction = <0>;
+			};
+		};
+
+	};
+};
+
diff --git a/arch/arm/boot/dts/apq8084.dtsi b/arch/arm/boot/dts/apq8084.dtsi
index 80fedee..350257c 100644
--- a/arch/arm/boot/dts/apq8084.dtsi
+++ b/arch/arm/boot/dts/apq8084.dtsi
@@ -25,6 +25,7 @@
 /include/ "apq8084-smp2p.dtsi"
 /include/ "apq8084-coresight.dtsi"
 /include/ "apq8084-mdss.dtsi"
+/include/ "apq8084-gpu.dtsi"
 
 &soc {
 	#address-cells = <1>;
@@ -244,7 +245,7 @@
 
 	memory_hole: qcom,msm-mem-hole {
 		compatible = "qcom,msm-mem-hole";
-		qcom,memblock-remove = <0x0dc00000 0x2000000>; /* Address and Size of Hole */
+		qcom,memblock-remove = <0x0d200000 0x02c00000>; /* Address and Size of Hole */
 	};
 
 	qcom,ipc-spinlock@fd484000 {
@@ -305,6 +306,62 @@
 	};
 };
 
+&gdsc_venus {
+	status = "ok";
+};
+
+&gdsc_venus_core0 {
+	status = "ok";
+};
+
+&gdsc_venus_core1 {
+	status = "ok";
+};
+
+&gdsc_vpu {
+	status = "ok";
+};
+
+&gdsc_mdss {
+	status = "ok";
+};
+
+&gdsc_jpeg {
+	status = "ok";
+};
+
+&gdsc_vfe {
+	status = "ok";
+};
+
+&gdsc_oxili_gx {
+	status = "ok";
+};
+
+&gdsc_oxili_cx {
+	status = "ok";
+};
+
+&gdsc_usb_hsic {
+	status = "ok";
+};
+
+&gdsc_pcie_0{
+	status = "ok";
+};
+
+&gdsc_pcie_1{
+	status = "ok";
+};
+
+&gdsc_usb30{
+	status = "ok";
+};
+
+&gdsc_usb30_sec{
+	status = "ok";
+};
+
 /include/ "msm-pma8084.dtsi"
 /include/ "apq8084-regulator.dtsi"
 
diff --git a/arch/arm/boot/dts/dsi-v2-panel-hx8379a-wvga-video.dtsi b/arch/arm/boot/dts/dsi-v2-panel-hx8379a-wvga-video.dtsi
index b9ed050..befc29c 100644
--- a/arch/arm/boot/dts/dsi-v2-panel-hx8379a-wvga-video.dtsi
+++ b/arch/arm/boot/dts/dsi-v2-panel-hx8379a-wvga-video.dtsi
@@ -40,7 +40,7 @@
 		qcom,mdss-pan-dsi-mdp-tr = <0x0>;/*todo*/
 		qcom,mdss-pan-dsi-dma-tr = <0x04>;
 		qcom,mdss-pan-dsi-frame-rate = <60>;
-		qcom,panel-phy-regulatorSettings =[09 08 05 00 20 03];
+		qcom,panel-phy-regulatorSettings =[02 08 05 00 20 03];
 		qcom,panel-phy-timingSettings = [5D 12 0C  00 33 39
 						 10 16 15  03 04 00];
 		qcom,panel-phy-strengthCtrl = [ff 06];
diff --git a/arch/arm/boot/dts/dsi-v2-panel-truly-wvga-video.dtsi b/arch/arm/boot/dts/dsi-v2-panel-truly-wvga-video.dtsi
index 891eac3..5693ccd 100644
--- a/arch/arm/boot/dts/dsi-v2-panel-truly-wvga-video.dtsi
+++ b/arch/arm/boot/dts/dsi-v2-panel-truly-wvga-video.dtsi
@@ -41,7 +41,7 @@
 		qcom,mdss-pan-dsi-mdp-tr = <0x0>;/*todo*/
 		qcom,mdss-pan-dsi-dma-tr = <0x04>;
 		qcom,mdss-pan-dsi-frame-rate = <60>;
-		qcom,panel-phy-regulatorSettings =[09 08 05 00 20 03];
+		qcom,panel-phy-regulatorSettings =[02 08 05 00 20 03];
 		qcom,panel-phy-timingSettings = [5D 12 0C  00 33 38
 						 10 16 1E 03 04 00];
 		qcom,panel-phy-strengthCtrl = [ff 06];
diff --git a/arch/arm/boot/dts/mpq8092-iommu.dtsi b/arch/arm/boot/dts/mpq8092-iommu.dtsi
index 56369dc..4fb2b24 100644
--- a/arch/arm/boot/dts/mpq8092-iommu.dtsi
+++ b/arch/arm/boot/dts/mpq8092-iommu.dtsi
@@ -14,27 +14,201 @@
 
 &jpeg_iommu {
 	status = "ok";
-	vdd-supply = <&gdsc_jpeg>;
+
+	qcom,iommu-bfb-regs =  <0x204c
+				0x2514
+				0x2540
+				0x256c
+				0x2314
+				0x2394
+				0x2414
+				0x2494
+				0x20ac
+				0x215c
+				0x220c
+				0x22bc
+				0x2008
+				0x200c
+				0x2010>;
+
+	qcom,iommu-bfb-data =  <0x3FFF
+				0x4
+				0x4
+				0x0
+				0x0
+				0x10
+				0x50
+				0x0
+				0x2000
+				0x2804
+				0x9614
+				0x0
+				0x0
+				0x0
+				0x0>;
 };
 
 &mdp_iommu {
 	status = "ok";
-	vdd-supply = <&gdsc_mdss>;
+
+	qcom,iommu-bfb-regs =  <0x204c
+				0x2514
+				0x2540
+				0x256c
+				0x20ac
+				0x215c
+				0x220c
+				0x22bc
+				0x2314
+				0x2394
+				0x2414
+				0x2494
+				0x2008
+				0x200c
+				0x2010
+				0x2014
+				0x2018>;
+
+	qcom,iommu-bfb-data =  <0x7FFFFF
+				0x4
+				0x10
+				0x0
+				0x5000
+				0x5a1d
+				0x1822d
+				0x0
+				0x0
+				0x28
+				0x68
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0>;
 };
 
 &venus_iommu {
 	status = "ok";
-	vdd-supply = <&gdsc_venus>;
+
+	qcom,iommu-bfb-regs =  <0x204c
+				0x2514
+				0x2540
+				0x256c
+				0x20ac
+				0x215c
+				0x220c
+				0x22bc
+				0x2314
+				0x2394
+				0x2414
+				0x2494
+				0x2008
+				0x200c
+				0x2010
+				0x2014
+				0x2018
+				0x201c>;
+
+	qcom,iommu-bfb-data =  <0x7FFFFFF
+				0x4
+				0x8
+				0x0
+				0x13607
+				0x4201
+				0x14221
+				0x0
+				0x0
+				0x94
+				0x114
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0
+				0x0>;
+
+	venus_ns: qcom,iommu-ctx@fdc8c000 {
+		qcom,iommu-ctx-sids = <0 1 2 3 4 5 7>;
+	};
+
+	venus_sec_bitstream: qcom,iommu-ctx@fdc8d000 {
+		qcom,iommu-ctx-sids = <0x80 0x81 0x82 0x83 0x84>;
+		label = "venus_sec_bitstream";
+	};
+
+	venus_sec_pixel: qcom,iommu-ctx@fdc8f000 {
+		compatible = "qcom,msm-smmu-v1-ctx";
+		reg = <0xfdc8f000 0x1000>;
+		interrupts = <0 42 0>;
+		qcom,iommu-ctx-sids = <0x85>;
+		label = "venus_sec_pixel";
+		qcom,secure-context;
+	};
+
+	venus_sec_non_pixel: qcom,iommu-ctx@fdc90000 {
+		compatible = "qcom,msm-smmu-v1-ctx";
+		reg = <0xfdc90000 0x1000>;
+		interrupts = <0 42 0>;
+		qcom,iommu-ctx-sids = <0x87 0xA0>;
+		label = "venus_sec_non_pixel";
+		qcom,secure-context;
+	};
 };
 
 &kgsl_iommu {
 	status = "ok";
-	qcom,needs-alt-core-clk;
-	vdd-supply = <&gdsc_oxili_cx>;
-	qcom,alt-vdd-supply = <&gdsc_oxili_gx>;
-};
 
-&vfe_iommu {
-	status = "ok";
-	vdd-supply = <&gdsc_vfe>;
+	qcom,iommu-bfb-regs =  <0x204c
+				0x2514
+				0x2540
+				0x256c
+				0x20ac
+				0x215c
+				0x220c
+				0x22bc
+				0x2314
+				0x2394
+				0x2414
+				0x2494
+				0x2008
+				0x2600
+				0x2604
+				0x2608
+				0x260c
+				0x2610
+				0x2614
+				0x2618
+				0x261c
+				0x2620
+				0x2624
+				0x2628
+				0x262c>;
+
+	qcom,iommu-bfb-data =  <0x3
+				0x8
+				0x10
+				0x0
+				0x0
+				0x0
+				0x20
+				0x0
+				0x0
+				0x1
+				0x101
+				0x0
+				0x0
+				0x7
+				0x4
+				0x8
+				0x14
+				0x0
+				0x0
+				0xc
+				0x6c
+				0x0
+				0x8
+				0x10
+				0x0>;
 };
diff --git a/arch/arm/boot/dts/msm-gdsc.dtsi b/arch/arm/boot/dts/msm-gdsc.dtsi
index 78234e8..495f65a 100644
--- a/arch/arm/boot/dts/msm-gdsc.dtsi
+++ b/arch/arm/boot/dts/msm-gdsc.dtsi
@@ -19,6 +19,27 @@
 		status = "disabled";
 	};
 
+	gdsc_venus_core0: qcom,gdsc@fd8c1040 {
+		compatible = "qcom,gdsc";
+		regulator-name = "gdsc_venus_core0";
+		reg = <0xfd8c1040 0x4>;
+		status = "disabled";
+	};
+
+	gdsc_venus_core1: qcom,gdsc@fd8c1044 {
+		compatible = "qcom,gdsc";
+		regulator-name = "gdsc_venus_core1";
+		reg = <0xfd8c1044 0x4>;
+		status = "disabled";
+	};
+
+	gdsc_vpu: qcom,gdsc@fd8c1404 {
+		compatible = "qcom,gdsc";
+		regulator-name = "gdsc_vpu";
+		reg = <0xfd8c1404 0x4>;
+		status = "disabled";
+	};
+
 	gdsc_mdss: qcom,gdsc@fd8c2304 {
 		compatible = "qcom,gdsc";
 		regulator-name = "gdsc_mdss";
@@ -60,4 +81,32 @@
 		reg = <0xfc400404 0x4>;
 		status = "disabled";
 	};
+
+	gdsc_pcie_0: qcom,gdsc@fc401ac4 {
+		compatible = "qcom,gdsc";
+		regulator-name = "gdsc_pcie_0";
+		reg = <0xfc401ac4 0x4>;
+		status = "disabled";
+	};
+
+	gdsc_pcie_1: qcom,gdsc@fc401b44 {
+		compatible = "qcom,gdsc";
+		regulator-name = "gdsc_pcie_1";
+		reg = <0xfc401b44 0x4>;
+		status = "disabled";
+	};
+
+	gdsc_usb30: qcom,gdsc@fc401e84 {
+		compatible = "qcom,gdsc";
+		regulator-name = "gdsc_usb30";
+		reg = <0xfc401e84 0x4>;
+		status = "disabled";
+	};
+
+	gdsc_usb30_sec: qcom,gdsc@fc401ec0 {
+		compatible = "qcom,gdsc";
+		regulator-name = "gdsc_usb30_sec";
+		reg = <0xfc401ec0 0x4>;
+		status = "disabled";
+	};
 };
diff --git a/arch/arm/boot/dts/msm-pm8226-rpm-regulator.dtsi b/arch/arm/boot/dts/msm-pm8226-rpm-regulator.dtsi
index ded9494..1ee7076 100644
--- a/arch/arm/boot/dts/msm-pm8226-rpm-regulator.dtsi
+++ b/arch/arm/boot/dts/msm-pm8226-rpm-regulator.dtsi
@@ -427,6 +427,22 @@
 		};
 	};
 
+	rpm-regulator-ldoa25 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <25>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l25 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8226_l25";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
 	rpm-regulator-ldoa26 {
 		compatible = "qcom,rpm-regulator-smd-resource";
 		qcom,resource-name = "ldoa";
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 40f9a7c..fc828b7 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -15,1383 +15,1381 @@
 	#size-cells = <0>;
 	interrupt-controller;
 	#interrupt-cells = <3>;
+};
 
-	qcom,pm8941@0 {
-		spmi-slave-container;
-		reg = <0x0>;
-		#address-cells = <1>;
-		#size-cells = <1>;
+&pm8941_lsid0 {
+	spmi-slave-container;
+	#address-cells = <1>;
+	#size-cells = <1>;
 
-		pm8941_misc: qcom,misc@900 {
-			compatible = "qcom,qpnp-misc";
-			reg = <0x900 0x100>;
+	pm8941_misc: qcom,misc@900 {
+		compatible = "qcom,qpnp-misc";
+		reg = <0x900 0x100>;
+	};
+
+	qcom,revid@100 {
+		compatible = "qcom,qpnp-revid";
+		reg = <0x100 0x100>;
+	};
+
+	qcom,temp-alarm@2400 {
+		compatible = "qcom,qpnp-temp-alarm";
+		reg = <0x2400 0x100>;
+		interrupts = <0x0 0x24 0x0>;
+		label = "pm8941_tz";
+		qcom,channel-num = <8>;
+		qcom,threshold-set = <0>;
+	};
+
+	qcom,power-on@800 {
+		compatible = "qcom,qpnp-power-on";
+		reg = <0x800 0x100>;
+		interrupts = <0x0 0x8 0x0>,
+			     <0x0 0x8 0x1>,
+			     <0x0 0x8 0x4>,
+			     <0x0 0x8 0x5>;
+		interrupt-names = "kpdpwr", "resin",
+				"resin-bark", "kpdpwr-resin-bark";
+		qcom,pon-dbc-delay = <15625>;
+		qcom,system-reset;
+		qcom,s3-debounce = <32>;
+
+		qcom,pon_1 {
+			qcom,pon-type = <0>;
+			qcom,pull-up = <1>;
+			linux,code = <116>;
 		};
 
-		qcom,revid@100 {
-			compatible = "qcom,qpnp-revid";
-			reg = <0x100 0x100>;
+		qcom,pon_2 {
+			qcom,pon-type = <1>;
+			qcom,support-reset = <1>;
+			qcom,pull-up = <1>;
+			qcom,s1-timer = <0>;
+			qcom,s2-timer = <2000>;
+			qcom,s2-type = <1>;
+			linux,code = <114>;
 		};
 
-		qcom,temp-alarm@2400 {
-			compatible = "qcom,qpnp-temp-alarm";
-			reg = <0x2400 0x100>;
-			interrupts = <0x0 0x24 0x0>;
-			label = "pm8941_tz";
-			qcom,channel-num = <8>;
-			qcom,threshold-set = <0>;
-		};
-
-		qcom,power-on@800 {
-			compatible = "qcom,qpnp-power-on";
-			reg = <0x800 0x100>;
-			interrupts = <0x0 0x8 0x0>,
-				     <0x0 0x8 0x1>,
-				     <0x0 0x8 0x4>,
-				     <0x0 0x8 0x5>;
-			interrupt-names = "kpdpwr", "resin",
-					"resin-bark", "kpdpwr-resin-bark";
-			qcom,pon-dbc-delay = <15625>;
-			qcom,system-reset;
-			qcom,s3-debounce = <32>;
-
-			qcom,pon_1 {
-				qcom,pon-type = <0>;
-				qcom,pull-up = <1>;
-				linux,code = <116>;
-			};
-
-			qcom,pon_2 {
-				qcom,pon-type = <1>;
-				qcom,support-reset = <1>;
-				qcom,pull-up = <1>;
-				qcom,s1-timer = <0>;
-				qcom,s2-timer = <2000>;
-				qcom,s2-type = <1>;
-				linux,code = <114>;
-			};
-
-			qcom,pon_3 {
-				qcom,pon-type = <3>;
-				qcom,support-reset = <1>;
-				qcom,s1-timer = <6720>;
-				qcom,s2-timer = <2000>;
-				qcom,s2-type = <7>;
-				qcom,pull-up = <1>;
-			};
-		};
-
-		bif_ctrl: qcom,bsi@1b00 {
-			compatible = "qcom,qpnp-bsi";
-			reg = <0x1b00 0x100>,
-			      <0x1208 0x1>;
-			reg-names = "bsi-base", "batt-id-status";
-			label = "pm8941-bsi";
-			interrupts = <0x0 0x1b 0x0>,
-				     <0x0 0x1b 0x1>,
-				     <0x0 0x1b 0x2>,
-				     <0x0 0x12 0x0>;
-			interrupt-names = "err",
-					  "rx",
-					  "tx",
-					  "batt-present";
-			qcom,channel-num = <0x31>;
-			qcom,pullup-ohms = <100000>;
-			qcom,vref-microvolts = <1800000>;
-			qcom,min-clock-period = <1000>;
-			qcom,max-clock-period = <160000>;
-			qcom,sample-rate = <4>;
-		};
-
-		pm8941_coincell: qcom,coincell@2800 {
-			compatible = "qcom,qpnp-coincell";
-			reg = <0x2800 0x100>;
-		};
-
-		pm8941_bms: qcom,bms {
-			spmi-dev-container;
-			compatible = "qcom,qpnp-bms";
-			#address-cells = <1>;
-			#size-cells = <1>;
-			status = "disabled";
-
-			qcom,r-sense-uohm = <10000>;
-			qcom,v-cutoff-uv = <3400000>;
-			qcom,max-voltage-uv = <4200000>;
-			qcom,r-conn-mohm = <0>;
-			qcom,shutdown-soc-valid-limit = <20>;
-			qcom,adjust-soc-low-threshold = <15>;
-			qcom,ocv-voltage-high-threshold-uv = <3750000>;
-			qcom,ocv-voltage-low-threshold-uv = <3650000>;
-			qcom,low-soc-calculate-soc-threshold = <15>;
-			qcom,low-soc-calculate-soc-ms = <5000>;
-			qcom,calculate-soc-ms = <20000>;
-			qcom,chg-term-ua = <100000>;
-			qcom,batt-type = <0>;
-			qcom,low-voltage-threshold = <3420000>;
-			qcom,tm-temp-margin = <5000>;
-			qcom,low-ocv-correction-limit-uv = <100>;
-			qcom,high-ocv-correction-limit-uv = <50>;
-			qcom,hold-soc-est = <3>;
-
-			qcom,bms-iadc@3800 {
-				reg = <0x3800 0x100>;
-			};
-
-			qcom,bms-bms@4000 {
-				reg = <0x4000 0x100>;
-				interrupts =	<0x0 0x40 0x0>,
-						<0x0 0x40 0x1>,
-						<0x0 0x40 0x2>,
-						<0x0 0x40 0x3>,
-						<0x0 0x40 0x4>,
-						<0x0 0x40 0x5>,
-						<0x0 0x40 0x6>,
-						<0x0 0x40 0x7>;
-
-				interrupt-names = "cc_thr",
-						  "ocv_for_r",
-						  "good_ocv",
-						  "charge_begin",
-						  "ocv_thr",
-						  "sw_cc_thr",
-						  "vsense_avg",
-						  "vsense_for_r";
-
-			};
-		};
-
-		clkdiv@5b00 {
-			reg = <0x5b00 0x100>;
-			compatible = "qcom,qpnp-clkdiv";
-			qcom,cxo-freq = <19200000>;
-		};
-
-		clkdiv@5c00 {
-			reg = <0x5c00 0x100>;
-			compatible = "qcom,qpnp-clkdiv";
-			qcom,cxo-freq = <19200000>;
-		};
-
-		clkdiv@5d00 {
-			reg = <0x5d00 0x1000>;
-			compatible = "qcom,qpnp-clkdiv";
-			qcom,cxo-freq = <19200000>;
-		};
-
-		pm8941_chg: qcom,charger {
-			spmi-dev-container;
-			compatible = "qcom,qpnp-charger";
-			#address-cells = <1>;
-			#size-cells = <1>;
-			status = "disabled";
-
-			qcom,vddmax-mv = <4200>;
-			qcom,vddsafe-mv = <4230>;
-			qcom,vinmin-mv = <4300>;
-			qcom,ibatmax-ma = <1500>;
-			qcom,ibatterm-ma = <100>;
-			qcom,ibatsafe-ma = <1500>;
-			qcom,thermal-mitigation = <1500 700 600 325>;
-			qcom,cool-bat-decidegc = <100>;
-			qcom,cool-bat-mv = <4100>;
-			qcom,ibatmax-warm-ma = <350>;
-			qcom,warm-bat-decidegc = <450>;
-			qcom,warm-bat-mv = <4100>;
-			qcom,ibatmax-cool-ma = <350>;
-			qcom,vbatdet-delta-mv = <100>;
-			qcom,tchg-mins = <150>;
-
-			qcom,chgr@1000 {
-				status = "disabled";
-				reg = <0x1000 0x100>;
-				interrupts =	<0x0 0x10 0x0>,
-						<0x0 0x10 0x1>,
-						<0x0 0x10 0x2>,
-						<0x0 0x10 0x3>,
-						<0x0 0x10 0x4>,
-						<0x0 0x10 0x5>,
-						<0x0 0x10 0x6>,
-						<0x0 0x10 0x7>;
-
-				interrupt-names =	"vbat-det-lo",
-							"vbat-det-hi",
-							"chgwdog",
-							"state-change",
-							"trkl-chg-on",
-							"fast-chg-on",
-							"chg-failed",
-							"chg-done";
-			};
-
-			qcom,buck@1100 {
-				status = "disabled";
-				reg = <0x1100 0x100>;
-				interrupts =	<0x0 0x11 0x0>,
-						<0x0 0x11 0x1>,
-						<0x0 0x11 0x2>,
-						<0x0 0x11 0x3>,
-						<0x0 0x11 0x4>,
-						<0x0 0x11 0x5>,
-						<0x0 0x11 0x6>;
-
-				interrupt-names =	"vbat-ov",
-							"vreg-ov",
-							"overtemp",
-							"vchg-loop",
-							"ichg-loop",
-							"ibat-loop",
-							"vdd-loop";
-			};
-
-			qcom,bat-if@1200 {
-				status = "disabled";
-				reg = <0x1200 0x100>;
-				interrupts =	<0x0 0x12 0x0>,
-						<0x0 0x12 0x1>,
-						<0x0 0x12 0x2>,
-						<0x0 0x12 0x3>,
-						<0x0 0x12 0x4>;
-
-				interrupt-names =	"batt-pres",
-							"bat-temp-ok",
-							"bat-fet-on",
-							"vcp-on",
-							"psi";
-
-			};
-
-			pm8941_chg_otg: qcom,usb-chgpth@1300 {
-				status = "disabled";
-				reg = <0x1300 0x100>;
-				interrupts =	<0 0x13 0x0>,
-						<0 0x13 0x1>,
-						<0x0 0x13 0x2>;
-
-				interrupt-names =	"coarse-det-usb",
-							"usbin-valid",
-							"chg-gone";
-			};
-
-			qcom,dc-chgpth@1400 {
-				status = "disabled";
-				reg = <0x1400 0x100>;
-				interrupts =	<0x0 0x14 0x0>,
-						<0x0 0x14 0x1>;
-
-				interrupt-names =	"coarse-det-dc",
-							"dcin-valid";
-			};
-
-			pm8941_chg_boost: qcom,boost@1500 {
-				status = "disabled";
-				reg = <0x1500 0x100>;
-				interrupts =	<0x0 0x15 0x0>,
-						<0x0 0x15 0x1>;
-
-				interrupt-names =	"boost-pwr-ok",
-							"limit-error";
-			};
-
-			qcom,chg-misc@1600 {
-				status = "disabled";
-				reg = <0x1600 0x100>;
-			};
-		};
-
-		pm8941_gpios: gpios {
-			spmi-dev-container;
-			compatible = "qcom,qpnp-pin";
-			gpio-controller;
-			#gpio-cells = <2>;
-			#address-cells = <1>;
-			#size-cells = <1>;
-			label = "pm8941-gpio";
-
-			gpio@c000 {
-				reg = <0xc000 0x100>;
-				qcom,pin-num = <1>;
-			};
-
-			gpio@c100 {
-				reg = <0xc100 0x100>;
-				qcom,pin-num = <2>;
-			};
-
-			gpio@c200 {
-				reg = <0xc200 0x100>;
-				qcom,pin-num = <3>;
-			};
-
-			gpio@c300 {
-				reg = <0xc300 0x100>;
-				qcom,pin-num = <4>;
-			};
-
-			gpio@c400 {
-				reg = <0xc400 0x100>;
-				qcom,pin-num = <5>;
-			};
-
-			gpio@c500 {
-				reg = <0xc500 0x100>;
-				qcom,pin-num = <6>;
-			};
-
-			gpio@c600 {
-				reg = <0xc600 0x100>;
-				qcom,pin-num = <7>;
-			};
-
-			gpio@c700 {
-				reg = <0xc700 0x100>;
-				qcom,pin-num = <8>;
-			};
-
-			gpio@c800 {
-				reg = <0xc800 0x100>;
-				qcom,pin-num = <9>;
-			};
-
-			gpio@c900 {
-				reg = <0xc900 0x100>;
-				qcom,pin-num = <10>;
-			};
-
-			gpio@ca00 {
-				reg = <0xca00 0x100>;
-				qcom,pin-num = <11>;
-			};
-
-			gpio@cb00 {
-				reg = <0xcb00 0x100>;
-				qcom,pin-num = <12>;
-			};
-
-			gpio@cc00 {
-				reg = <0xcc00 0x100>;
-				qcom,pin-num = <13>;
-			};
-
-			gpio@cd00 {
-				reg = <0xcd00 0x100>;
-				qcom,pin-num = <14>;
-			};
-
-			gpio@ce00 {
-				reg = <0xce00 0x100>;
-				qcom,pin-num = <15>;
-			};
-
-			gpio@cf00 {
-				reg = <0xcf00 0x100>;
-				qcom,pin-num = <16>;
-			};
-
-			gpio@d000 {
-				reg = <0xd000 0x100>;
-				qcom,pin-num = <17>;
-			};
-
-			gpio@d100 {
-				reg = <0xd100 0x100>;
-				qcom,pin-num = <18>;
-			};
-
-			gpio@d200 {
-				reg = <0xd200 0x100>;
-				qcom,pin-num = <19>;
-			};
-
-			gpio@d300 {
-				reg = <0xd300 0x100>;
-				qcom,pin-num = <20>;
-			};
-
-			gpio@d400 {
-				reg = <0xd400 0x100>;
-				qcom,pin-num = <21>;
-			};
-
-			gpio@d500 {
-				reg = <0xd500 0x100>;
-				qcom,pin-num = <22>;
-			};
-
-			gpio@d600 {
-				reg = <0xd600 0x100>;
-				qcom,pin-num = <23>;
-			};
-
-			gpio@d700 {
-				reg = <0xd700 0x100>;
-				qcom,pin-num = <24>;
-			};
-
-			gpio@d800 {
-				reg = <0xd800 0x100>;
-				qcom,pin-num = <25>;
-			};
-
-			gpio@d900 {
-				reg = <0xd900 0x100>;
-				qcom,pin-num = <26>;
-			};
-
-			gpio@da00 {
-				reg = <0xda00 0x100>;
-				qcom,pin-num = <27>;
-			};
-
-			gpio@db00 {
-				reg = <0xdb00 0x100>;
-				qcom,pin-num = <28>;
-			};
-
-			gpio@dc00 {
-				reg = <0xdc00 0x100>;
-				qcom,pin-num = <29>;
-			};
-
-			gpio@dd00 {
-				reg = <0xdd00 0x100>;
-				qcom,pin-num = <30>;
-			};
-
-			gpio@de00 {
-				reg = <0xde00 0x100>;
-				qcom,pin-num = <31>;
-			};
-
-			gpio@df00 {
-				reg = <0xdf00 0x100>;
-				qcom,pin-num = <32>;
-			};
-
-			gpio@e000 {
-				reg = <0xe000 0x100>;
-				qcom,pin-num = <33>;
-			};
-
-			gpio@e100 {
-				reg = <0xe100 0x100>;
-				qcom,pin-num = <34>;
-			};
-
-			gpio@e200 {
-				reg = <0xe200 0x100>;
-				qcom,pin-num = <35>;
-			};
-
-			gpio@e300 {
-				reg = <0xe300 0x100>;
-				qcom,pin-num = <36>;
-			};
-		};
-
-		pm8941_mpps: mpps {
-			spmi-dev-container;
-			compatible = "qcom,qpnp-pin";
-			gpio-controller;
-			#gpio-cells = <2>;
-			#address-cells = <1>;
-			#size-cells = <1>;
-			label = "pm8941-mpp";
-
-			mpp@a000 {
-				reg = <0xa000 0x100>;
-				qcom,pin-num = <1>;
-			};
-
-			mpp@a100 {
-				reg = <0xa100 0x100>;
-				qcom,pin-num = <2>;
-			};
-
-			mpp@a200 {
-				reg = <0xa200 0x100>;
-				qcom,pin-num = <3>;
-			};
-
-			mpp@a300 {
-				reg = <0xa300 0x100>;
-				qcom,pin-num = <4>;
-			};
-
-			mpp@a400 {
-				reg = <0xa400 0x100>;
-				qcom,pin-num = <5>;
-			};
-
-			mpp@a500 {
-				reg = <0xa500 0x100>;
-				qcom,pin-num = <6>;
-			};
-
-			mpp@a600 {
-				reg = <0xa600 0x100>;
-				qcom,pin-num = <7>;
-			};
-
-			mpp@a700 {
-				reg = <0xa700 0x100>;
-				qcom,pin-num = <8>;
-			};
-		};
-
-		qcom,pm8941_rtc {
-			spmi-dev-container;
-			compatible = "qcom,qpnp-rtc";
-			#address-cells = <1>;
-			#size-cells = <1>;
-			qcom,qpnp-rtc-write = <0>;
-			qcom,qpnp-rtc-alarm-pwrup = <0>;
-
-			qcom,pm8941_rtc_rw@6000 {
-				reg = <0x6000 0x100>;
-			};
-			qcom,pm8941_rtc_alarm@6100 {
-				reg = <0x6100 0x100>;
-				interrupts = <0x0 0x61 0x1>;
-			};
-		};
-
-		pm8941_vadc: vadc@3100 {
-			compatible = "qcom,qpnp-vadc";
-			reg = <0x3100 0x100>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			interrupts = <0x0 0x31 0x0>;
-			interrupt-names = "eoc-int-en-set";
-			qcom,adc-bit-resolution = <15>;
-			qcom,adc-vdd-reference = <1800>;
-
-			chan@0 {
-				label = "usb_in";
-				reg = <0>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <4>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@1 {
-				label = "dc_in";
-				reg = <1>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <4>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@2 {
-				label = "vchg_sns";
-				reg = <2>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <3>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@3 {
-				label = "spare1_div3";
-				reg = <3>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <1>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@4 {
-				label = "usb_id_mv";
-				reg = <4>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <1>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@5 {
-				label = "vcoin";
-				reg = <5>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <1>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@6 {
-				label = "vbat_sns";
-				reg = <6>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <1>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@7 {
-				label = "vph_pwr";
-				reg = <7>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <1>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@8 {
-				label = "die_temp";
-				reg = <8>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <3>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@9 {
-				label = "ref_625mv";
-				reg = <9>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@a {
-				label = "ref_1250v";
-				reg = <0xa>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@30 {
-				label = "batt_therm";
-				reg = <0x30>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <1>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@31 {
-				label = "batt_id";
-				reg = <0x31>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@b2 {
-				label = "xo_therm_pu2";
-				reg = <0xb2>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <4>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@b3 {
-				label = "msm_therm";
-				reg = <0xb3>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@b4 {
-				label = "emmc_therm";
-				reg = <0xb4>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@b5 {
-				label = "pa_therm0";
-				reg = <0xb5>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@b7 {
-				label = "pa_therm1";
-				reg = <0xb7>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@b8 {
-				label = "quiet_therm";
-				reg = <0xb8>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@b9 {
-				label = "usb_id";
-				reg = <0xb9>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <0>;
-			};
-
-			chan@39 {
-				label = "usb_id_nopull";
-				reg = <0x39>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <0>;
-			};
-		};
-
-		pm8941_iadc: iadc@3600 {
-			compatible = "qcom,qpnp-iadc";
-			reg = <0x3600 0x100>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			interrupts = <0x0 0x36 0x0>;
-			interrupt-names = "eoc-int-en-set";
-			qcom,adc-bit-resolution = <16>;
-			qcom,adc-vdd-reference = <1800>;
-
-			chan@0 {
-				label = "internal_rsense";
-				reg = <0>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <1>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <0>;
-			};
-		};
-
-		pm8941_adc_tm: qcom,vadc@3400 {
-			compatible = "qcom,qpnp-adc-tm";
-			reg = <0x3400 0x100>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			interrupts =	<0x0 0x34 0x0>,
-					<0x0 0x34 0x3>,
-				     <0x0 0x34 0x4>;
-			interrupt-names =	"eoc-int-en-set",
-						"high-thr-en-set",
-						"low-thr-en-set";
-			qcom,adc-bit-resolution = <15>;
-			qcom,adc-vdd-reference = <1800>;
-
-			/* Channel Node */
-			chan@b9 {
-				label = "usb_id";
-				reg = <0xb9>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <3>;
-				qcom,btm-channel-number = <0x48>;
-			};
-
-			chan@30 {
-				label = "batt_therm";
-				reg = <0x30>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <1>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <3>;
-				qcom,btm-channel-number = <0x68>;
-			};
-
-			chan@8 {
-				label = "die_temp";
-				reg = <8>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <3>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <3>;
-				qcom,btm-channel-number = <0x70>;
-			};
-
-			chan@6 {
-				label = "vbat_sns";
-				reg = <6>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <1>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
-				qcom,fast-avg-setup = <3>;
-				qcom,btm-channel-number = <0x78>;
-			};
-
-			chan@b5 {
-				label = "pa_therm0";
-				reg = <0xb5>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <3>;
-				qcom,btm-channel-number = <0x80>;
-				qcom,thermal-node;
-			};
-
-			chan@b7 {
-				label = "pa_therm1";
-				reg = <0xb7>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <3>;
-				qcom,btm-channel-number = <0x88>;
-				qcom,thermal-node;
-			};
-
-			chan@b4 {
-				label = "emmc_therm";
-				reg = <0xb4>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <3>;
-				qcom,btm-channel-number = <0x90>;
-				qcom,thermal-node;
-			};
-
-			chan@b3 {
-				label = "msm_therm";
-				reg = <0xb3>;
-				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <0>;
-				qcom,calibration-type = "ratiometric";
-				qcom,scale-function = <2>;
-				qcom,hw-settle-time = <2>;
-				qcom,fast-avg-setup = <3>;
-				qcom,btm-channel-number = <0x98>;
-				qcom,thermal-node;
-			};
+		qcom,pon_3 {
+			qcom,pon-type = <3>;
+			qcom,support-reset = <1>;
+			qcom,s1-timer = <6720>;
+			qcom,s2-timer = <2000>;
+			qcom,s2-type = <7>;
+			qcom,pull-up = <1>;
 		};
 	};
 
-	qcom,pm8941@1 {
-		spmi-slave-container;
-		reg = <0x1>;
+	bif_ctrl: qcom,bsi@1b00 {
+		compatible = "qcom,qpnp-bsi";
+		reg = <0x1b00 0x100>,
+		      <0x1208 0x1>;
+		reg-names = "bsi-base", "batt-id-status";
+		label = "pm8941-bsi";
+		interrupts = <0x0 0x1b 0x0>,
+			     <0x0 0x1b 0x1>,
+			     <0x0 0x1b 0x2>,
+			     <0x0 0x12 0x0>;
+		interrupt-names = "err",
+				  "rx",
+				  "tx",
+				  "batt-present";
+		qcom,channel-num = <0x31>;
+		qcom,pullup-ohms = <100000>;
+		qcom,vref-microvolts = <1800000>;
+		qcom,min-clock-period = <1000>;
+		qcom,max-clock-period = <160000>;
+		qcom,sample-rate = <4>;
+	};
+
+	pm8941_coincell: qcom,coincell@2800 {
+		compatible = "qcom,qpnp-coincell";
+		reg = <0x2800 0x100>;
+	};
+
+	pm8941_bms: qcom,bms {
+		spmi-dev-container;
+		compatible = "qcom,qpnp-bms";
 		#address-cells = <1>;
 		#size-cells = <1>;
+		status = "disabled";
 
-		regulator@1400 {
-			regulator-name = "8941_s1";
-			spmi-dev-container;
-			#address-cells = <1>;
-			#size-cells = <1>;
-			compatible = "qcom,qpnp-regulator";
-			reg = <0x1400 0x300>;
-			status = "disabled";
+		qcom,r-sense-uohm = <10000>;
+		qcom,v-cutoff-uv = <3400000>;
+		qcom,max-voltage-uv = <4200000>;
+		qcom,r-conn-mohm = <0>;
+		qcom,shutdown-soc-valid-limit = <20>;
+		qcom,adjust-soc-low-threshold = <15>;
+		qcom,ocv-voltage-high-threshold-uv = <3750000>;
+		qcom,ocv-voltage-low-threshold-uv = <3650000>;
+		qcom,low-soc-calculate-soc-threshold = <15>;
+		qcom,low-soc-calculate-soc-ms = <5000>;
+		qcom,calculate-soc-ms = <20000>;
+		qcom,chg-term-ua = <100000>;
+		qcom,batt-type = <0>;
+		qcom,low-voltage-threshold = <3420000>;
+		qcom,tm-temp-margin = <5000>;
+		qcom,low-ocv-correction-limit-uv = <100>;
+		qcom,high-ocv-correction-limit-uv = <50>;
+		qcom,hold-soc-est = <3>;
 
-			qcom,ctl@1400 {
-				reg = <0x1400 0x100>;
-			};
-			qcom,ps@1500 {
-				reg = <0x1500 0x100>;
-			};
-			qcom,freq@1600 {
-				reg = <0x1600 0x100>;
-			};
+		qcom,bms-iadc@3800 {
+			reg = <0x3800 0x100>;
 		};
 
-		regulator@1700 {
-			regulator-name = "8941_s2";
-			spmi-dev-container;
-			#address-cells = <1>;
-			#size-cells = <1>;
-			compatible = "qcom,qpnp-regulator";
-			reg = <0x1700 0x300>;
-			status = "disabled";
-
-			qcom,ctl@1700 {
-				reg = <0x1700 0x100>;
-			};
-			qcom,ps@1800 {
-				reg = <0x1800 0x100>;
-			};
-			qcom,freq@1900 {
-				reg = <0x1900 0x100>;
-			};
-		};
-
-		regulator@1a00 {
-			regulator-name = "8941_s3";
-			spmi-dev-container;
-			#address-cells = <1>;
-			#size-cells = <1>;
-			compatible = "qcom,qpnp-regulator";
-			reg = <0x1a00 0x300>;
-			status = "disabled";
-
-			qcom,ctl@1a00 {
-				reg = <0x1a00 0x100>;
-			};
-			qcom,ps@1b00 {
-				reg = <0x1b00 0x100>;
-			};
-			qcom,freq@1c00 {
-				reg = <0x1c00 0x100>;
-			};
-		};
-
-		regulator@a000 {
-			regulator-name = "8941_boost";
-			reg = <0xa000 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@4000 {
-			regulator-name = "8941_l1";
+		qcom,bms-bms@4000 {
 			reg = <0x4000 0x100>;
-			compatible = "qcom,qpnp-regulator";
+			interrupts =	<0x0 0x40 0x0>,
+					<0x0 0x40 0x1>,
+					<0x0 0x40 0x2>,
+					<0x0 0x40 0x3>,
+					<0x0 0x40 0x4>,
+					<0x0 0x40 0x5>,
+					<0x0 0x40 0x6>,
+					<0x0 0x40 0x7>;
+
+			interrupt-names = "cc_thr",
+					  "ocv_for_r",
+					  "good_ocv",
+					  "charge_begin",
+					  "ocv_thr",
+					  "sw_cc_thr",
+					  "vsense_avg",
+					  "vsense_for_r";
+		};
+	};
+
+	clkdiv@5b00 {
+		reg = <0x5b00 0x100>;
+		compatible = "qcom,qpnp-clkdiv";
+		qcom,cxo-freq = <19200000>;
+	};
+
+	clkdiv@5c00 {
+		reg = <0x5c00 0x100>;
+		compatible = "qcom,qpnp-clkdiv";
+		qcom,cxo-freq = <19200000>;
+	};
+
+	clkdiv@5d00 {
+		reg = <0x5d00 0x1000>;
+		compatible = "qcom,qpnp-clkdiv";
+		qcom,cxo-freq = <19200000>;
+	};
+
+	pm8941_chg: qcom,charger {
+		spmi-dev-container;
+		compatible = "qcom,qpnp-charger";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		status = "disabled";
+
+		qcom,vddmax-mv = <4200>;
+		qcom,vddsafe-mv = <4230>;
+		qcom,vinmin-mv = <4300>;
+		qcom,ibatmax-ma = <1500>;
+		qcom,ibatterm-ma = <100>;
+		qcom,ibatsafe-ma = <1500>;
+		qcom,thermal-mitigation = <1500 700 600 325>;
+		qcom,cool-bat-decidegc = <100>;
+		qcom,cool-bat-mv = <4100>;
+		qcom,ibatmax-warm-ma = <350>;
+		qcom,warm-bat-decidegc = <450>;
+		qcom,warm-bat-mv = <4100>;
+		qcom,ibatmax-cool-ma = <350>;
+		qcom,vbatdet-delta-mv = <100>;
+		qcom,resume-soc = <99>;
+		qcom,tchg-mins = <150>;
+
+		qcom,chgr@1000 {
 			status = "disabled";
+			reg = <0x1000 0x100>;
+			interrupts =	<0x0 0x10 0x0>,
+					<0x0 0x10 0x1>,
+					<0x0 0x10 0x2>,
+					<0x0 0x10 0x3>,
+					<0x0 0x10 0x4>,
+					<0x0 0x10 0x5>,
+					<0x0 0x10 0x6>,
+					<0x0 0x10 0x7>;
+
+			interrupt-names =	"vbat-det-lo",
+						"vbat-det-hi",
+						"chgwdog",
+						"state-change",
+						"trkl-chg-on",
+						"fast-chg-on",
+						"chg-failed",
+						"chg-done";
 		};
 
-		regulator@4100 {
-			regulator-name = "8941_l2";
-			reg = <0x4100 0x100>;
-			compatible = "qcom,qpnp-regulator";
+		qcom,buck@1100 {
 			status = "disabled";
+			reg = <0x1100 0x100>;
+			interrupts =	<0x0 0x11 0x0>,
+					<0x0 0x11 0x1>,
+					<0x0 0x11 0x2>,
+					<0x0 0x11 0x3>,
+					<0x0 0x11 0x4>,
+					<0x0 0x11 0x5>,
+					<0x0 0x11 0x6>;
+
+			interrupt-names =	"vbat-ov",
+						"vreg-ov",
+						"overtemp",
+						"vchg-loop",
+						"ichg-loop",
+						"ibat-loop",
+						"vdd-loop";
 		};
 
-		regulator@4200 {
-			regulator-name = "8941_l3";
-			reg = <0x4200 0x100>;
-			compatible = "qcom,qpnp-regulator";
+		qcom,bat-if@1200 {
 			status = "disabled";
+			reg = <0x1200 0x100>;
+			interrupts =	<0x0 0x12 0x0>,
+					<0x0 0x12 0x1>,
+					<0x0 0x12 0x2>,
+					<0x0 0x12 0x3>,
+					<0x0 0x12 0x4>;
+
+			interrupt-names =	"batt-pres",
+						"bat-temp-ok",
+						"bat-fet-on",
+						"vcp-on",
+						"psi";
+
 		};
 
-		regulator@4300 {
-			regulator-name = "8941_l4";
-			reg = <0x4300 0x100>;
-			compatible = "qcom,qpnp-regulator";
+		pm8941_chg_otg: qcom,usb-chgpth@1300 {
 			status = "disabled";
+			reg = <0x1300 0x100>;
+			interrupts =	<0 0x13 0x0>,
+					<0 0x13 0x1>,
+					<0x0 0x13 0x2>;
+
+			interrupt-names =	"coarse-det-usb",
+						"usbin-valid",
+						"chg-gone";
 		};
 
-		regulator@4400 {
-			regulator-name = "8941_l5";
-			reg = <0x4400 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			qcom,force-type = <0x04 0x10>;
+		qcom,dc-chgpth@1400 {
 			status = "disabled";
+			reg = <0x1400 0x100>;
+			interrupts =	<0x0 0x14 0x0>,
+					<0x0 0x14 0x1>;
+
+			interrupt-names =	"coarse-det-dc",
+						"dcin-valid";
 		};
 
-		regulator@4500 {
-			regulator-name = "8941_l6";
-			reg = <0x4500 0x100>;
-			compatible = "qcom,qpnp-regulator";
+		pm8941_chg_boost: qcom,boost@1500 {
 			status = "disabled";
+			reg = <0x1500 0x100>;
+			interrupts =	<0x0 0x15 0x0>,
+					<0x0 0x15 0x1>;
+
+			interrupt-names =	"boost-pwr-ok",
+						"limit-error";
 		};
 
-		regulator@4600 {
-			regulator-name = "8941_l7";
-			reg = <0x4600 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			qcom,force-type = <0x04 0x10>;
+		qcom,chg-misc@1600 {
 			status = "disabled";
+			reg = <0x1600 0x100>;
 		};
+	};
 
-		regulator@4700 {
-			regulator-name = "8941_l8";
-			reg = <0x4700 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
+	pm8941_gpios: gpios {
+		spmi-dev-container;
+		compatible = "qcom,qpnp-pin";
+		gpio-controller;
+		#gpio-cells = <2>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		label = "pm8941-gpio";
 
-		regulator@4800 {
-			regulator-name = "8941_l9";
-			reg = <0x4800 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@4900 {
-			regulator-name = "8941_l10";
-			reg = <0x4900 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@4a00 {
-			regulator-name = "8941_l11";
-			reg = <0x4a00 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@4b00 {
-			regulator-name = "8941_l12";
-			reg = <0x4b00 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@4c00 {
-			regulator-name = "8941_l13";
-			reg = <0x4c00 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@4d00 {
-			regulator-name = "8941_l14";
-			reg = <0x4d00 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@4e00 {
-			regulator-name = "8941_l15";
-			reg = <0x4e00 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@4f00 {
-			regulator-name = "8941_l16";
-			reg = <0x4f00 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@5000 {
-			regulator-name = "8941_l17";
-			reg = <0x5000 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@5100 {
-			regulator-name = "8941_l18";
-			reg = <0x5100 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@5200 {
-			regulator-name = "8941_l19";
-			reg = <0x5200 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@5300 {
-			regulator-name = "8941_l20";
-			reg = <0x5300 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@5400 {
-			regulator-name = "8941_l21";
-			reg = <0x5400 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@5500 {
-			regulator-name = "8941_l22";
-			reg = <0x5500 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@5600 {
-			regulator-name = "8941_l23";
-			reg = <0x5600 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@5700 {
-			regulator-name = "8941_l24";
-			reg = <0x5700 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@8000 {
-			regulator-name = "8941_lvs1";
-			reg = <0x8000 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@8100 {
-			regulator-name = "8941_lvs2";
-			reg = <0x8100 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@8200 {
-			regulator-name = "8941_lvs3";
-			reg = <0x8200 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@8300 {
-			regulator-name = "8941_mvs1";
-			reg = <0x8300 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		regulator@8400 {
-			regulator-name = "8941_mvs2";
-			reg = <0x8400 0x100>;
-			compatible = "qcom,qpnp-regulator";
-			status = "disabled";
-		};
-
-		qcom,vibrator@c000 {
-			compatible = "qcom,qpnp-vibrator";
+		gpio@c000 {
 			reg = <0xc000 0x100>;
-			label = "vibrator";
-			status = "disabled";
+			qcom,pin-num = <1>;
 		};
 
-		qcom,leds@d000 {
-			compatible = "qcom,leds-qpnp";
+		gpio@c100 {
+			reg = <0xc100 0x100>;
+			qcom,pin-num = <2>;
+		};
+
+		gpio@c200 {
+			reg = <0xc200 0x100>;
+			qcom,pin-num = <3>;
+		};
+
+		gpio@c300 {
+			reg = <0xc300 0x100>;
+			qcom,pin-num = <4>;
+		};
+
+		gpio@c400 {
+			reg = <0xc400 0x100>;
+			qcom,pin-num = <5>;
+		};
+
+		gpio@c500 {
+			reg = <0xc500 0x100>;
+			qcom,pin-num = <6>;
+		};
+
+		gpio@c600 {
+			reg = <0xc600 0x100>;
+			qcom,pin-num = <7>;
+		};
+
+		gpio@c700 {
+			reg = <0xc700 0x100>;
+			qcom,pin-num = <8>;
+		};
+
+		gpio@c800 {
+			reg = <0xc800 0x100>;
+			qcom,pin-num = <9>;
+		};
+
+		gpio@c900 {
+			reg = <0xc900 0x100>;
+			qcom,pin-num = <10>;
+		};
+
+		gpio@ca00 {
+			reg = <0xca00 0x100>;
+			qcom,pin-num = <11>;
+		};
+
+		gpio@cb00 {
+			reg = <0xcb00 0x100>;
+			qcom,pin-num = <12>;
+		};
+
+		gpio@cc00 {
+			reg = <0xcc00 0x100>;
+			qcom,pin-num = <13>;
+		};
+
+		gpio@cd00 {
+			reg = <0xcd00 0x100>;
+			qcom,pin-num = <14>;
+		};
+
+		gpio@ce00 {
+			reg = <0xce00 0x100>;
+			qcom,pin-num = <15>;
+		};
+
+		gpio@cf00 {
+			reg = <0xcf00 0x100>;
+			qcom,pin-num = <16>;
+		};
+
+		gpio@d000 {
 			reg = <0xd000 0x100>;
-			label = "rgb";
+			qcom,pin-num = <17>;
 		};
 
-		qcom,leds@d100 {
-			compatible = "qcom,leds-qpnp";
+		gpio@d100 {
 			reg = <0xd100 0x100>;
-			label = "rgb";
+			qcom,pin-num = <18>;
 		};
 
-		qcom,leds@d200 {
-			compatible = "qcom,leds-qpnp";
+		gpio@d200 {
 			reg = <0xd200 0x100>;
-			label = "rgb";
+			qcom,pin-num = <19>;
 		};
 
-		qcom,leds@d300 {
-			compatible = "qcom,leds-qpnp";
+		gpio@d300 {
 			reg = <0xd300 0x100>;
-			label = "flash";
-			flash_boost-supply = <&pm8941_chg_boost>;
+			qcom,pin-num = <20>;
 		};
 
-		qcom,leds@d400 {
-			compatible = "qcom,leds-qpnp";
+		gpio@d400 {
 			reg = <0xd400 0x100>;
-			label = "flash";
+			qcom,pin-num = <21>;
 		};
 
-		qcom,leds@d500 {
-			compatible = "qcom,leds-qpnp";
+		gpio@d500 {
 			reg = <0xd500 0x100>;
-			label = "flash";
+			qcom,pin-num = <22>;
 		};
 
-		qcom,leds@d600 {
-			compatible = "qcom,leds-qpnp";
+		gpio@d600 {
 			reg = <0xd600 0x100>;
-			label = "flash";
+			qcom,pin-num = <23>;
 		};
 
-		qcom,leds@d700 {
-			compatible = "qcom,leds-qpnp";
+		gpio@d700 {
 			reg = <0xd700 0x100>;
-			label = "flash";
+			qcom,pin-num = <24>;
 		};
 
-		qcom,leds@d800 {
-			compatible = "qcom,leds-qpnp";
+		gpio@d800 {
 			reg = <0xd800 0x100>;
-			label = "wled";
+			qcom,pin-num = <25>;
 		};
 
-		qcom,leds@d900 {
-			compatible = "qcom,leds-qpnp";
+		gpio@d900 {
 			reg = <0xd900 0x100>;
-			label = "wled";
+			qcom,pin-num = <26>;
 		};
 
-		qcom,leds@da00 {
-			compatible = "qcom,leds-qpnp";
+		gpio@da00 {
 			reg = <0xda00 0x100>;
-			label = "wled";
+			qcom,pin-num = <27>;
 		};
 
-		qcom,leds@db00 {
-			compatible = "qcom,leds-qpnp";
+		gpio@db00 {
 			reg = <0xdb00 0x100>;
-			label = "wled";
+			qcom,pin-num = <28>;
 		};
 
-		qcom,leds@dc00 {
-			compatible = "qcom,leds-qpnp";
+		gpio@dc00 {
 			reg = <0xdc00 0x100>;
-			label = "wled";
+			qcom,pin-num = <29>;
 		};
 
-		qcom,leds@dd00 {
-			compatible = "qcom,leds-qpnp";
+		gpio@dd00 {
 			reg = <0xdd00 0x100>;
-			label = "wled";
+			qcom,pin-num = <30>;
 		};
 
-		qcom,leds@de00 {
-			compatible = "qcom,leds-qpnp";
+		gpio@de00 {
 			reg = <0xde00 0x100>;
-			label = "wled";
+			qcom,pin-num = <31>;
 		};
 
-		qcom,leds@df00 {
-			compatible = "qcom,leds-qpnp";
+		gpio@df00 {
 			reg = <0xdf00 0x100>;
-			label = "wled";
+			qcom,pin-num = <32>;
 		};
 
-		qcom,leds@e000 {
-			compatible = "qcom,leds-qpnp";
+		gpio@e000 {
 			reg = <0xe000 0x100>;
-			label = "wled";
+			qcom,pin-num = <33>;
 		};
 
-		qcom,leds@e100 {
-			compatible = "qcom,leds-qpnp";
+		gpio@e100 {
 			reg = <0xe100 0x100>;
-			label = "wled";
+			qcom,pin-num = <34>;
 		};
 
-		pwm@b100 {
-			compatible = "qcom,qpnp-pwm";
-			reg = <0xb100 0x100>,
-			      <0xb042 0x7e>;
-			reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base";
-			qcom,channel-id = <0>;
+		gpio@e200 {
+			reg = <0xe200 0x100>;
+			qcom,pin-num = <35>;
 		};
 
-		pwm@b200 {
-			compatible = "qcom,qpnp-pwm";
-			reg = <0xb200 0x100>,
-			      <0xb042 0x7e>;
-			reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base";
-			qcom,channel-id = <1>;
+		gpio@e300 {
+			reg = <0xe300 0x100>;
+			qcom,pin-num = <36>;
+		};
+	};
+
+	pm8941_mpps: mpps {
+		spmi-dev-container;
+		compatible = "qcom,qpnp-pin";
+		gpio-controller;
+		#gpio-cells = <2>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		label = "pm8941-mpp";
+
+		mpp@a000 {
+			reg = <0xa000 0x100>;
+			qcom,pin-num = <1>;
 		};
 
-		pwm@b300 {
-			compatible = "qcom,qpnp-pwm";
-			reg = <0xb300 0x100>,
-			      <0xb042 0x7e>;
-			reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base";
-			qcom,channel-id = <2>;
+		mpp@a100 {
+			reg = <0xa100 0x100>;
+			qcom,pin-num = <2>;
 		};
 
-		pwm@b400 {
-			compatible = "qcom,qpnp-pwm";
-			reg = <0xb400 0x100>,
-			      <0xb042 0x7e>;
-			reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base";
-			qcom,channel-id = <3>;
+		mpp@a200 {
+			reg = <0xa200 0x100>;
+			qcom,pin-num = <3>;
 		};
 
-		pwm@b500 {
-			compatible = "qcom,qpnp-pwm";
-			reg = <0xb500 0x100>,
-			      <0xb042 0x7e>;
-			reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base";
-			qcom,channel-id = <4>;
+		mpp@a300 {
+			reg = <0xa300 0x100>;
+			qcom,pin-num = <4>;
 		};
 
-		pwm@b600 {
-			compatible = "qcom,qpnp-pwm";
-			reg = <0xb600 0x100>,
-			      <0xb042 0x7e>;
-			reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base";
-			qcom,channel-id = <5>;
+		mpp@a400 {
+			reg = <0xa400 0x100>;
+			qcom,pin-num = <5>;
 		};
 
-		pwm@b700 {
-			compatible = "qcom,qpnp-pwm";
-			reg = <0xb700 0x100>,
-			      <0xb042 0x7e>;
-			reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base";
-			qcom,channel-id = <6>;
+		mpp@a500 {
+			reg = <0xa500 0x100>;
+			qcom,pin-num = <6>;
 		};
 
-		pwm@b800 {
-			compatible = "qcom,qpnp-pwm";
-			reg = <0xb800 0x100>,
-			      <0xb042 0x7e>;
-			reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base";
-			qcom,channel-id = <7>;
+		mpp@a600 {
+			reg = <0xa600 0x100>;
+			qcom,pin-num = <7>;
 		};
+
+		mpp@a700 {
+			reg = <0xa700 0x100>;
+			qcom,pin-num = <8>;
+		};
+	};
+
+	qcom,pm8941_rtc {
+		spmi-dev-container;
+		compatible = "qcom,qpnp-rtc";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		qcom,qpnp-rtc-write = <0>;
+		qcom,qpnp-rtc-alarm-pwrup = <0>;
+
+		qcom,pm8941_rtc_rw@6000 {
+			reg = <0x6000 0x100>;
+		};
+		qcom,pm8941_rtc_alarm@6100 {
+			reg = <0x6100 0x100>;
+			interrupts = <0x0 0x61 0x1>;
+		};
+	};
+
+	pm8941_vadc: vadc@3100 {
+		compatible = "qcom,qpnp-vadc";
+		reg = <0x3100 0x100>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		interrupts = <0x0 0x31 0x0>;
+		interrupt-names = "eoc-int-en-set";
+		qcom,adc-bit-resolution = <15>;
+		qcom,adc-vdd-reference = <1800>;
+
+		chan@0 {
+			label = "usb_in";
+			reg = <0>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <4>;
+			qcom,calibration-type = "absolute";
+			qcom,scale-function = <0>;
+			qcom,hw-settle-time = <0>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@1 {
+			label = "dc_in";
+			reg = <1>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <4>;
+			qcom,calibration-type = "absolute";
+			qcom,scale-function = <0>;
+			qcom,hw-settle-time = <0>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@2 {
+			label = "vchg_sns";
+			reg = <2>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <3>;
+			qcom,calibration-type = "absolute";
+			qcom,scale-function = <0>;
+			qcom,hw-settle-time = <0>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@3 {
+			label = "spare1_div3";
+			reg = <3>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <1>;
+			qcom,calibration-type = "absolute";
+			qcom,scale-function = <0>;
+			qcom,hw-settle-time = <0>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@4 {
+			label = "usb_id_mv";
+			reg = <4>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <1>;
+			qcom,calibration-type = "absolute";
+			qcom,scale-function = <0>;
+			qcom,hw-settle-time = <0>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@5 {
+			label = "vcoin";
+			reg = <5>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <1>;
+			qcom,calibration-type = "absolute";
+			qcom,scale-function = <0>;
+			qcom,hw-settle-time = <0>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@6 {
+			label = "vbat_sns";
+			reg = <6>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <1>;
+			qcom,calibration-type = "absolute";
+			qcom,scale-function = <0>;
+			qcom,hw-settle-time = <0>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@7 {
+			label = "vph_pwr";
+			reg = <7>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <1>;
+			qcom,calibration-type = "absolute";
+			qcom,scale-function = <0>;
+			qcom,hw-settle-time = <0>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@8 {
+			label = "die_temp";
+			reg = <8>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "absolute";
+			qcom,scale-function = <3>;
+			qcom,hw-settle-time = <0>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@9 {
+			label = "ref_625mv";
+			reg = <9>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "absolute";
+			qcom,scale-function = <0>;
+			qcom,hw-settle-time = <0>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@a {
+			label = "ref_1250v";
+			reg = <0xa>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "absolute";
+			qcom,scale-function = <0>;
+			qcom,hw-settle-time = <0>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@30 {
+			label = "batt_therm";
+			reg = <0x30>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "ratiometric";
+			qcom,scale-function = <1>;
+			qcom,hw-settle-time = <2>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@31 {
+			label = "batt_id";
+			reg = <0x31>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "ratiometric";
+			qcom,scale-function = <0>;
+			qcom,hw-settle-time = <2>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@b2 {
+			label = "xo_therm_pu2";
+			reg = <0xb2>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "ratiometric";
+			qcom,scale-function = <4>;
+			qcom,hw-settle-time = <2>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@b3 {
+			label = "msm_therm";
+			reg = <0xb3>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "ratiometric";
+			qcom,scale-function = <2>;
+			qcom,hw-settle-time = <2>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@b4 {
+			label = "emmc_therm";
+			reg = <0xb4>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "ratiometric";
+			qcom,scale-function = <2>;
+			qcom,hw-settle-time = <2>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@b5 {
+			label = "pa_therm0";
+			reg = <0xb5>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "ratiometric";
+			qcom,scale-function = <2>;
+			qcom,hw-settle-time = <2>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@b7 {
+			label = "pa_therm1";
+			reg = <0xb7>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "ratiometric";
+			qcom,scale-function = <2>;
+			qcom,hw-settle-time = <2>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@b8 {
+			label = "quiet_therm";
+			reg = <0xb8>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "ratiometric";
+			qcom,scale-function = <2>;
+			qcom,hw-settle-time = <2>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@b9 {
+			label = "usb_id";
+			reg = <0xb9>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "ratiometric";
+			qcom,scale-function = <0>;
+			qcom,hw-settle-time = <2>;
+			qcom,fast-avg-setup = <0>;
+		};
+
+		chan@39 {
+			label = "usb_id_nopull";
+			reg = <0x39>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "ratiometric";
+			qcom,scale-function = <0>;
+			qcom,hw-settle-time = <2>;
+			qcom,fast-avg-setup = <0>;
+		};
+	};
+
+	pm8941_iadc: iadc@3600 {
+		compatible = "qcom,qpnp-iadc";
+		reg = <0x3600 0x100>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		interrupts = <0x0 0x36 0x0>;
+		interrupt-names = "eoc-int-en-set";
+		qcom,adc-bit-resolution = <16>;
+		qcom,adc-vdd-reference = <1800>;
+
+		chan@0 {
+			label = "internal_rsense";
+			reg = <0>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <1>;
+			qcom,calibration-type = "absolute";
+			qcom,scale-function = <0>;
+			qcom,hw-settle-time = <0>;
+			qcom,fast-avg-setup = <0>;
+		};
+	};
+
+	pm8941_adc_tm: qcom,vadc@3400 {
+		compatible = "qcom,qpnp-adc-tm";
+		reg = <0x3400 0x100>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		interrupts =	<0x0 0x34 0x0>,
+				<0x0 0x34 0x3>,
+			     <0x0 0x34 0x4>;
+		interrupt-names =	"eoc-int-en-set",
+					"high-thr-en-set",
+					"low-thr-en-set";
+		qcom,adc-bit-resolution = <15>;
+		qcom,adc-vdd-reference = <1800>;
+
+		/* Channel Node */
+		chan@b9 {
+			label = "usb_id";
+			reg = <0xb9>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "ratiometric";
+			qcom,scale-function = <2>;
+			qcom,hw-settle-time = <2>;
+			qcom,fast-avg-setup = <3>;
+			qcom,btm-channel-number = <0x48>;
+		};
+
+		chan@30 {
+			label = "batt_therm";
+			reg = <0x30>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "ratiometric";
+			qcom,scale-function = <1>;
+			qcom,hw-settle-time = <2>;
+			qcom,fast-avg-setup = <3>;
+			qcom,btm-channel-number = <0x68>;
+		};
+
+		chan@8 {
+			label = "die_temp";
+			reg = <8>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "absolute";
+			qcom,scale-function = <3>;
+			qcom,hw-settle-time = <0>;
+			qcom,fast-avg-setup = <3>;
+			qcom,btm-channel-number = <0x70>;
+		};
+
+		chan@6 {
+			label = "vbat_sns";
+			reg = <6>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <1>;
+			qcom,calibration-type = "absolute";
+			qcom,scale-function = <0>;
+			qcom,hw-settle-time = <0>;
+			qcom,fast-avg-setup = <3>;
+			qcom,btm-channel-number = <0x78>;
+		};
+
+		chan@b5 {
+			label = "pa_therm0";
+			reg = <0xb5>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "ratiometric";
+			qcom,scale-function = <2>;
+			qcom,hw-settle-time = <2>;
+			qcom,fast-avg-setup = <3>;
+			qcom,btm-channel-number = <0x80>;
+			qcom,thermal-node;
+		};
+
+		chan@b7 {
+			label = "pa_therm1";
+			reg = <0xb7>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "ratiometric";
+			qcom,scale-function = <2>;
+			qcom,hw-settle-time = <2>;
+			qcom,fast-avg-setup = <3>;
+			qcom,btm-channel-number = <0x88>;
+			qcom,thermal-node;
+		};
+
+		chan@b4 {
+			label = "emmc_therm";
+			reg = <0xb4>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "ratiometric";
+			qcom,scale-function = <2>;
+			qcom,hw-settle-time = <2>;
+			qcom,fast-avg-setup = <3>;
+			qcom,btm-channel-number = <0x90>;
+			qcom,thermal-node;
+		};
+
+		chan@b3 {
+			label = "msm_therm";
+			reg = <0xb3>;
+			qcom,decimation = <0>;
+			qcom,pre-div-channel-scaling = <0>;
+			qcom,calibration-type = "ratiometric";
+			qcom,scale-function = <2>;
+			qcom,hw-settle-time = <2>;
+			qcom,fast-avg-setup = <3>;
+			qcom,btm-channel-number = <0x98>;
+			qcom,thermal-node;
+		};
+	};
+};
+
+&pm8941_lsid1 {
+	spmi-slave-container;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	regulator@1400 {
+		regulator-name = "8941_s1";
+		spmi-dev-container;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "qcom,qpnp-regulator";
+		reg = <0x1400 0x300>;
+		status = "disabled";
+
+		qcom,ctl@1400 {
+			reg = <0x1400 0x100>;
+		};
+		qcom,ps@1500 {
+			reg = <0x1500 0x100>;
+		};
+		qcom,freq@1600 {
+			reg = <0x1600 0x100>;
+		};
+	};
+
+	regulator@1700 {
+		regulator-name = "8941_s2";
+		spmi-dev-container;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "qcom,qpnp-regulator";
+		reg = <0x1700 0x300>;
+		status = "disabled";
+
+		qcom,ctl@1700 {
+			reg = <0x1700 0x100>;
+		};
+		qcom,ps@1800 {
+			reg = <0x1800 0x100>;
+		};
+		qcom,freq@1900 {
+			reg = <0x1900 0x100>;
+		};
+	};
+
+	regulator@1a00 {
+		regulator-name = "8941_s3";
+		spmi-dev-container;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "qcom,qpnp-regulator";
+		reg = <0x1a00 0x300>;
+		status = "disabled";
+
+		qcom,ctl@1a00 {
+			reg = <0x1a00 0x100>;
+		};
+		qcom,ps@1b00 {
+			reg = <0x1b00 0x100>;
+		};
+		qcom,freq@1c00 {
+			reg = <0x1c00 0x100>;
+		};
+	};
+
+	regulator@a000 {
+		regulator-name = "8941_boost";
+		reg = <0xa000 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@4000 {
+		regulator-name = "8941_l1";
+		reg = <0x4000 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@4100 {
+		regulator-name = "8941_l2";
+		reg = <0x4100 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@4200 {
+		regulator-name = "8941_l3";
+		reg = <0x4200 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@4300 {
+		regulator-name = "8941_l4";
+		reg = <0x4300 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@4400 {
+		regulator-name = "8941_l5";
+		reg = <0x4400 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		qcom,force-type = <0x04 0x10>;
+		status = "disabled";
+	};
+
+	regulator@4500 {
+		regulator-name = "8941_l6";
+		reg = <0x4500 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@4600 {
+		regulator-name = "8941_l7";
+		reg = <0x4600 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		qcom,force-type = <0x04 0x10>;
+		status = "disabled";
+	};
+
+	regulator@4700 {
+		regulator-name = "8941_l8";
+		reg = <0x4700 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@4800 {
+		regulator-name = "8941_l9";
+		reg = <0x4800 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@4900 {
+		regulator-name = "8941_l10";
+		reg = <0x4900 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@4a00 {
+		regulator-name = "8941_l11";
+		reg = <0x4a00 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@4b00 {
+		regulator-name = "8941_l12";
+		reg = <0x4b00 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@4c00 {
+		regulator-name = "8941_l13";
+		reg = <0x4c00 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@4d00 {
+		regulator-name = "8941_l14";
+		reg = <0x4d00 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@4e00 {
+		regulator-name = "8941_l15";
+		reg = <0x4e00 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@4f00 {
+		regulator-name = "8941_l16";
+		reg = <0x4f00 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@5000 {
+		regulator-name = "8941_l17";
+		reg = <0x5000 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@5100 {
+		regulator-name = "8941_l18";
+		reg = <0x5100 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@5200 {
+		regulator-name = "8941_l19";
+		reg = <0x5200 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@5300 {
+		regulator-name = "8941_l20";
+		reg = <0x5300 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@5400 {
+		regulator-name = "8941_l21";
+		reg = <0x5400 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@5500 {
+		regulator-name = "8941_l22";
+		reg = <0x5500 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@5600 {
+		regulator-name = "8941_l23";
+		reg = <0x5600 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@5700 {
+		regulator-name = "8941_l24";
+		reg = <0x5700 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@8000 {
+		regulator-name = "8941_lvs1";
+		reg = <0x8000 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@8100 {
+		regulator-name = "8941_lvs2";
+		reg = <0x8100 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@8200 {
+		regulator-name = "8941_lvs3";
+		reg = <0x8200 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@8300 {
+		regulator-name = "8941_mvs1";
+		reg = <0x8300 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	regulator@8400 {
+		regulator-name = "8941_mvs2";
+		reg = <0x8400 0x100>;
+		compatible = "qcom,qpnp-regulator";
+		status = "disabled";
+	};
+
+	qcom,vibrator@c000 {
+		compatible = "qcom,qpnp-vibrator";
+		reg = <0xc000 0x100>;
+		label = "vibrator";
+		status = "disabled";
+	};
+
+	qcom,leds@d000 {
+		compatible = "qcom,leds-qpnp";
+		reg = <0xd000 0x100>;
+		label = "rgb";
+	};
+
+	qcom,leds@d100 {
+		compatible = "qcom,leds-qpnp";
+		reg = <0xd100 0x100>;
+		label = "rgb";
+	};
+
+	qcom,leds@d200 {
+		compatible = "qcom,leds-qpnp";
+		reg = <0xd200 0x100>;
+		label = "rgb";
+	};
+
+	qcom,leds@d300 {
+		compatible = "qcom,leds-qpnp";
+		reg = <0xd300 0x100>;
+		label = "flash";
+		flash_boost-supply = <&pm8941_chg_boost>;
+	};
+
+	qcom,leds@d400 {
+		compatible = "qcom,leds-qpnp";
+		reg = <0xd400 0x100>;
+		label = "flash";
+	};
+
+	qcom,leds@d500 {
+		compatible = "qcom,leds-qpnp";
+		reg = <0xd500 0x100>;
+		label = "flash";
+	};
+
+	qcom,leds@d600 {
+		compatible = "qcom,leds-qpnp";
+		reg = <0xd600 0x100>;
+		label = "flash";
+	};
+
+	qcom,leds@d700 {
+		compatible = "qcom,leds-qpnp";
+		reg = <0xd700 0x100>;
+		label = "flash";
+	};
+
+	qcom,leds@d800 {
+		compatible = "qcom,leds-qpnp";
+		reg = <0xd800 0x100>;
+		label = "wled";
+	};
+
+	qcom,leds@d900 {
+		compatible = "qcom,leds-qpnp";
+		reg = <0xd900 0x100>;
+		label = "wled";
+	};
+
+	qcom,leds@da00 {
+		compatible = "qcom,leds-qpnp";
+		reg = <0xda00 0x100>;
+		label = "wled";
+	};
+
+	qcom,leds@db00 {
+		compatible = "qcom,leds-qpnp";
+		reg = <0xdb00 0x100>;
+		label = "wled";
+	};
+
+	qcom,leds@dc00 {
+		compatible = "qcom,leds-qpnp";
+		reg = <0xdc00 0x100>;
+		label = "wled";
+	};
+
+	qcom,leds@dd00 {
+		compatible = "qcom,leds-qpnp";
+		reg = <0xdd00 0x100>;
+		label = "wled";
+	};
+
+	qcom,leds@de00 {
+		compatible = "qcom,leds-qpnp";
+		reg = <0xde00 0x100>;
+		label = "wled";
+	};
+
+	qcom,leds@df00 {
+		compatible = "qcom,leds-qpnp";
+		reg = <0xdf00 0x100>;
+		label = "wled";
+	};
+
+	qcom,leds@e000 {
+		compatible = "qcom,leds-qpnp";
+		reg = <0xe000 0x100>;
+		label = "wled";
+	};
+
+	qcom,leds@e100 {
+		compatible = "qcom,leds-qpnp";
+		reg = <0xe100 0x100>;
+		label = "wled";
+	};
+
+	pwm@b100 {
+		compatible = "qcom,qpnp-pwm";
+		reg = <0xb100 0x100>,
+		      <0xb042 0x7e>;
+		reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base";
+		qcom,channel-id = <0>;
+	};
+
+	pwm@b200 {
+		compatible = "qcom,qpnp-pwm";
+		reg = <0xb200 0x100>,
+		      <0xb042 0x7e>;
+		reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base";
+		qcom,channel-id = <1>;
+	};
+
+	pwm@b300 {
+		compatible = "qcom,qpnp-pwm";
+		reg = <0xb300 0x100>,
+		      <0xb042 0x7e>;
+		reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base";
+		qcom,channel-id = <2>;
+	};
+
+	pwm@b400 {
+		compatible = "qcom,qpnp-pwm";
+		reg = <0xb400 0x100>,
+		      <0xb042 0x7e>;
+		reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base";
+		qcom,channel-id = <3>;
+	};
+
+	pwm@b500 {
+		compatible = "qcom,qpnp-pwm";
+		reg = <0xb500 0x100>,
+		      <0xb042 0x7e>;
+		reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base";
+		qcom,channel-id = <4>;
+	};
+
+	pwm@b600 {
+		compatible = "qcom,qpnp-pwm";
+		reg = <0xb600 0x100>,
+		      <0xb042 0x7e>;
+		reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base";
+		qcom,channel-id = <5>;
+	};
+
+	pwm@b700 {
+		compatible = "qcom,qpnp-pwm";
+		reg = <0xb700 0x100>,
+		      <0xb042 0x7e>;
+		reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base";
+		qcom,channel-id = <6>;
+	};
+
+	pwm@b800 {
+		compatible = "qcom,qpnp-pwm";
+		reg = <0xb800 0x100>,
+		      <0xb042 0x7e>;
+		reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base";
+		qcom,channel-id = <7>;
 	};
 };
diff --git a/arch/arm/boot/dts/msm-pma8084-rpm-regulator.dtsi b/arch/arm/boot/dts/msm-pma8084-rpm-regulator.dtsi
new file mode 100644
index 0000000..31796dd
--- /dev/null
+++ b/arch/arm/boot/dts/msm-pma8084-rpm-regulator.dtsi
@@ -0,0 +1,712 @@
+/* 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.
+ */
+
+&rpm_bus {
+	rpm-regulator-smpa1 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "smpa";
+		qcom,resource-id = <1>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+		status = "disabled";
+
+		regulator-s1 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_s1";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-smpa2 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "smpa";
+		qcom,resource-id = <2>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+		status = "disabled";
+
+		regulator-s2 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_s2";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-smpa3 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "smpa";
+		qcom,resource-id = <3>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+		status = "disabled";
+
+		regulator-s3 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_s3";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-smpa4 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "smpa";
+		qcom,resource-id = <4>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+		status = "disabled";
+
+		regulator-s4 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_s4";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-smpa5 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "smpa";
+		qcom,resource-id = <5>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+		status = "disabled";
+
+		regulator-s5 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_s5";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-smpa6 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "smpa";
+		qcom,resource-id = <6>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+		status = "disabled";
+
+		regulator-s6 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_s6";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-smpa7 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "smpa";
+		qcom,resource-id = <7>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+		status = "disabled";
+
+		regulator-s7 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_s7";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-smpa8 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "smpa";
+		qcom,resource-id = <8>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+		status = "disabled";
+
+		regulator-s8 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_s8";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-smpa9 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "smpa";
+		qcom,resource-id = <9>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+		status = "disabled";
+
+		regulator-s9 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_s9";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-smpa10 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "smpa";
+		qcom,resource-id = <10>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+		status = "disabled";
+
+		regulator-s10 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_s10";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-smpa11 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "smpa";
+		qcom,resource-id = <11>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+		status = "disabled";
+
+		regulator-s11 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_s11";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-smpa12 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "smpa";
+		qcom,resource-id = <12>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+		status = "disabled";
+
+		regulator-s12 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_s12";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa1 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <1>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l1 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l1";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa2 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <2>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l2 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l2";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa3 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <3>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l3 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l3";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa4 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <4>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l4 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l4";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa5 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <5>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l5 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l5";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa6 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <6>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l6 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l6";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa7 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <7>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l7 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l7";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa8 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <8>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l8 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l8";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa9 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <9>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l9 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l9";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa10 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <10>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l10 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l10";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa11 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <11>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l11 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l11";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa12 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <12>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l12 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l12";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa13 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <13>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l13 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l13";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa14 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <14>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l14 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l14";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa15 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <15>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l15 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l15";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa16 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <16>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l16 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l16";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa17 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <17>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l17 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l17";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa18 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <18>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l18 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l18";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa19 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <19>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l19 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l19";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa20 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <20>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l20 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l20";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa21 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <21>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l21 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l21";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa22 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <22>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l22 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l22";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa23 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <23>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l23 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l23";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa24 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <24>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l24 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l24";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa25 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <25>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l25 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l25";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa26 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <26>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l26 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l26";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa27 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <27>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l27 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l27";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-vsa1 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "vsa";
+		qcom,resource-id = <1>;
+		qcom,regulator-type = <2>;
+		status = "disabled";
+
+		regulator-lvs1 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_lvs1";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-vsa2 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "vsa";
+		qcom,resource-id = <2>;
+		qcom,regulator-type = <2>;
+		status = "disabled";
+
+		regulator-lvs2 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_lvs2";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-vsa3 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "vsa";
+		qcom,resource-id = <3>;
+		qcom,regulator-type = <2>;
+		status = "disabled";
+
+		regulator-lvs3 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_lvs3";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-vsa4 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "vsa";
+		qcom,resource-id = <4>;
+		qcom,regulator-type = <2>;
+		status = "disabled";
+
+		regulator-lvs4 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_lvs4";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-vsa5 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "vsa";
+		qcom,resource-id = <5>;
+		qcom,regulator-type = <2>;
+		status = "disabled";
+
+		regulator-mvs1 {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_mvs1";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/msm-pma8084.dtsi b/arch/arm/boot/dts/msm-pma8084.dtsi
index 42c48f8..ecbfc53 100644
--- a/arch/arm/boot/dts/msm-pma8084.dtsi
+++ b/arch/arm/boot/dts/msm-pma8084.dtsi
@@ -22,6 +22,68 @@
 		#address-cells = <1>;
 		#size-cells = <1>;
 
+		qcom,revid@100 {
+			compatible = "qcom,qpnp-revid";
+			reg = <0x100 0x100>;
+		};
+
+		qcom,power-on@800 {
+			compatible = "qcom,qpnp-power-on";
+			reg = <0x800 0x100>;
+			interrupts = <0x0 0x8 0x0>,
+				     <0x0 0x8 0x1>,
+				     <0x0 0x8 0x4>,
+				     <0x0 0x8 0x5>;
+			interrupt-names = "kpdpwr", "resin",
+					"resin-bark", "kpdpwr-resin-bark";
+			qcom,pon-dbc-delay = <15625>;
+			qcom,system-reset;
+			qcom,s3-debounce = <32>;
+
+			qcom,pon_1 {
+				qcom,pon-type = <0>;
+				qcom,pull-up = <1>;
+				linux,code = <116>;
+			};
+
+			qcom,pon_2 {
+				qcom,pon-type = <1>;
+				qcom,support-reset = <1>;
+				qcom,pull-up = <1>;
+				qcom,s1-timer = <0>;
+				qcom,s2-timer = <2000>;
+				qcom,s2-type = <1>;
+				linux,code = <114>;
+			};
+
+			qcom,pon_3 {
+				qcom,pon-type = <3>;
+				qcom,support-reset = <1>;
+				qcom,s1-timer = <6720>;
+				qcom,s2-timer = <2000>;
+				qcom,s2-type = <7>;
+				qcom,pull-up = <1>;
+			};
+		};
+
+		pma8084_misc: qcom,misc@900 {
+			compatible = "qcom,qpnp-misc";
+			reg = <0x900 0x100>;
+		};
+
+		qcom,temp-alarm@2400 {
+			compatible = "qcom,qpnp-temp-alarm";
+			reg = <0x2400 0x100>;
+			interrupts = <0x0 0x24 0x0>;
+			label = "pma8084_tz";
+			qcom,threshold-set = <0>;
+		};
+
+		qcom,coincell@2800 {
+			compatible = "qcom,qpnp-coincell";
+			reg = <0x2800 0x100>;
+		};
+
 		pma8084_gpios: gpios {
 			spmi-dev-container;
 			compatible = "qcom,qpnp-pin";
@@ -261,6 +323,23 @@
 			qcom,adc-bit-resolution = <15>;
 			qcom,adc-vdd-reference = <1800>;
 		};
+
+		qcom,rtc {
+			compatible = "qcom,qpnp-rtc";
+			spmi-dev-container;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			qcom,qpnp-rtc-write = <0>;
+			qcom,qpnp-rtc-alarm-pwrup = <0>;
+
+			qcom,rtc_rw@6000 {
+				reg = <0x6000 0x100>;
+			};
+			qcom,rtc_alarm@6100 {
+				reg = <0x6100 0x100>;
+				interrupts = <0x0 0x61 0x1>;
+			};
+		};
 	};
 
 	qcom,pma8084@1 {
diff --git a/arch/arm/boot/dts/msm8226-cdp.dtsi b/arch/arm/boot/dts/msm8226-cdp.dtsi
index e5683fb..1e379b2 100644
--- a/arch/arm/boot/dts/msm8226-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8226-cdp.dtsi
@@ -227,6 +227,16 @@
 	status = "ok";
 };
 
+&sdcc3 {
+	qcom,sup-voltages = <1800 1800>;
+	status = "disabled";
+};
+
+&sdhc_3 {
+	qcom,sup-voltages = <1800 1800>;
+	status = "disabled";
+};
+
 &spmi_bus {
 	qcom,pm8226@0 {
 		qcom,leds@a100 {
diff --git a/arch/arm/boot/dts/msm8226-mdss.dtsi b/arch/arm/boot/dts/msm8226-mdss.dtsi
index f580897..b895c64 100644
--- a/arch/arm/boot/dts/msm8226-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8226-mdss.dtsi
@@ -36,6 +36,7 @@
 		qcom,mdss-wb-off = <0x00011100 0x00013100>;
 		qcom,mdss-intf-off = <0x00000000 0x00021300>;
 		qcom,mdss-rot-block-size = <64>;
+		qcom,mdss-smp-mb-per-pipe = <2>;
 
 		qcom,vbif-settings = <0x004 0x00000001>,
 				     <0x0D8 0x00000707>,
diff --git a/arch/arm/boot/dts/msm8226-qrd.dtsi b/arch/arm/boot/dts/msm8226-qrd.dtsi
index db0620f..e991552 100644
--- a/arch/arm/boot/dts/msm8226-qrd.dtsi
+++ b/arch/arm/boot/dts/msm8226-qrd.dtsi
@@ -180,7 +180,7 @@
 &sdcc2 {
 	vdd-supply = <&pm8226_l18>;
 	qcom,vdd-voltage-level = <2950000 2950000>;
-	qcom,vdd-current-level = <9000 800000>;
+	qcom,vdd-current-level = <9000 400000>;
 
 	vdd-io-supply = <&pm8226_l21>;
 	qcom,vdd-io-voltage-level = <1800000 2950000>;
@@ -196,7 +196,7 @@
 
 	qcom,xpc;
 	qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
-	qcom,current-limit = <600>;
+	qcom,current-limit = <400>;
 
 	#address-cells = <0>;
 	interrupt-parent = <&sdcc2>;
@@ -215,7 +215,7 @@
 &sdhc_2 {
 	vdd-supply = <&pm8226_l18>;
 	qcom,vdd-voltage-level = <2950000 2950000>;
-	qcom,vdd-current-level = <9000 800000>;
+	qcom,vdd-current-level = <9000 400000>;
 
 	vdd-io-supply = <&pm8226_l21>;
 	qcom,vdd-io-voltage-level = <1800000 2950000>;
diff --git a/arch/arm/boot/dts/msm8226-regulator.dtsi b/arch/arm/boot/dts/msm8226-regulator.dtsi
index 8006da2..3e89c3a 100644
--- a/arch/arm/boot/dts/msm8226-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8226-regulator.dtsi
@@ -30,14 +30,17 @@
 	apc_vreg_corner: regulator@f9018000 {
 		status = "okay";
 		compatible = "qcom,cpr-regulator";
-		reg = <0xf9018000 0x1000>, <0xf9011064 4>, <0xfc4b80b0 8>,
-			<0xfc4bc450 16>;
-		reg-names = "rbcpr", "rbcpr_clk", "pvs_efuse", "cpr_efuse";
+		reg = <0xf9018000 0x1000>, <0xf9011064 4>, <0xfc4b8000 0x1000>;
+		reg-names = "rbcpr", "rbcpr_clk", "efuse_addr";
 		interrupts = <0 15 0>;
 		regulator-name = "apc_corner";
 		regulator-min-microvolt = <1>;
 		regulator-max-microvolt = <3>;
-		qcom,num-efuse-bits = <5>;
+
+		qcom,pvs-fuse-redun-sel = <22 24 3 2>;
+		qcom,pvs-fuse = <22 6 5>;
+		qcom,pvs-fuse-redun = <22 27 5>;
+
 		qcom,pvs-bin-process = <0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 2
 					2 2 2 2 3 3 3 3 3 3 3 3 0 0 0 0>;
 		qcom,pvs-corner-ceiling-slow = <1155000 1160000 1275000>;
@@ -63,6 +66,16 @@
 		qcom,vdd-apc-step-down-limit = <1>;
 		qcom,cpr-apc-volt-step = <5000>;
 
+		qcom,cpr-fuse-redun-sel = <138 57 1 1>;
+		qcom,cpr-fuse-row = <138>;
+		qcom,cpr-fuse-bp-cpr-disable = <36>;
+		qcom,cpr-fuse-bp-scheme = <37>;
+		qcom,cpr-fuse-target-quot = <24 12 0>;
+		qcom,cpr-fuse-ro-sel = <54 38 41>;
+		qcom,cpr-fuse-redun-row = <139>;
+		qcom,cpr-fuse-redun-target-quot = <24 12 0>;
+		qcom,cpr-fuse-redun-ro-sel = <46 36 39>;
+
 		qcom,cpr-enable;
 	};
 };
@@ -411,6 +424,17 @@
 		};
 	};
 
+	rpm-regulator-ldoa25 {
+		status = "okay";
+		pm8226_l25: regulator-l25 {
+			regulator-name = "8226_l25";
+			regulator-min-microvolt = <1775000>;
+			regulator-max-microvolt = <2125000>;
+			qcom,init-voltage = <1775000>;
+			status = "okay";
+		};
+	};
+
 	rpm-regulator-ldoa26 {
 		status = "okay";
 		pm8226_l26: regulator-l26 {
diff --git a/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts b/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts
index 8520ae3..cb5e299 100644
--- a/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts
+++ b/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts
@@ -30,4 +30,29 @@
 		status = "ok";
 		qcom,mdss-pan-bl-ctrl = "bl_ctrl_dcs";
 	};
+
+	sound {
+		qcom,model = "msm8226-tapan-skuf-snd-card";
+
+		qcom,audio-routing =
+			"RX_BIAS", "MCLK",
+			"LDO_H", "MCLK",
+			"SPK_OUT", "MCLK",
+			"SPK_OUT", "EXT_VDD_SPKR",
+			"Lineout_1 amp", "LINEOUT1",
+			"Lineout_2 amp", "LINEOUT2",
+			"AMIC1", "MIC BIAS1 External",
+			"MIC BIAS1 External", "Handset Mic",
+			"AMIC2", "MIC BIAS2 External",
+			"MIC BIAS2 External", "Headset Mic",
+			"AMIC3", "MIC BIAS1 External",
+			"MIC BIAS1 External", "ANCRight Headset Mic",
+			"AMIC4", "MIC BIAS2 External",
+			"MIC BIAS2 External", "ANCLeft Headset Mic";
+
+		qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
+		qcom,cdc-lineout-spkr-gpios = <&pm8226_gpios 2 0>;
+		qcom,cdc-vdd-spkr-gpios;
+		qcom,cdc-us-euro-gpios;
+	};
 };
diff --git a/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts b/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts
index 1c43589..ac8b437 100644
--- a/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts
+++ b/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts
@@ -31,4 +31,29 @@
 		status = "ok";
 		qcom,mdss-pan-bl-ctrl = "bl_ctrl_dcs";
 	};
+
+	sound {
+		qcom,model = "msm8226-tapan-skuf-snd-card";
+
+		qcom,audio-routing =
+			"RX_BIAS", "MCLK",
+			"LDO_H", "MCLK",
+			"SPK_OUT", "MCLK",
+			"SPK_OUT", "EXT_VDD_SPKR",
+			"Lineout_1 amp", "LINEOUT1",
+			"Lineout_2 amp", "LINEOUT2",
+			"AMIC1", "MIC BIAS1 External",
+			"MIC BIAS1 External", "Handset Mic",
+			"AMIC2", "MIC BIAS2 External",
+			"MIC BIAS2 External", "Headset Mic",
+			"AMIC3", "MIC BIAS1 External",
+			"MIC BIAS1 External", "ANCRight Headset Mic",
+			"AMIC4", "MIC BIAS2 External",
+			"MIC BIAS2 External", "ANCLeft Headset Mic";
+
+		qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
+		qcom,cdc-lineout-spkr-gpios = <&pm8226_gpios 2 0>;
+		qcom,cdc-vdd-spkr-gpios;
+		qcom,cdc-us-euro-gpios;
+	};
 };
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index 42c1247..17bdb9c 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -21,6 +21,7 @@
 		spi0 = &spi_0;
 		sdhc1 = &sdhc_1; /* SDC1 eMMC slot */
 		sdhc2 = &sdhc_2; /* SDC2 SD card slot */
+		sdhc3 = &sdhc_3; /* SDC3 SDIO slot */
 	};
 
 	memory {
@@ -762,6 +763,95 @@
 		status = "disabled";
 	};
 
+	sdcc3: qcom,sdcc@f9864000 {
+		cell-index = <3>;
+		compatible = "qcom,msm-sdcc";
+		reg = <0xf9864000 0x800>,
+			<0xf9864800 0x100>,
+			<0xf9844000 0x7000>;
+		reg-names = "core_mem", "dml_mem", "bam_mem";
+
+		qcom,bus-width = <4>;
+		gpios = <&msmgpio 44 0>, /* CLK */
+			<&msmgpio 43 0>, /* CMD */
+			<&msmgpio 42 0>, /* DATA0 */
+			<&msmgpio 41 0>, /* DATA1 */
+			<&msmgpio 40 0>, /* DATA2 */
+			<&msmgpio 39 0>; /* DATA3 */
+		qcom,gpio-names = "CLK", "CMD", "DAT0", "DAT1", "DAT2", "DAT3";
+
+		qcom,clk-rates = <400000 20000000 25000000 50000000 100000000>;
+
+		qcom,msm-bus,name = "sdcc3";
+		qcom,msm-bus,num-cases = <8>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps = <79 512 0 0>, /* No vote */
+				<79 512 1600 3200>,    /* 400 KB/s*/
+				<79 512 80000 160000>, /* 20 MB/s */
+				<79 512 100000 200000>, /* 25 MB/s */
+				<79 512 200000 400000>, /* 50 MB/s */
+				<79 512 400000 800000>, /* 100 MB/s */
+				<79 512 400000 800000>, /* 200 MB/s */
+				<79 512 2048000 4096000>; /* Max. bandwidth */
+		qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000
+						100000000 200000000 4294967295>;
+
+		#address-cells = <0>;
+		interrupt-parent = <&sdcc3>;
+		interrupts = <0 1 2>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0xffffffff>;
+		interrupt-map = <0 &intc 0 127 0
+			      1 &intc 0 223 0
+			      2 &msmgpio 41 0x8>;
+		interrupt-names = "core_irq", "bam_irq", "sdiowakeup_irq";
+
+		status = "disabled";
+	};
+
+	sdhc_3: sdhci@f9864900 {
+		compatible = "qcom,sdhci-msm";
+		reg = <0xf9864900 0x11c>, <0xf9864000 0x800>;
+		reg-names = "hc_mem", "core_mem";
+
+		qcom,bus-width = <4>;
+		gpios = <&msmgpio 44 0>, /* CLK */
+			<&msmgpio 43 0>, /* CMD */
+			<&msmgpio 42 0>, /* DATA0 */
+			<&msmgpio 41 0>, /* DATA1 */
+			<&msmgpio 40 0>, /* DATA2 */
+			<&msmgpio 39 0>; /* DATA3 */
+		qcom,gpio-names = "CLK", "CMD", "DAT0", "DAT1", "DAT2", "DAT3";
+
+		qcom,clk-rates = <400000 20000000 25000000 50000000 100000000>;
+
+		qcom,msm-bus,name = "sdhc3";
+		qcom,msm-bus,num-cases = <8>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps = <79 512 0 0>, /* No vote */
+				<79 512 1600 3200>,    /* 400 KB/s*/
+				<79 512 80000 160000>, /* 20 MB/s */
+				<79 512 100000 200000>, /* 25 MB/s */
+				<79 512 200000 400000>, /* 50 MB/s */
+				<79 512 400000 800000>, /* 100 MB/s */
+				<79 512 400000 800000>, /* 200 MB/s */
+				<79 512 2048000 4096000>; /* Max. bandwidth */
+		qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000
+						100000000 200000000 4294967295>;
+
+		#address-cells = <0>;
+		interrupt-parent = <&sdhc_3>;
+		interrupts = <0 1 2>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0xffffffff>;
+		interrupt-map = <0 &intc 0 127 0
+			      1 &intc 0 224 0
+			      2 &msmgpio 41 0x8>;
+		interrupt-names = "hc_irq", "pwr_irq", "sdiowakeup_irq";
+
+		status = "disabled";
+	};
+
 	spmi_bus: qcom,spmi@fc4c0000 {
 		cell-index = <0>;
 		compatible = "qcom,spmi-pmic-arb";
diff --git a/arch/arm/boot/dts/msm8610-mtp.dts b/arch/arm/boot/dts/msm8610-mtp.dts
index 27381e2..16fc2e7 100644
--- a/arch/arm/boot/dts/msm8610-mtp.dts
+++ b/arch/arm/boot/dts/msm8610-mtp.dts
@@ -90,6 +90,23 @@
 		};
 	};
 
+	i2c@f9925000 {
+		mpu3050@68 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "okay";
+			reg = <0x68>;
+			compatible = "invn,mpu3050";
+			interrupt-parent = <&msmgpio>;
+			interrupts = <84 0x2>;
+			vlogic-supply = <&pm8110_l14>;
+			vdd-supply = <&pm8110_l19>;
+			invn,gpio-int = <&msmgpio 84 0x2>;
+			invn,gpio-en = <&pm8110_gpios 2 0x2>;
+			invn,poll-interval = <200>;
+		};
+	};
+
 	gen-vkeys {
 		compatible = "qcom,gen-vkeys";
 		label = "atmel_mxt_ts";
@@ -154,7 +171,7 @@
 
 		cdc-vdda-h-supply = <&pm8110_l6>;
 		qcom,cdc-vdda-h-voltage = <1800000 1800000>;
-		qcom,cdc-vdda-h-current = <250000>;
+		qcom,cdc-vdda-h-current = <25000>;
 
 		cdc-vdd-px-supply = <&pm8110_l6>;
 		qcom,cdc-vdd-px-voltage = <1800000 1800000>;
diff --git a/arch/arm/boot/dts/msm8610-qrd-skuaa.dts b/arch/arm/boot/dts/msm8610-qrd-skuaa.dts
new file mode 100644
index 0000000..220f642
--- /dev/null
+++ b/arch/arm/boot/dts/msm8610-qrd-skuaa.dts
@@ -0,0 +1,42 @@
+/* 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.
+ */
+
+/dts-v1/;
+
+/include/ "msm8610-qrd.dtsi"
+/include/ "dsi-v2-panel-hx8379a-wvga-video.dtsi"
+/include/ "msm8610-qrd-camera-sensor.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8610 QRD";
+	compatible = "qcom,msm8610-qrd", "qcom,msm8610", "qcom,qrd";
+	qcom,board-id = <11 1>, <11 0>;
+	qcom,msm-id = <147 0>, <165 0>, <161 0>, <162 0>,
+				  <163 0>, <164 0>, <166 0>;
+};
+
+&soc {
+    sound {
+        qcom,model = "msm8x10-skuaa-snd-card";
+
+        qcom,audio-routing =
+            "RX_BIAS", "MCLK",
+            "INT_LDO_H", "MCLK",
+            "Lineout amp", "LINEOUT",
+            "MIC BIAS Internal1", "Handset Mic",
+            "MIC BIAS Internal2", "Headset Mic",
+            "AMIC1", "MIC BIAS Internal1",
+            "AMIC2", "MIC BIAS Internal2";
+
+        qcom,ext-spk-amp-gpio = <&msmgpio 92 0x0>;
+    };
+};
diff --git a/arch/arm/boot/dts/msm8610-qrd-skuab.dts b/arch/arm/boot/dts/msm8610-qrd-skuab.dts
new file mode 100644
index 0000000..c46e9d2
--- /dev/null
+++ b/arch/arm/boot/dts/msm8610-qrd-skuab.dts
@@ -0,0 +1,40 @@
+/* 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.
+ */
+
+/dts-v1/;
+
+/include/ "msm8610-qrd.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8610 QRD";
+	compatible = "qcom,msm8610-qrd", "qcom,msm8610", "qcom,qrd";
+	qcom,board-id = <11 3>;
+	qcom,msm-id = <147 0>, <165 0>, <161 0>, <162 0>,
+				  <163 0>, <164 0>, <166 0>;
+};
+
+&soc {
+    sound {
+        qcom,model = "msm8x10-skuab-snd-card";
+
+        qcom,audio-routing =
+            "RX_BIAS", "MCLK",
+            "INT_LDO_H", "MCLK",
+            "Lineout amp", "LINEOUT",
+            "MIC BIAS Internal1", "Handset Mic",
+            "MIC BIAS Internal2", "Headset Mic",
+            "AMIC1", "MIC BIAS Internal1",
+            "AMIC2", "MIC BIAS Internal2";
+
+        qcom,ext-spk-amp-gpio = <&msmgpio 92 0x0>;
+    };
+};
diff --git a/arch/arm/boot/dts/msm8610-qrd.dts b/arch/arm/boot/dts/msm8610-qrd.dts
deleted file mode 100644
index 86294df..0000000
--- a/arch/arm/boot/dts/msm8610-qrd.dts
+++ /dev/null
@@ -1,25 +0,0 @@
-/* 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.
- */
-
-/dts-v1/;
-
-/include/ "msm8610-qrd.dtsi"
-/include/ "dsi-v2-panel-hx8379a-wvga-video.dtsi"
-/include/ "msm8610-qrd-camera-sensor.dtsi"
-
-/ {
-	model = "Qualcomm MSM 8610 QRD";
-	compatible = "qcom,msm8610-qrd", "qcom,msm8610", "qcom,qrd";
-	qcom,msm-id = <147 11 0>, <165 11 0>, <161 11 0>, <162 11 0>,
-				  <163 11 0>, <164 11 0>, <166 11 0>;
-};
-
diff --git a/arch/arm/boot/dts/msm8610-qrd.dtsi b/arch/arm/boot/dts/msm8610-qrd.dtsi
index 7a93c49..5a30d40 100644
--- a/arch/arm/boot/dts/msm8610-qrd.dtsi
+++ b/arch/arm/boot/dts/msm8610-qrd.dtsi
@@ -124,51 +124,6 @@
 		};
 	};
 
-	i2c@f9927000  {
-                        msm8x10_wcd_codec@0d{
-                        compatible = "qcom,msm8x10-wcd-i2c";
-                        reg = <0x0d>;
-                        cdc-vdda-cp-supply = <&pm8110_s4>;
-                        qcom,cdc-vdda-cp-voltage = <2150000 2150000>;
-                        qcom,cdc-vdda-cp-current = <650000>;
-
-                        cdc-vdda-h-supply = <&pm8110_l6>;
-                        qcom,cdc-vdda-h-voltage = <1800000 1800000>;
-                        qcom,cdc-vdda-h-current = <250000>;
-
-                        cdc-vdd-px-supply = <&pm8110_l6>;
-                        qcom,cdc-vdd-px-voltage = <1800000 1800000>;
-                        qcom,cdc-vdd-px-current = <10000>;
-
-                        cdc-vdd-1p2v-supply = <&pm8110_l4>;
-                        qcom,cdc-vdd-1p2v-voltage = <1200000 1200000>;
-                        qcom,cdc-vdd-1p2v-current = <5000>;
-
-                        cdc-vdd-mic-bias-supply = <&pm8110_l20>;
-                        qcom,cdc-vdd-mic-bias-voltage = <3075000 3075000>;
-                        qcom,cdc-vdd-mic-bias-current = <25000>;
-
-                        qcom,cdc-micbias-cfilt-sel = <0x0>;
-                        qcom,cdc-micbias-cfilt-mv = <1800000>;
-                        qcom,cdc-mclk-clk-rate = <12288000>;
-                };
-
-                msm8x10_wcd_codec@77{
-                        compatible = "qcom,msm8x10-wcd-i2c";
-                        reg = <0x77>;
-                };
-
-                msm8x10_wcd_codec@66{
-                        compatible = "qcom,msm8x10-wcd-i2c";
-                        reg = <0x66>;
-                };
-
-                msm8x10_wcd_codec@55{
-                        compatible = "qcom,msm8x10-wcd-i2c";
-                        reg = <0x55>;
-                };
-	};
-
     sound {
         qcom,audio-routing =
             "RX_BIAS", "MCLK",
@@ -180,6 +135,58 @@
     };
 };
 
+&i2c_cdc  {
+	msm8x10_wcd_codec@0d{
+		compatible = "qcom,msm8x10-wcd-i2c";
+		reg = <0x0d>;
+		cdc-vdda-cp-supply = <&pm8110_s4>;
+		qcom,cdc-vdda-cp-voltage = <1800000 2150000>;
+		qcom,cdc-vdda-cp-current = <650000>;
+
+		cdc-vdda-h-supply = <&pm8110_l6>;
+		qcom,cdc-vdda-h-voltage = <1800000 1800000>;
+		qcom,cdc-vdda-h-current = <25000>;
+
+		cdc-vdd-px-supply = <&pm8110_l6>;
+		qcom,cdc-vdd-px-voltage = <1800000 1800000>;
+		qcom,cdc-vdd-px-current = <10000>;
+
+		cdc-vdd-1p2v-supply = <&pm8110_l4>;
+		qcom,cdc-vdd-1p2v-voltage = <1200000 1200000>;
+		qcom,cdc-vdd-1p2v-current = <5000>;
+
+		cdc-vdd-mic-bias-supply = <&pm8110_l20>;
+		qcom,cdc-vdd-mic-bias-voltage = <3075000 3075000>;
+		qcom,cdc-vdd-mic-bias-current = <25000>;
+
+		qcom,cdc-micbias-cfilt-sel = <0x0>;
+		qcom,cdc-micbias-cfilt-mv = <1800000>;
+		qcom,cdc-mclk-clk-rate = <12288000>;
+
+		qcom,cdc-static-supplies = "cdc-vdda-h",
+						"cdc-vdd-px",
+						"cdc-vdd-1p2v";
+
+		qcom,cdc-on-demand-supplies = "cdc-vdda-cp",
+						"cdc-vdd-mic-bias";
+	};
+
+	msm8x10_wcd_codec@77{
+		compatible = "qcom,msm8x10-wcd-i2c";
+		reg = <0x77>;
+	};
+
+	msm8x10_wcd_codec@66{
+		compatible = "qcom,msm8x10-wcd-i2c";
+		reg = <0x66>;
+	};
+
+	msm8x10_wcd_codec@55{
+		compatible = "qcom,msm8x10-wcd-i2c";
+		reg = <0x55>;
+	};
+};
+
 &spmi_bus {
 	qcom,pm8110@0 {
 		qcom,leds@a100 {
diff --git a/arch/arm/boot/dts/msm8610-regulator.dtsi b/arch/arm/boot/dts/msm8610-regulator.dtsi
index 0d47e5d..38f587b 100644
--- a/arch/arm/boot/dts/msm8610-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8610-regulator.dtsi
@@ -30,19 +30,22 @@
 	apc_vreg_corner: regulator@f9018000 {
 		status = "okay";
 		compatible = "qcom,cpr-regulator";
-		reg = <0xf9018000 0x1000>, <0xf9011064 4>, <0xfc4b80b0 8>,
-			<0xfc4bc450 16>;
-		reg-names = "rbcpr", "rbcpr_clk", "pvs_efuse", "cpr_efuse";
+		reg = <0xf9018000 0x1000>, <0xf9011064 4>, <0xfc4b8000 0x1000>;
+		reg-names = "rbcpr", "rbcpr_clk", "efuse_addr";
 		interrupts = <0 15 0>;
 		regulator-name = "apc_corner";
 		regulator-min-microvolt = <1>;
 		regulator-max-microvolt = <3>;
-		qcom,num-efuse-bits = <5>;
-		qcom,pvs-bin-process = <0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 2
-					2 2 2 2 3 3 3 3 3 3 3 3 0 0 0 0>;
+
+		qcom,pvs-fuse-redun-sel = <53 25 3 2>;
+		qcom,pvs-fuse = <23 6 5>;
+		qcom,pvs-fuse-redun = <61 47 5>;
+
+		qcom,pvs-bin-process = <1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+					1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1>;
 		qcom,pvs-corner-ceiling-slow = <1150000 1150000 1275000>;
-		qcom,pvs-corner-ceiling-nom  =  <975000 1075000 1200000>;
-		qcom,pvs-corner-ceiling-fast =  <900000 1000000 1140000>;
+		qcom,pvs-corner-ceiling-nom  = <1075000 1075000 1200000>;
+		qcom,pvs-corner-ceiling-fast = <1000000 1000000 1140000>;
 		vdd-apc-supply = <&pm8110_s2>;
 
 		vdd-mx-supply = <&pm8110_l3_ao>;
@@ -62,6 +65,18 @@
 		qcom,vdd-apc-step-up-limit = <1>;
 		qcom,vdd-apc-step-down-limit = <1>;
 		qcom,cpr-apc-volt-step = <5000>;
+
+		qcom,cpr-fuse-redun-sel = <53 25 3 2>;
+		qcom,cpr-fuse-row = <61>;
+		qcom,cpr-fuse-bp-cpr-disable = <39>;
+		qcom,cpr-fuse-bp-scheme = <40>;
+		qcom,cpr-fuse-target-quot = <27 15 3>;
+		qcom,cpr-fuse-ro-sel = <47 41 44>;
+		qcom,cpr-fuse-redun-row = <52>;
+		qcom,cpr-fuse-redun-bp-cpr-disable = <24>;
+		qcom,cpr-fuse-redun-bp-scheme = <25>;
+		qcom,cpr-fuse-redun-target-quot = <32 12 0>;
+		qcom,cpr-fuse-redun-ro-sel = <44 26 29>;
 	};
 };
 
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index c9e88a8..15214dd 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -701,6 +701,7 @@
 		gpios = <&msmgpio 23 0>, <&msmgpio 24 0>, <&msmgpio 25 0>, <&msmgpio 26 0>, <&msmgpio 27 0>;
 		qcom,has-pronto-hw;
 		qcom,wlan-rx-buff-count = <256>;
+		qcom,has-autodetect-xo;
 	};
 
 	qcom,mss@fc880000 {
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-dragonboard.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-dragonboard.dtsi
index b9f2125..2f8e558 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-dragonboard.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-dragonboard.dtsi
@@ -50,12 +50,15 @@
 		qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
 		qcom,gpio-no-mux = <0>;
 		gpios = <&msmgpio 15 0>,
-			<&msmgpio 90 0>;
+			<&msmgpio 90 0>,
+			<&msmgpio 89 0>;
 		qcom,gpio-reset = <1>;
-		qcom,gpio-req-tbl-num = <0 1>;
-		qcom,gpio-req-tbl-flags = <1 0>;
+		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_RESET1",
+					  "CAM_STANDBY";
 		qcom,gpio-set-tbl-num = <1 1>;
 		qcom,gpio-set-tbl-flags = <0 2>;
 		qcom,gpio-set-tbl-delay = <1000 30000>;
@@ -90,12 +93,15 @@
 		qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
 		qcom,gpio-no-mux = <0>;
 		gpios = <&msmgpio 15 0>,
-			<&msmgpio 90 0>;
+			<&msmgpio 90 0>,
+			<&msmgpio 89 0>;
 		qcom,gpio-reset = <1>;
-		qcom,gpio-req-tbl-num = <0 1>;
-		qcom,gpio-req-tbl-flags = <1 0>;
+		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_RESET1",
+					  "CAM_STANDBY";
 		qcom,gpio-set-tbl-num = <1 1>;
 		qcom,gpio-set-tbl-flags = <0 2>;
 		qcom,gpio-set-tbl-delay = <1000 30000>;
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index bcdaf1b..8a3a77e 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.dtsi
@@ -252,63 +252,61 @@
 	};
 };
 
-&spmi_bus {
-	qcom,pm8941@1 {
-		qcom,leds@d800 {
-			status = "okay";
-			qcom,wled_0 {
-				label = "wled";
-				linux,name = "wled:backlight";
-				linux,default-trigger = "bkl-trigger";
-				qcom,cs-out-en;
-				qcom,op-fdbck = <1>;
-				qcom,default-state = "on";
-				qcom,max-current = <25>;
-				qcom,ctrl-delay-us = <0>;
-				qcom,boost-curr-lim = <3>;
-				qcom,cp-sel = <0>;
-				qcom,switch-freq = <2>;
-				qcom,ovp-val = <2>;
-				qcom,num-strings = <1>;
-				qcom,id = <0>;
-			};
+&pm8941_lsid1 {
+	qcom,leds@d800 {
+		status = "okay";
+		qcom,wled_0 {
+			label = "wled";
+			linux,name = "wled:backlight";
+			linux,default-trigger = "bkl-trigger";
+			qcom,cs-out-en;
+			qcom,op-fdbck = <1>;
+			qcom,default-state = "on";
+			qcom,max-current = <25>;
+			qcom,ctrl-delay-us = <0>;
+			qcom,boost-curr-lim = <3>;
+			qcom,cp-sel = <0>;
+			qcom,switch-freq = <2>;
+			qcom,ovp-val = <2>;
+			qcom,num-strings = <1>;
+			qcom,id = <0>;
 		};
+	};
 
-		qcom,leds@d900 {
-			status = "disabled";
-		};
+	qcom,leds@d900 {
+		status = "disabled";
+	};
 
-		qcom,leds@da00 {
-			status = "disabled";
-		};
+	qcom,leds@da00 {
+		status = "disabled";
+	};
 
-		qcom,leds@db00 {
-			status = "disabled";
-		};
+	qcom,leds@db00 {
+		status = "disabled";
+	};
 
-		qcom,leds@dc00 {
-			status = "disabled";
-		};
+	qcom,leds@dc00 {
+		status = "disabled";
+	};
 
-		qcom,leds@dd00 {
-			status = "disabled";
-		};
+	qcom,leds@dd00 {
+		status = "disabled";
+	};
 
-		qcom,leds@de00 {
-			status = "disabled";
-		};
+	qcom,leds@de00 {
+		status = "disabled";
+	};
 
-		qcom,leds@df00 {
-			status = "disabled";
-		};
+	qcom,leds@df00 {
+		status = "disabled";
+	};
 
-		qcom,leds@e000 {
-			status = "disabled";
-		};
+	qcom,leds@e000 {
+		status = "disabled";
+	};
 
-		qcom,leds@e100 {
-			status = "disabled";
-		};
+	qcom,leds@e100 {
+		status = "disabled";
 	};
 };
 
diff --git a/arch/arm/boot/dts/msm8974-clock.dtsi b/arch/arm/boot/dts/msm8974-clock.dtsi
index bed5d70..8d90771 100644
--- a/arch/arm/boot/dts/msm8974-clock.dtsi
+++ b/arch/arm/boot/dts/msm8974-clock.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -10,18 +10,14 @@
  * GNU General Public License for more details.
  */
 
-&spmi_bus {
+&pm8941_lsid0 {
+	pm8941_clkdiv1: clkdiv@5b00 {
+		qcom,cxo-div = <2>;
+	};
 
-	qcom,pm8941@0 {
+	pm8941_clkdiv2: clkdiv@5c00 {
+	};
 
-		pm8941_clkdiv1: clkdiv@5b00 {
-			qcom,cxo-div = <2>;
-		};
-
-		pm8941_clkdiv2: clkdiv@5c00 {
-		};
-
-		pm8941_clkdiv3: clkdiv@5d00 {
-		};
+	pm8941_clkdiv3: clkdiv@5d00 {
 	};
 };
diff --git a/arch/arm/boot/dts/msm8974-fluid.dtsi b/arch/arm/boot/dts/msm8974-fluid.dtsi
index 638e6dd..57ce130 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-fluid.dtsi
@@ -251,63 +251,61 @@
 	};
 };
 
-&spmi_bus {
-	qcom,pm8941@1 {
-		qcom,leds@d800 {
-			status = "okay";
-			qcom,wled_0 {
-				label = "wled";
-				linux,name = "wled:backlight";
-				linux,default-trigger = "bkl-trigger";
-				qcom,cs-out-en;
-				qcom,op-fdbck = <1>;
-				qcom,default-state = "on";
-				qcom,max-current = <25>;
-				qcom,ctrl-delay-us = <0>;
-				qcom,boost-curr-lim = <3>;
-				qcom,cp-sel = <0>;
-				qcom,switch-freq = <2>;
-				qcom,ovp-val = <2>;
-				qcom,num-strings = <1>;
-				qcom,id = <0>;
-			};
+&pm8941_lsid1 {
+	qcom,leds@d800 {
+		status = "okay";
+		qcom,wled_0 {
+			label = "wled";
+			linux,name = "wled:backlight";
+			linux,default-trigger = "bkl-trigger";
+			qcom,cs-out-en;
+			qcom,op-fdbck = <1>;
+			qcom,default-state = "on";
+			qcom,max-current = <25>;
+			qcom,ctrl-delay-us = <0>;
+			qcom,boost-curr-lim = <3>;
+			qcom,cp-sel = <0>;
+			qcom,switch-freq = <2>;
+			qcom,ovp-val = <2>;
+			qcom,num-strings = <1>;
+			qcom,id = <0>;
 		};
+	};
 
-		qcom,leds@d900 {
-			status = "disabled";
-		};
+	qcom,leds@d900 {
+		status = "disabled";
+	};
 
-		qcom,leds@da00 {
-			status = "disabled";
-		};
+	qcom,leds@da00 {
+		status = "disabled";
+	};
 
-		qcom,leds@db00 {
-			status = "disabled";
-		};
+	qcom,leds@db00 {
+		status = "disabled";
+	};
 
-		qcom,leds@dc00 {
-			status = "disabled";
-		};
+	qcom,leds@dc00 {
+		status = "disabled";
+	};
 
-		qcom,leds@dd00 {
-			status = "disabled";
-		};
+	qcom,leds@dd00 {
+		status = "disabled";
+	};
 
-		qcom,leds@de00 {
-			status = "disabled";
-		};
+	qcom,leds@de00 {
+		status = "disabled";
+	};
 
-		qcom,leds@df00 {
-			status = "disabled";
-		};
+	qcom,leds@df00 {
+		status = "disabled";
+	};
 
-		qcom,leds@e000 {
-			status = "disabled";
-		};
+	qcom,leds@e000 {
+		status = "disabled";
+	};
 
-		qcom,leds@e100 {
-			status = "disabled";
-		};
+	qcom,leds@e100 {
+		status = "disabled";
 	};
 };
 
diff --git a/arch/arm/boot/dts/msm8974-leds.dtsi b/arch/arm/boot/dts/msm8974-leds.dtsi
index 5e91f45..ab57468 100644
--- a/arch/arm/boot/dts/msm8974-leds.dtsi
+++ b/arch/arm/boot/dts/msm8974-leds.dtsi
@@ -11,119 +11,116 @@
  * GNU General Public License for more details.
  */
 
-&spmi_bus {
-	qcom,pm8941@1 {
-		qcom,leds@d000 {
-			status = "okay";
-			qcom,rgb_0 {
-				label = "rgb";
-				linux,name = "led:rgb_red";
-				qcom,mode = "pwm";
-				qcom,pwm-channel = <6>;
-				qcom,pwm-us = <1000>;
-				qcom,max-current = <12>;
-				qcom,default-state = "off";
-				qcom,id = <3>;
-				linux,default-trigger =
-					"battery-charging";
-			};
-
-			qcom,rgb_1 {
-				label = "rgb";
-				linux,name = "led:rgb_green";
-				qcom,mode = "pwm";
-				qcom,pwm-channel = <5>;
-				qcom,pwm-us = <1000>;
-				qcom,max-current = <12>;
-				qcom,default-state = "off";
-				qcom,id = <4>;
-				linux,default-trigger = "battery-full";
-			};
-
-			qcom,rgb_2 {
-				label = "rgb";
-				linux,name = "led:rgb_blue";
-				qcom,mode = "pwm";
-				qcom,pwm-channel = <4>;
-				qcom,pwm-us = <1000>;
-				qcom,max-current = <12>;
-				qcom,id = <5>;
-				status = "disabled";
-			};
+&pm8941_lsid1 {
+	qcom,leds@d000 {
+		status = "okay";
+		qcom,rgb_0 {
+			label = "rgb";
+			linux,name = "led:rgb_red";
+			qcom,mode = "pwm";
+			qcom,pwm-channel = <6>;
+			qcom,pwm-us = <1000>;
+			qcom,max-current = <12>;
+			qcom,default-state = "off";
+			qcom,id = <3>;
+			linux,default-trigger =
+				"battery-charging";
 		};
 
-		qcom,leds@d100 {
-			status = "disabled";
+		qcom,rgb_1 {
+			label = "rgb";
+			linux,name = "led:rgb_green";
+			qcom,mode = "pwm";
+			qcom,pwm-channel = <5>;
+			qcom,pwm-us = <1000>;
+			qcom,max-current = <12>;
+			qcom,default-state = "off";
+			qcom,id = <4>;
+			linux,default-trigger = "battery-full";
 		};
 
-		qcom,leds@d200 {
-			status = "disabled";
-		};
-
-		qcom,leds@d300 {
-			status = "okay";
-			pm8941_flash0: qcom,flash_0 {
-				qcom,max-current = <1000>;
-				qcom,default-state = "off";
-				qcom,headroom = <3>;
-				qcom,duration = <1280>;
-				qcom,clamp-curr = <200>;
-				qcom,startup-dly = <3>;
-				qcom,safety-timer;
-				label = "flash";
-				linux,default-trigger =
-					"flash0_trigger";
-				qcom,id = <1>;
-				linux,name = "led:flash_0";
-				qcom,current = <625>;
-			};
-
-			pm8941_flash1: qcom,flash_1 {
-				qcom,max-current = <1000>;
-				qcom,default-state = "off";
-				qcom,headroom = <3>;
-				qcom,duration = <1280>;
-				qcom,clamp-curr = <200>;
-				qcom,startup-dly = <3>;
-				qcom,safety-timer;
-				linux,default-trigger =
-					"flash1_trigger";
-				label = "flash";
-				qcom,id = <2>;
-				linux,name = "led:flash_1";
-				qcom,current = <625>;
-			};
-
-			pm8941_torch: qcom,flash_torch {
-				qcom,max-current = <200>;
-				qcom,default-state = "off";
-				qcom,headroom = <0>;
-				qcom,startup-dly = <1>;
-				linux,default-trigger =
-					"torch_trigger";
-				label = "flash";
-				qcom,id = <2>;
-				linux,name = "led:flash_torch";
-				qcom,current = <200>;
-				qcom,torch-enable;
-			};
-		};
-
-		qcom,leds@d400 {
-			status = "disabled";
-		};
-
-		qcom,leds@d500 {
-			status = "disabled";
-		};
-
-		qcom,leds@d600 {
-			status = "disabled";
-		};
-
-		qcom,leds@d700 {
+		qcom,rgb_2 {
+			label = "rgb";
+			linux,name = "led:rgb_blue";
+			qcom,mode = "pwm";
+			qcom,pwm-channel = <4>;
+			qcom,pwm-us = <1000>;
+			qcom,max-current = <12>;
+			qcom,id = <5>;
 			status = "disabled";
 		};
 	};
-};
 
+	qcom,leds@d100 {
+		status = "disabled";
+	};
+
+	qcom,leds@d200 {
+		status = "disabled";
+	};
+
+	qcom,leds@d300 {
+		status = "okay";
+		pm8941_flash0: qcom,flash_0 {
+			qcom,max-current = <1000>;
+			qcom,default-state = "off";
+			qcom,headroom = <3>;
+			qcom,duration = <1280>;
+			qcom,clamp-curr = <200>;
+			qcom,startup-dly = <3>;
+			qcom,safety-timer;
+			label = "flash";
+			linux,default-trigger =
+				"flash0_trigger";
+			qcom,id = <1>;
+			linux,name = "led:flash_0";
+			qcom,current = <625>;
+		};
+
+		pm8941_flash1: qcom,flash_1 {
+			qcom,max-current = <1000>;
+			qcom,default-state = "off";
+			qcom,headroom = <3>;
+			qcom,duration = <1280>;
+			qcom,clamp-curr = <200>;
+			qcom,startup-dly = <3>;
+			qcom,safety-timer;
+			linux,default-trigger =
+				"flash1_trigger";
+			label = "flash";
+			qcom,id = <2>;
+			linux,name = "led:flash_1";
+			qcom,current = <625>;
+		};
+
+		pm8941_torch: qcom,flash_torch {
+			qcom,max-current = <200>;
+			qcom,default-state = "off";
+			qcom,headroom = <0>;
+			qcom,startup-dly = <1>;
+			linux,default-trigger =
+				"torch_trigger";
+			label = "flash";
+			qcom,id = <2>;
+			linux,name = "led:flash_torch";
+			qcom,current = <200>;
+			qcom,torch-enable;
+		};
+	};
+
+	qcom,leds@d400 {
+		status = "disabled";
+	};
+
+	qcom,leds@d500 {
+		status = "disabled";
+	};
+
+	qcom,leds@d600 {
+		status = "disabled";
+	};
+
+	qcom,leds@d700 {
+		status = "disabled";
+	};
+};
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index ddf5b60..82bb7dc 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.dtsi
@@ -782,14 +782,12 @@
 	};
 };
 
-&spmi_bus {
-	qcom,pm8941@1 {
-		qcom,leds@d000 {
-			qcom,rgb_2 {
-				status = "ok";
-				qcom,default-state = "on";
-				qcom,turn-off-delay-ms = <1000>;
-			};
+&pm8941_lsid1 {
+	qcom,leds@d000 {
+		qcom,rgb_2 {
+			status = "ok";
+			qcom,default-state = "on";
+			qcom,turn-off-delay-ms = <1000>;
 		};
 	};
 };
diff --git a/arch/arm/boot/dts/msm8974-mtp.dtsi b/arch/arm/boot/dts/msm8974-mtp.dtsi
index 4af48cc..7b43d9b 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-mtp.dtsi
@@ -192,63 +192,61 @@
 	};
 };
 
-&spmi_bus {
-	qcom,pm8941@1 {
-		qcom,leds@d800 {
-			status = "okay";
-			qcom,wled_0 {
-				label = "wled";
-				linux,name = "wled:backlight";
-				linux,default-trigger = "bkl-trigger";
-				qcom,cs-out-en;
-				qcom,op-fdbck = <1>;
-				qcom,default-state = "on";
-				qcom,max-current = <25>;
-				qcom,ctrl-delay-us = <0>;
-				qcom,boost-curr-lim = <3>;
-				qcom,cp-sel = <0>;
-				qcom,switch-freq = <2>;
-				qcom,ovp-val = <2>;
-				qcom,num-strings = <1>;
-				qcom,id = <0>;
-			};
+&pm8941_lsid1 {
+	qcom,leds@d800 {
+		status = "okay";
+		qcom,wled_0 {
+			label = "wled";
+			linux,name = "wled:backlight";
+			linux,default-trigger = "bkl-trigger";
+			qcom,cs-out-en;
+			qcom,op-fdbck = <1>;
+			qcom,default-state = "on";
+			qcom,max-current = <25>;
+			qcom,ctrl-delay-us = <0>;
+			qcom,boost-curr-lim = <3>;
+			qcom,cp-sel = <0>;
+			qcom,switch-freq = <2>;
+			qcom,ovp-val = <2>;
+			qcom,num-strings = <1>;
+			qcom,id = <0>;
 		};
+	};
 
-		qcom,leds@d900 {
-			status = "disabled";
-		};
+	qcom,leds@d900 {
+		status = "disabled";
+	};
 
-		qcom,leds@da00 {
-			status = "disabled";
-		};
+	qcom,leds@da00 {
+		status = "disabled";
+	};
 
-		qcom,leds@db00 {
-			status = "disabled";
-		};
+	qcom,leds@db00 {
+		status = "disabled";
+	};
 
-		qcom,leds@dc00 {
-			status = "disabled";
-		};
+	qcom,leds@dc00 {
+		status = "disabled";
+	};
 
-		qcom,leds@dd00 {
-			status = "disabled";
-		};
+	qcom,leds@dd00 {
+		status = "disabled";
+	};
 
-		qcom,leds@de00 {
-			status = "disabled";
-		};
+	qcom,leds@de00 {
+		status = "disabled";
+	};
 
-		qcom,leds@df00 {
-			status = "disabled";
-		};
+	qcom,leds@df00 {
+		status = "disabled";
+	};
 
-		qcom,leds@e000 {
-			status = "disabled";
-		};
+	qcom,leds@e000 {
+		status = "disabled";
+	};
 
-		qcom,leds@e100 {
-			status = "disabled";
-		};
+	qcom,leds@e100 {
+		status = "disabled";
 	};
 };
 
@@ -667,21 +665,6 @@
 	};
 };
 
-&pm8841_mpps {
-
-	mpp@a000 { /* MPP 1 */
-	};
-
-	mpp@a100 { /* MPP 2 */
-	};
-
-	mpp@a200 { /* MPP 3 */
-	};
-
-	mpp@a300 { /* MPP 4 */
-	};
-};
-
 &slim_msm {
 	taiko_codec {
 		qcom,cdc-micbias1-ext-cap;
diff --git a/arch/arm/boot/dts/msm8974-regulator.dtsi b/arch/arm/boot/dts/msm8974-regulator.dtsi
index d9d5aaa..eae9032 100644
--- a/arch/arm/boot/dts/msm8974-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974-regulator.dtsi
@@ -13,48 +13,44 @@
 
 /* QPNP controlled regulators: */
 
-&spmi_bus {
+&pm8941_lsid1 {
+	pm8941_boost: regulator@a000 {
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		qcom,enable-time = <500>;
+		status = "okay";
+	};
 
-	qcom,pm8941@1 {
+	pm8941_mvs1: regulator@8300 {
+		parent-supply = <&pm8941_chg_otg>;
+		qcom,enable-time = <1000>;
+		qcom,pull-down-enable = <1>;
+		interrupts = <0x1 0x83 0x2>;
+		interrupt-names = "ocp";
+		qcom,ocp-enable = <1>;
+		qcom,ocp-max-retries = <10>;
+		qcom,ocp-retry-delay = <30>;
+		qcom,soft-start-enable = <1>;
+		qcom,vs-soft-start-strength = <0>;
+		qcom,hpm-enable = <1>;
+		qcom,auto-mode-enable = <0>;
+		status = "okay";
+	};
 
-		pm8941_boost: regulator@a000 {
-			regulator-min-microvolt = <5000000>;
-			regulator-max-microvolt = <5000000>;
-			qcom,enable-time = <500>;
-			status = "okay";
-		};
-
-		pm8941_mvs1: regulator@8300 {
-			parent-supply = <&pm8941_chg_otg>;
-			qcom,enable-time = <1000>;
-			qcom,pull-down-enable = <1>;
-			interrupts = <0x1 0x83 0x2>;
-			interrupt-names = "ocp";
-			qcom,ocp-enable = <1>;
-			qcom,ocp-max-retries = <10>;
-			qcom,ocp-retry-delay = <30>;
-			qcom,soft-start-enable = <1>;
-			qcom,vs-soft-start-strength = <0>;
-			qcom,hpm-enable = <1>;
-			qcom,auto-mode-enable = <0>;
-			status = "okay";
-		};
-
-		pm8941_mvs2: regulator@8400 {
-			parent-supply = <&pm8941_boost>;
-			qcom,enable-time = <1000>;
-			qcom,pull-down-enable = <1>;
-			interrupts = <0x1 0x84 0x2>;
-			interrupt-names = "ocp";
-			qcom,ocp-enable = <1>;
-			qcom,ocp-max-retries = <10>;
-			qcom,ocp-retry-delay = <30>;
-			qcom,soft-start-enable = <1>;
-			qcom,vs-soft-start-strength = <0>;
-			qcom,hpm-enable = <1>;
-			qcom,auto-mode-enable = <0>;
-			status = "okay";
-		};
+	pm8941_mvs2: regulator@8400 {
+		parent-supply = <&pm8941_boost>;
+		qcom,enable-time = <1000>;
+		qcom,pull-down-enable = <1>;
+		interrupts = <0x1 0x84 0x2>;
+		interrupt-names = "ocp";
+		qcom,ocp-enable = <1>;
+		qcom,ocp-max-retries = <10>;
+		qcom,ocp-retry-delay = <30>;
+		qcom,soft-start-enable = <1>;
+		qcom,vs-soft-start-strength = <0>;
+		qcom,hpm-enable = <1>;
+		qcom,auto-mode-enable = <0>;
+		status = "okay";
 	};
 };
 
diff --git a/arch/arm/boot/dts/msm8974-v1.dtsi b/arch/arm/boot/dts/msm8974-v1.dtsi
index caec2dc..cfacac6 100644
--- a/arch/arm/boot/dts/msm8974-v1.dtsi
+++ b/arch/arm/boot/dts/msm8974-v1.dtsi
@@ -17,6 +17,21 @@
  */
 
 /include/ "msm8974.dtsi"
+
+/include/ "msm-pm8x41-rpm-regulator.dtsi"
+/include/ "msm-pm8841.dtsi"
+&spmi_bus {
+	pm8941_lsid0: qcom,pm8941@0 {
+		reg = <0x0>;
+	};
+	pm8941_lsid1: qcom,pm8941@1 {
+		reg = <0x1>;
+	};
+};
+/include/ "msm-pm8941.dtsi"
+/include/ "msm8974-regulator.dtsi"
+/include/ "msm8974-clock.dtsi"
+
 /include/ "msm8974-v1-iommu.dtsi"
 /include/ "msm8974-v1-iommu-domains.dtsi"
 /include/ "msm8974-v1-pm.dtsi"
diff --git a/arch/arm/boot/dts/msm8974-v2.dtsi b/arch/arm/boot/dts/msm8974-v2.dtsi
index 0240039..0b3b60f 100644
--- a/arch/arm/boot/dts/msm8974-v2.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2.dtsi
@@ -17,6 +17,21 @@
  */
 
 /include/ "msm8974.dtsi"
+
+/include/ "msm-pm8x41-rpm-regulator.dtsi"
+/include/ "msm-pm8841.dtsi"
+&spmi_bus {
+	pm8941_lsid0: qcom,pm8941@0 {
+		reg = <0x0>;
+	};
+	pm8941_lsid1: qcom,pm8941@1 {
+		reg = <0x1>;
+	};
+};
+/include/ "msm-pm8941.dtsi"
+/include/ "msm8974-regulator.dtsi"
+/include/ "msm8974-clock.dtsi"
+
 /include/ "msm8974-v2-iommu.dtsi"
 /include/ "msm8974-v2-iommu-domains.dtsi"
 /include/ "msm8974-v2-pm.dtsi"
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 181eb9a..4564c6a 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -1690,9 +1690,3 @@
 &gdsc_usb_hsic {
 	status = "ok";
 };
-
-/include/ "msm-pm8x41-rpm-regulator.dtsi"
-/include/ "msm-pm8841.dtsi"
-/include/ "msm-pm8941.dtsi"
-/include/ "msm8974-regulator.dtsi"
-/include/ "msm8974-clock.dtsi"
diff --git a/arch/arm/boot/dts/msm8974pro-ab-mtp.dts b/arch/arm/boot/dts/msm8974pro-ab-mtp.dts
index 002baf7..d1566ae 100644
--- a/arch/arm/boot/dts/msm8974pro-ab-mtp.dts
+++ b/arch/arm/boot/dts/msm8974pro-ab-mtp.dts
@@ -26,3 +26,7 @@
 		      <217 8 0x10000>,
 		      <218 8 0x10000>;
 };
+
+&sdhc_1 {
+	qcom,clk-rates = <400000 20000000 25000000 50000000 100000000>;
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ab.dtsi b/arch/arm/boot/dts/msm8974pro-ab.dtsi
index 9240514..88687bd 100644
--- a/arch/arm/boot/dts/msm8974pro-ab.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-ab.dtsi
@@ -17,3 +17,25 @@
  */
 
 /include/ "msm8974pro.dtsi"
+
+/include/ "msm-pm8x41-rpm-regulator.dtsi"
+/include/ "msm-pm8841.dtsi"
+&spmi_bus {
+	pm8941_lsid0: qcom,pm8941@0 {
+		reg = <0x0>;
+	};
+	pm8941_lsid1: qcom,pm8941@1 {
+		reg = <0x1>;
+	};
+};
+/include/ "msm-pm8941.dtsi"
+/include/ "msm8974-regulator.dtsi"
+/include/ "msm8974-clock.dtsi"
+
+&krait_pdn {
+	qcom,use-phase-switching;
+};
+
+&tspp {
+	vdd_cx-supply = <&pm8841_s2_corner>;
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ac-mtp.dts b/arch/arm/boot/dts/msm8974pro-ac-mtp.dts
index c5042b7..b8df576 100644
--- a/arch/arm/boot/dts/msm8974pro-ac-mtp.dts
+++ b/arch/arm/boot/dts/msm8974pro-ac-mtp.dts
@@ -12,8 +12,8 @@
 
 /dts-v1/;
 
-/include/ "msm8974pro-ac.dtsi"
-/include/ "msm8974-mtp.dtsi"
+/include/ "msm8974pro-ac-pm8941.dtsi"
+/include/ "msm8974pro-ac-mtp.dtsi"
 
 / {
 	model = "Qualcomm MSM 8974Pro-AC MTP";
@@ -23,3 +23,7 @@
 		      <213 8 0x10000>,
 		      <216 8 0x10000>;
 };
+
+&sdhc_1 {
+	qcom,clk-rates = <400000 20000000 25000000 50000000 100000000>;
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ac-mtp.dtsi b/arch/arm/boot/dts/msm8974pro-ac-mtp.dtsi
new file mode 100644
index 0000000..250afd2
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974pro-ac-mtp.dtsi
@@ -0,0 +1,302 @@
+/* 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/ "msm8974-mtp.dtsi"
+
+&cci {
+	qcom,camera@6e {
+		qcom,vdd-cx-supply = <&pma8084_s2>;
+		cam_vdig-supply = <&pma8084_l3>;
+		cam_vana-supply = <&pma8084_l17>;
+		cam_vio-supply = <&pma8084_lvs4>;
+		cam_vaf-supply = <&pma8084_l23>;
+	};
+
+	qcom,camera@20 {
+		qcom,vdd-cx-supply = <&pma8084_s2>;
+		cam_vdig-supply = <&pma8084_l3>;
+		cam_vana-supply = <&pma8084_l17>;
+		cam_vio-supply = <&pma8084_lvs4>;
+		cam_vaf-supply = <&pma8084_l23>;
+	};
+
+	qcom,camera@6c {
+		qcom,vdd-cx-supply = <&pma8084_s2>;
+		cam_vdig-supply = <&pma8084_l3>;
+		cam_vana-supply = <&pma8084_l17>;
+		cam_vio-supply = <&pma8084_lvs4>;
+	};
+
+	qcom,camera@90 {
+		qcom,vdd-cx-supply = <&pma8084_s2>;
+		cam_vdig-supply = <&pma8084_l3>;
+		cam_vana-supply = <&pma8084_l17>;
+		cam_vio-supply = <&pma8084_lvs4>;
+	};
+};
+
+&soc {
+	i2c@f9924000 {
+		atmel_mxt_ts@4a {
+			vdd_ana-supply = <&pma8084_l18>;
+			vcc_i2c-supply = <&pma8084_lvs1>;
+		};
+	};
+
+	i2c@f9967000 {
+		isa1200@48 {
+			vcc_i2c-supply = <&pma8084_s4>;
+		};
+	};
+
+	qcom,ssusb@f9200000 {
+		vbus_dwc3-supply = <&pm8941_mvs1>;
+	};
+
+	qcom,mdss_dsi_toshiba_720p_video {
+		qcom,rst-gpio = <&pma8084_gpios 20 0>;
+	};
+
+	gpio_keys {
+		camera_snapshot {
+			gpios = <&pma8084_gpios 3 0x1>;
+		};
+
+		camera_focus {
+			gpios = <&pma8084_gpios 4 0x1>;
+		};
+
+		vol_up {
+			gpios = <&pma8084_gpios 5 0x1>;
+		};
+	};
+
+	spi@f9923000 {
+		ethernet-switch@2 {
+			rst-gpio = <&pma8084_mpps 6 0>;
+		};
+	};
+};
+
+&sdhc_1 {
+	vdd-supply = <&pma8084_l20>;
+	vdd-io-supply = <&pma8084_s4>;
+};
+
+&sdhc_2 {
+	vdd-supply = <&pma8084_l21>;
+	vdd-io-supply = <&pma8084_l13>;
+};
+
+&pma8084_gpios {
+	gpio@c000 { /* GPIO 1 */
+		/* Unused */
+		qcom,mode = <0>;		/* Digital input */
+		qcom,pull = <0>;		/* Pull up 30 uA */
+		qcom,master-en = <1>;
+	};
+
+	gpio@c100 { /* GPIO 2 */
+		/* Unused */
+		qcom,mode = <0>;		/* Digital input */
+		qcom,pull = <0>;		/* Pull up 30 uA */
+		qcom,master-en = <1>;
+	};
+
+	gpio@c200 { /* GPIO 3 */
+		/* Snapshot button */
+		qcom,mode = <0>;		/* Digital input */
+		qcom,pull = <0>;		/* Pull up 30 uA */
+		qcom,vin-sel = <2>;		/* PMA8084 S4 = 1.8 V */
+		qcom,src-sel = <0>;		/* Constant */
+		qcom,master-en = <1>;
+	};
+
+	gpio@c300 { /* GPIO 4 */
+		/* Focus button */
+		qcom,mode = <0>;		/* Digital input */
+		qcom,pull = <0>;		/* Pull up 30 uA */
+		qcom,vin-sel = <2>;		/* PMA8084 S4 = 1.8 V */
+		qcom,src-sel = <0>;		/* Constant */
+		qcom,master-en = <1>;
+	};
+
+	gpio@c400 { /* GPIO 5 */
+		/* Volume up button */
+		qcom,mode = <0>;		/* Digital input */
+		qcom,pull = <0>;		/* Pull up 30 uA */
+		qcom,vin-sel = <2>;		/* PMA8084 S4 = 1.8 V */
+		qcom,src-sel = <0>;		/* Constant */
+		qcom,master-en = <1>;
+	};
+
+	gpio@c500 { /* GPIO 6 */
+		/* Flash LED now */
+		qcom,mode = <0>;		/* Digital input */
+		qcom,pull = <4>;		/* Pull down */
+		qcom,master-en = <1>;
+	};
+
+	gpio@c600 { /* GPIO 7 */
+		/* GRFC_12 */
+	};
+
+	gpio@c700 { /* GPIO 8 */
+		/* Unused */
+		qcom,mode = <0>;		/* Digital input */
+		qcom,pull = <0>;		/* Pull up 30 uA */
+		qcom,master-en = <1>;
+	};
+
+	gpio@c800 { /* GPIO 9 */
+		/* Unused */
+		qcom,mode = <1>;		/* Digital output */
+		qcom,out-strength = <1>;	/* Low */
+		qcom,src-sel = <2>;		/* Function 1  */
+		qcom,master-en = <1>;
+	};
+
+	gpio@c900 { /* GPIO 10 */
+		/* NFC clock request */
+		qcom,mode = <0>;		/* Digital input */
+		qcom,pull = <4>;		/* Pull down */
+		qcom,master-en = <1>;
+	};
+
+	gpio@ca00 { /* GPIO 11 */
+		/* Unused */
+		qcom,mode = <1>;		/* Digital output */
+		qcom,out-strength = <1>;	/* Low */
+		qcom,src-sel = <2>;		/* Function 1  */
+		qcom,master-en = <1>;
+	};
+
+	gpio@cb00 { /* GPIO 12 */
+		/* Unused */
+		qcom,mode = <1>;		/* Digital output */
+		qcom,out-strength = <1>;	/* Low */
+		qcom,src-sel = <2>;		/* Function 1  */
+		qcom,master-en = <1>;
+	};
+
+	gpio@cc00 { /* GPIO 13 */
+		/* TS_CHGR_IN */
+		qcom,mode = <0>;		/* Digital input */
+		qcom,pull = <4>;		/* Pull down */
+		qcom,master-en = <1>;
+	};
+
+	gpio@cd00 { /* GPIO 14 */
+		/* Unused */
+		qcom,mode = <1>;		/* Digital output */
+		qcom,out-strength = <1>;	/* Low */
+		qcom,src-sel = <2>;		/* Function 1  */
+		qcom,master-en = <1>;
+	};
+
+	gpio@ce00 { /* GPIO 15 */
+		/* Codec clock */
+		qcom,mode = <1>;		/* Digital output */
+		qcom,output-type = <0>;		/* CMOS */
+		qcom,vin-sel = <2>;		/* PMA8084 S4 = 1.8 V */
+		qcom,out-strength = <1>;	/* Low */
+		qcom,src-sel = <2>;		/* Function 1 - DIVCLK1 */
+		qcom,master-en = <1>;
+	};
+
+	gpio@cf00 { /* GPIO 16 */
+		/* Haptics clock */
+		qcom,mode = <1>;		/* Digital output */
+		qcom,output-type = <0>;		/* CMOS */
+		qcom,vin-sel = <2>;		/* PMA8084 S4 = 1.8 V */
+		qcom,out-strength = <3>;	/* High */
+		qcom,src-sel = <3>;       	/* Function 2 - SLEEPCLK3  */
+		qcom,master-en = <1>;
+	};
+
+	gpio@d000 { /* GPIO 17 */
+		/* QPA clock */
+	};
+
+	gpio@d100 { /* GPIO 18 */
+		/* Unused */
+	};
+
+	gpio@d200 { /* GPIO 19 */
+		/* BOOST_BYP */
+	};
+
+	gpio@d300 { /* GPIO 20 */
+		/* Display enable */
+		qcom,mode = <1>;		/* Digital output */
+		qcom,output-type = <0>;		/* CMOS */
+		qcom,vin-sel = <2>;		/* PMA8084 S4 = 1.8 V */
+		qcom,out-strength = <1>;	/* Low */
+		qcom,src-sel = <0>;		/* Constant */
+		qcom,master-en = <1>;
+	};
+
+	gpio@d400 { /* GPIO 21 */
+		/* BATT_GONE */
+	};
+
+	gpio@d500 { /* GPIO 22 */
+		/* BATT_REM_ALARM */
+	};
+};
+
+&pma8084_mpps {
+	mpp@a000 { /* MPP 1 */
+		/* SDC_UIM_VBIAS */
+		status = "disabled";
+	};
+
+	mpp@a100 { /* MPP 2 */
+		/* PM8941_PON_1 */
+	};
+
+	mpp@a200 { /* MPP 3 */
+		/* VREF_DAC */
+	};
+
+	mpp@a300 { /* MPP 4 */
+		/* Unused */
+	};
+
+	mpp@a400 { /* MPP 5 */
+		/* Unused */
+	};
+
+	mpp@a500 { /* MPP 6 */
+		/* SPI ethernet enable */
+		qcom,mode = <1>;		/* Digital output */
+		qcom,output-type = <0>;		/* CMOS */
+		qcom,vin-sel = <2>;		/* PMA8084 S4 = 1.8V > 1.6V */
+		qcom,src-sel = <0>;		/* Constant */
+		qcom,out-strength = <1>;	/* Low */
+		qcom,master-en = <1>;
+	};
+
+	mpp@a600 { /* MPP 7 */
+		/* NFC disable */
+		qcom,mode = <1>;		/* Digital output */
+		qcom,out-strength = <1>;	/* Low */
+		qcom,master-en = <1>;
+	};
+
+	mpp@a700 { /* MPP 8 */
+		/* Unused */
+		qcom,mode = <1>;		/* Digital output */
+		qcom,out-strength = <1>;	/* Low */
+		qcom,master-en = <1>;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ac-pm8941.dtsi b/arch/arm/boot/dts/msm8974pro-ac-pm8941.dtsi
new file mode 100644
index 0000000..4d10ded
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974pro-ac-pm8941.dtsi
@@ -0,0 +1,250 @@
+/* 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/ "msm8974pro-ac.dtsi"
+&spmi_bus {
+	pm8941_lsid0: qcom,pm8941@2 {
+		reg = <0x2>;
+	};
+	pm8941_lsid1: qcom,pm8941@3 {
+		reg = <0x3>;
+	};
+};
+/include/ "msm-pm8941.dtsi"
+
+&pma8084_vadc {
+	status = "disabled";
+};
+
+&pma8084_adc_tm {
+	status = "disabled";
+};
+
+&pm8941_lsid0 {
+	qcom,power-on@800 {
+		status = "disabled";
+	};
+
+	clkdiv@5b00 {
+		status = "disabled";
+	};
+
+	clkdiv@5c00 {
+		status = "disabled";
+	};
+
+	clkdiv@5d00 {
+		status = "disabled";
+	};
+
+	qcom,pm8941_rtc {
+		status = "disabled";
+	};
+
+	gpios {
+		status = "disabled";
+	};
+
+	mpps {
+		status = "disabled";
+	};
+};
+
+&pm8941_lsid1 {
+	pm8941_boost: regulator@a000 {
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		qcom,enable-time = <500>;
+		status = "okay";
+	};
+
+	pm8941_mvs1: regulator@8300 {
+		parent-supply = <&pm8941_chg_otg>;
+		qcom,enable-time = <1000>;
+		qcom,pull-down-enable = <1>;
+		interrupts = <0x3 0x83 0x2>;
+		interrupt-names = "ocp";
+		qcom,ocp-enable = <1>;
+		qcom,ocp-max-retries = <10>;
+		qcom,ocp-retry-delay = <30>;
+		qcom,soft-start-enable = <1>;
+		qcom,vs-soft-start-strength = <0>;
+		qcom,hpm-enable = <1>;
+		qcom,auto-mode-enable = <0>;
+		status = "okay";
+	};
+};
+
+&pma8084_mvs1 {
+	parent-supply = <&pm8941_boost>;
+};
+
+&pm8941_chg {
+	otg-parent-supply = <&pm8941_boost>;
+};
+
+&pm8941_chg_boost {
+	regulator-min-microvolt = <5000000>;
+	regulator-max-microvolt = <5000000>;
+	regulator-name = "8941_smbb_boost";
+};
+
+&pm8941_chg_otg {
+	regulator-name = "8941_smbb_otg";
+};
+
+/* Correct PM8941 local slave ID 0 to use global SID 4 for all interrupts. */
+&pm8941_lsid0 {
+	qcom,temp-alarm@2400 {
+		interrupts = <0x2 0x24 0x0>;
+	};
+
+	qcom,power-on@800 {
+		interrupts = <0x2 0x8 0x0>,
+			     <0x2 0x8 0x1>,
+			     <0x2 0x8 0x4>,
+			     <0x2 0x8 0x5>;
+		interrupt-names = "kpdpwr", "resin",
+				"resin-bark", "kpdpwr-resin-bark";
+	};
+
+	qcom,bsi@1b00 {
+		interrupts = <0x2 0x1b 0x0>,
+			     <0x2 0x1b 0x1>,
+			     <0x2 0x1b 0x2>,
+			     <0x2 0x12 0x0>;
+		interrupt-names = "err",
+				  "rx",
+				  "tx",
+				  "batt-present";
+	};
+
+	qcom,bms {
+		qcom,bms-bms@4000 {
+			interrupts =	<0x2 0x40 0x0>,
+					<0x2 0x40 0x1>,
+					<0x2 0x40 0x2>,
+					<0x2 0x40 0x3>,
+					<0x2 0x40 0x4>,
+					<0x2 0x40 0x5>,
+					<0x2 0x40 0x6>,
+					<0x2 0x40 0x7>;
+			interrupt-names = "cc_thr",
+					  "ocv_for_r",
+					  "good_ocv",
+					  "charge_begin",
+					  "ocv_thr",
+					  "sw_cc_thr",
+					  "vsense_avg",
+					  "vsense_for_r";
+		};
+	};
+
+	qcom,charger {
+		qcom,chgr@1000 {
+			interrupts =	<0x2 0x10 0x0>,
+					<0x2 0x10 0x1>,
+					<0x2 0x10 0x2>,
+					<0x2 0x10 0x3>,
+					<0x2 0x10 0x4>,
+					<0x2 0x10 0x5>,
+					<0x2 0x10 0x6>,
+					<0x2 0x10 0x7>;
+			interrupt-names =	"vbat-det-lo",
+						"vbat-det-hi",
+						"chgwdog",
+						"state-change",
+						"trkl-chg-on",
+						"fast-chg-on",
+						"chg-failed",
+						"chg-done";
+		};
+
+		qcom,buck@1100 {
+			interrupts =	<0x2 0x11 0x0>,
+					<0x2 0x11 0x1>,
+					<0x2 0x11 0x2>,
+					<0x2 0x11 0x3>,
+					<0x2 0x11 0x4>,
+					<0x2 0x11 0x5>,
+					<0x2 0x11 0x6>;
+			interrupt-names =	"vbat-ov",
+						"vreg-ov",
+						"overtemp",
+						"vchg-loop",
+						"ichg-loop",
+						"ibat-loop",
+						"vdd-loop";
+		};
+
+		qcom,bat-if@1200 {
+			interrupts =	<0x2 0x12 0x0>,
+					<0x2 0x12 0x1>,
+					<0x2 0x12 0x2>,
+					<0x2 0x12 0x3>,
+					<0x2 0x12 0x4>;
+			interrupt-names =	"batt-pres",
+						"bat-temp-ok",
+						"bat-fet-on",
+						"vcp-on",
+						"psi";
+		};
+
+		qcom,usb-chgpth@1300 {
+			interrupts =	<0x2 0x13 0x0>,
+					<0x2 0x13 0x1>,
+					<0x2 0x13 0x2>;
+			interrupt-names =	"coarse-det-usb",
+						"usbin-valid",
+						"chg-gone";
+		};
+
+		qcom,dc-chgpth@1400 {
+			interrupts =	<0x2 0x14 0x0>,
+					<0x2 0x14 0x1>;
+			interrupt-names =	"coarse-det-dc",
+						"dcin-valid";
+		};
+
+		qcom,boost@1500 {
+			interrupts =	<0x2 0x15 0x0>,
+					<0x2 0x15 0x1>;
+			interrupt-names =	"boost-pwr-ok",
+						"limit-error";
+		};
+	};
+
+	qcom,pm8941_rtc {
+		qcom,pm8941_rtc_alarm@6100 {
+			interrupts = <0x2 0x61 0x1>;
+		};
+	};
+
+	vadc@3100 {
+		interrupts = <0x2 0x31 0x0>;
+		interrupt-names = "eoc-int-en-set";
+	};
+
+	iadc@3600 {
+		interrupts = <0x2 0x36 0x0>;
+		interrupt-names = "eoc-int-en-set";
+	};
+
+	qcom,vadc@3400 {
+		interrupts =	<0x2 0x34 0x0>,
+				<0x2 0x34 0x3>,
+				<0x2 0x34 0x4>;
+		interrupt-names =	"eoc-int-en-set",
+					"high-thr-en-set",
+					"low-thr-en-set";
+	};
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ac-regulator.dtsi b/arch/arm/boot/dts/msm8974pro-ac-regulator.dtsi
new file mode 100644
index 0000000..9d7f316
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974pro-ac-regulator.dtsi
@@ -0,0 +1,566 @@
+/* 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_mvs1: regulator@8400 {
+			qcom,enable-time = <1000>;
+			qcom,pull-down-enable = <1>;
+			interrupts = <0x1 0x84 0x2>;
+			interrupt-names = "ocp";
+			qcom,ocp-enable = <1>;
+			qcom,ocp-max-retries = <10>;
+			qcom,ocp-retry-delay = <30>;
+			qcom,soft-start-enable = <1>;
+			qcom,vs-soft-start-strength = <0>;
+			qcom,hpm-enable = <1>;
+			qcom,auto-mode-enable = <0>;
+			status = "okay";
+		};
+	};
+};
+
+/* RPM controlled regulators: */
+
+&rpm_bus {
+	rpm-regulator-smpa1 {
+		status = "okay";
+		pma8084_s1: regulator-s1 {
+			regulator-min-microvolt = <675000>;
+			regulator-max-microvolt = <1050000>;
+			status = "okay";
+		};
+		pma8084_s1_ao: regulator-s1-ao {
+			regulator-name = "8084_s1_ao";
+			qcom,set = <1>;
+			regulator-min-microvolt = <675000>;
+			regulator-max-microvolt = <1050000>;
+			status = "okay";
+			compatible = "qcom,rpm-regulator-smd";
+		};
+		pma8084_s1_so: regulator-s1-so {
+			regulator-name = "8084_s1_so";
+			qcom,set = <2>;
+			regulator-min-microvolt = <675000>;
+			regulator-max-microvolt = <1050000>;
+			qcom,init-voltage = <675000>;
+			status = "okay";
+			compatible = "qcom,rpm-regulator-smd";
+		};
+	};
+
+	rpm-regulator-smpa2 {
+		status = "okay";
+		pma8084_s2: regulator-s2 {
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1050000>;
+			status = "okay";
+		};
+		pma8084_s2_corner: regulator-s2-corner {
+			regulator-name = "8084_s2_corner";
+			qcom,set = <3>;
+			regulator-min-microvolt = <1>;
+			regulator-max-microvolt = <7>;
+			qcom,use-voltage-corner;
+			compatible = "qcom,rpm-regulator-smd";
+			qcom,consumer-supplies = "vdd_dig", "";
+		};
+		pma8084_s2_corner_ao: regulator-s2-corner-ao {
+			regulator-name = "8084_s2_corner_ao";
+			qcom,set = <1>;
+			regulator-min-microvolt = <1>;
+			regulator-max-microvolt = <7>;
+			qcom,use-voltage-corner;
+			compatible = "qcom,rpm-regulator-smd";
+		};
+		pma8084_s2_floor_corner: regulator-s2-floor-corner {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_s2_floor_corner";
+			qcom,set = <3>;
+			regulator-min-microvolt = <1>;
+			regulator-max-microvolt = <7>;
+			qcom,use-voltage-floor-corner;
+			qcom,always-send-voltage;
+		};
+	};
+
+
+	rpm-regulator-smpa3 {
+		status = "okay";
+		pma8084_s3: regulator-s3 {
+			regulator-min-microvolt = <1300000>;
+			regulator-max-microvolt = <1300000>;
+			qcom,init-voltage = <1300000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-smpa4 {
+		status = "okay";
+		pma8084_s4: regulator-s4 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,init-voltage = <1800000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-smpa5 {
+		status = "okay";
+		pma8084_s5: regulator-s5 {
+			regulator-min-microvolt = <2150000>;
+			regulator-max-microvolt = <2150000>;
+			qcom,init-voltage = <2150000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-smpa6 {
+		status = "okay";
+		pma8084_s6: regulator-s6 {
+			regulator-min-microvolt = <1050000>;
+			regulator-max-microvolt = <1050000>;
+			qcom,init-voltage = <1050000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-smpa7 {
+		status = "okay";
+		pma8084_s7: regulator-s7 {
+			regulator-min-microvolt = <815000>;
+			regulator-max-microvolt = <900000>;
+			status = "okay";
+		};
+		pma8084_s7_corner: regulator-s7-corner {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_s7_corner";
+			qcom,set = <3>;
+			qcom,use-voltage-corner;
+			regulator-min-microvolt = <1>;
+			regulator-max-microvolt = <7>;
+			qcom,init-voltage-corner = <3>; /* SVS SOC */
+		};
+		pma8084_s7_floor_corner: regulator-s7-floor-corner {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_s7_floor_corner";
+			qcom,set = <3>;
+			regulator-min-microvolt = <1>;
+			regulator-max-microvolt = <7>;
+			qcom,use-voltage-floor-corner;
+			qcom,always-send-voltage;
+		};
+	};
+
+	rpm-regulator-ldoa1 {
+		status = "okay";
+		pma8084_l1: regulator-l1 {
+			regulator-min-microvolt = <1225000>;
+			regulator-max-microvolt = <1225000>;
+			qcom,init-voltage = <1225000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa2 {
+		status = "okay";
+		pma8084_l2: regulator-l2 {
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			qcom,init-voltage = <1200000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa3 {
+		status = "okay";
+		pma8084_l3: regulator-l3 {
+			regulator-min-microvolt = <1225000>;
+			regulator-max-microvolt = <1225000>;
+			qcom,init-voltage = <1225000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa4 {
+		status = "okay";
+		pma8084_l4: regulator-l4 {
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1225000>;
+			qcom,init-voltage = <1225000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa5 {
+		status = "okay";
+		pma8084_l5: regulator-l5 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,init-voltage = <1800000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa6 {
+		status = "okay";
+		pma8084_l6: regulator-l6 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,init-voltage = <1800000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa7 {
+		status = "okay";
+		pma8084_l7: regulator-l7 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,init-voltage = <1800000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa8 {
+		status = "okay";
+		pma8084_l8: regulator-l8 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,init-voltage = <1800000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa9 {
+		status = "okay";
+		pma8084_l9: regulator-l9 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2950000>;
+			qcom,init-voltage = <2950000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa10 {
+		status = "okay";
+		pma8084_l10: regulator-l10 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2950000>;
+			qcom,init-voltage = <2950000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa11 {
+		status = "okay";
+		pma8084_l11: regulator-l11 {
+			regulator-min-microvolt = <1300000>;
+			regulator-max-microvolt = <1300000>;
+			qcom,init-voltage = <1300000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa12 {
+		status = "okay";
+		pma8084_l12: regulator-l12 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			status = "okay";
+		};
+		pma8084_l12_ao: regulator-l12-ao {
+			regulator-name = "8084_l12_ao";
+			qcom,set = <1>;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			status = "okay";
+			compatible = "qcom,rpm-regulator-smd";
+		};
+	};
+
+	rpm-regulator-ldoa13 {
+		status = "okay";
+		pma8084_l13: regulator-l13 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2950000>;
+			qcom,init-voltage = <2950000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa14 {
+		status = "okay";
+		pma8084_l14: regulator-l14 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,init-voltage = <1800000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa15 {
+		status = "okay";
+		pma8084_l15: regulator-l15 {
+			regulator-min-microvolt = <2050000>;
+			regulator-max-microvolt = <2050000>;
+			qcom,init-voltage = <2050000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa16 {
+		status = "okay";
+		pma8084_l16: regulator-l16 {
+			regulator-min-microvolt = <2700000>;
+			regulator-max-microvolt = <2700000>;
+			qcom,init-voltage = <2700000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa17 {
+		status = "okay";
+		pma8084_l17: regulator-l17 {
+			regulator-min-microvolt = <2850000>;
+			regulator-max-microvolt = <2850000>;
+			qcom,init-voltage = <2850000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa18 {
+		status = "okay";
+		pma8084_l18: regulator-l18 {
+			regulator-min-microvolt = <2850000>;
+			regulator-max-microvolt = <2850000>;
+			qcom,init-voltage = <2850000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa19 {
+		status = "okay";
+		pma8084_l19: regulator-l19 {
+			regulator-min-microvolt = <2900000>;
+			regulator-max-microvolt = <3300000>;
+			qcom,init-voltage = <2900000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa20 {
+		status = "okay";
+		pma8084_l20: regulator-l20 {
+			regulator-min-microvolt = <2950000>;
+			regulator-max-microvolt = <2950000>;
+			qcom,init-voltage = <2950000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa21 {
+		status = "okay";
+		pma8084_l21: regulator-l21 {
+			regulator-min-microvolt = <2950000>;
+			regulator-max-microvolt = <2950000>;
+			qcom,init-voltage = <2950000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa22 {
+		status = "okay";
+		pma8084_l22: regulator-l22 {
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3000000>;
+			qcom,init-voltage = <3000000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa23 {
+		status = "okay";
+		pma8084_l23: regulator-l23 {
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3000000>;
+			qcom,init-voltage = <3000000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa24 {
+		status = "okay";
+		pma8084_l24: regulator-l24 {
+			regulator-min-microvolt = <3075000>;
+			regulator-max-microvolt = <3075000>;
+			qcom,init-voltage = <3075000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa25 {
+		status = "okay";
+		pma8084_l25: regulator-l25 {
+			regulator-min-microvolt = <2100000>;
+			regulator-max-microvolt = <2100000>;
+			qcom,init-voltage = <2100000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa26 {
+		status = "okay";
+		pma8084_l26: regulator-l26 {
+			regulator-min-microvolt = <2050000>;
+			regulator-max-microvolt = <2050000>;
+			qcom,init-voltage = <2050000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa27 {
+		status = "okay";
+		pma8084_l27: regulator-l27 {
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1225000>;
+			qcom,init-voltage = <1200000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-vsa1 {
+		status = "okay";
+		pma8084_lvs1: regulator-lvs1 {
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-vsa2 {
+		status = "okay";
+		pma8084_lvs2: regulator-lvs2 {
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-vsa3 {
+		status = "okay";
+		pma8084_lvs3: regulator-lvs3 {
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-vsa4 {
+		status = "okay";
+		pma8084_lvs4: regulator-lvs4 {
+			status = "okay";
+		};
+	};
+};
+
+&soc {
+	krait_pdn: krait-pdn@f9011000 {
+		reg = <0xf9011000 0x1000>,
+		      <0xfc4b80b0 8>;
+		reg-names = "apcs_gcc", "phase-scaling-efuse";
+		compatible = "qcom,krait-pdn";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		qcom,pfm-threshold = <73>;
+
+		krait0_vreg: regulator@f9088000 {
+			compatible = "qcom,krait-regulator";
+			regulator-name = "krait0";
+			reg = <0xf9088000 0x1000>, /* APCS_ALIAS0_KPSS_ACS */
+				<0xf908a800 0x1000>; /* APCS_ALIAS0_KPSS_MDD */
+			reg-names = "acs", "mdd";
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1100000>;
+			qcom,headroom-voltage = <150000>;
+			qcom,retention-voltage = <675000>;
+			qcom,ldo-default-voltage = <750000>;
+			qcom,ldo-threshold-voltage = <850000>;
+			qcom,ldo-delta-voltage = <50000>;
+			qcom,cpu-num = <0>;
+		};
+
+		krait1_vreg: regulator@f9098000 {
+			compatible = "qcom,krait-regulator";
+			regulator-name = "krait1";
+			reg = <0xf9098000 0x1000>, /* APCS_ALIAS1_KPSS_ACS */
+				<0xf909a800 0x1000>; /* APCS_ALIAS1_KPSS_MDD */
+			reg-names = "acs", "mdd";
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1100000>;
+			qcom,headroom-voltage = <150000>;
+			qcom,retention-voltage = <675000>;
+			qcom,ldo-default-voltage = <750000>;
+			qcom,ldo-threshold-voltage = <850000>;
+			qcom,ldo-delta-voltage = <50000>;
+			qcom,cpu-num = <1>;
+		};
+
+		krait2_vreg: regulator@f90a8000 {
+			compatible = "qcom,krait-regulator";
+			regulator-name = "krait2";
+			reg = <0xf90a8000 0x1000>, /* APCS_ALIAS2_KPSS_ACS */
+				<0xf90aa800 0x1000>; /* APCS_ALIAS2_KPSS_MDD */
+			reg-names = "acs", "mdd";
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1100000>;
+			qcom,headroom-voltage = <150000>;
+			qcom,retention-voltage = <675000>;
+			qcom,ldo-default-voltage = <750000>;
+			qcom,ldo-threshold-voltage = <850000>;
+			qcom,ldo-delta-voltage = <50000>;
+			qcom,cpu-num = <2>;
+		};
+
+		krait3_vreg: regulator@f90b8000 {
+			compatible = "qcom,krait-regulator";
+			regulator-name = "krait3";
+			reg = <0xf90b8000 0x1000>, /* APCS_ALIAS3_KPSS_ACS */
+				<0xf90ba800 0x1000>; /* APCS_ALIAS3_KPSS_MDD */
+			reg-names = "acs", "mdd";
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1100000>;
+			qcom,headroom-voltage = <150000>;
+			qcom,retention-voltage = <675000>;
+			qcom,ldo-default-voltage = <750000>;
+			qcom,ldo-threshold-voltage = <850000>;
+			qcom,ldo-delta-voltage = <50000>;
+			qcom,cpu-num = <3>;
+		};
+	};
+
+	/* SPI expects a regulator device, but no hardware is present. */
+	spi_eth_vreg: spi_eth_phy_vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "ethernet_phy";
+		regulator-always-on;
+	};
+
+	/*
+	 * vph_pwr_vreg represents the unregulated battery voltage supply
+	 * VPH_PWR that is present whenever the device is powered on.
+	 */
+	vph_pwr_vreg: vph_pwr_vreg {
+		compatible = "regulator-fixed";
+		status = "disabled";
+		regulator-name = "vph_pwr";
+		regulator-always-on;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ac.dtsi b/arch/arm/boot/dts/msm8974pro-ac.dtsi
index 9240514..cca34fb 100644
--- a/arch/arm/boot/dts/msm8974pro-ac.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-ac.dtsi
@@ -17,3 +17,174 @@
  */
 
 /include/ "msm8974pro.dtsi"
+
+/include/ "msm-pma8084-rpm-regulator.dtsi"
+/include/ "msm-pma8084.dtsi"
+/include/ "msm8974pro-ac-regulator.dtsi"
+
+/*
+ * Override PM8841 and PM8941 resources with proper PMA8084 resources for
+ * MSM8974Pro AC.
+ */
+
+&soc {
+	qcom,csid@fda08000  {
+		qcom,mipi-csi-vdd-supply = <&pma8084_l12>;
+	};
+
+	qcom,csid@fda08400 {
+		qcom,mipi-csi-vdd-supply = <&pma8084_l12>;
+	};
+
+	qcom,csid@fda08800 {
+		qcom,mipi-csi-vdd-supply = <&pma8084_l12>;
+	};
+
+	qcom,csid@fda08C00 {
+		qcom,mipi-csi-vdd-supply = <&pma8084_l12>;
+	};
+
+	tpiu@fc318000 {
+		vdd-supply = <&pma8084_l21>;
+	};
+
+	qcom,mdss_dsi@fd922800 {
+		vdd-supply = <&pma8084_l22>;
+		vddio-supply = <&pma8084_l12>;
+		vdda-supply = <&pma8084_l2>;
+	};
+
+	qcom,mdss_dsi@fd922e00 {
+		vdd-supply = <&pma8084_l22>;
+		vddio-supply = <&pma8084_l12>;
+		vdda-supply = <&pma8084_l2>;
+	};
+
+	qcom,hdmi_tx@fd922100 {
+		hpd-5v-supply = <&pma8084_mvs1>;
+		core-vdda-supply = <&pma8084_l12>;
+		core-vcc-supply = <&pma8084_s4>;
+	};
+
+	qcom,mdss_edp@fd923400 {
+		vdda-supply = <&pma8084_l12>;
+	};
+
+	usb@f9a55000 {
+		HSUSB_VDDCX-supply = <&pma8084_s2_corner>;
+		HSUSB_1p8-supply = <&pma8084_l6>;
+		HSUSB_3p3-supply = <&pma8084_l24>;
+	};
+
+	qcom,sdcc@f9824000 {
+		vdd-supply = <&pma8084_l20>;
+		vdd-io-supply = <&pma8084_s4>;
+	};
+
+	qcom,sdcc@f98a4000 {
+		vdd-supply = <&pma8084_l21>;
+		vdd-io-supply = <&pma8084_l13>;
+	};
+
+	slim@fe12f000 {
+		taiko_codec {
+			cdc-vdd-buck-supply = <&pma8084_s5>;
+			cdc-vdd-tx-h-supply = <&pma8084_s4>;
+			cdc-vdd-rx-h-supply = <&pma8084_s4>;
+			cdc-vddpx-1-supply = <&pma8084_s4>;
+			cdc-vdd-a-1p2v-supply = <&pma8084_l1>;
+			cdc-vddcx-1-supply = <&pma8084_l1>;
+			cdc-vddcx-2-supply = <&pma8084_l1>;
+		};
+	};
+
+	qcom,acpuclk@f9000000 {
+		krait0_mem-supply = <&pma8084_s1_ao>;
+		krait1_mem-supply = <&pma8084_s1_ao>;
+		krait2_mem-supply = <&pma8084_s1_ao>;
+		krait3_mem-supply = <&pma8084_s1_ao>;
+		krait0_dig-supply = <&pma8084_s2_corner_ao>;
+		krait1_dig-supply = <&pma8084_s2_corner_ao>;
+		krait2_dig-supply = <&pma8084_s2_corner_ao>;
+		krait3_dig-supply = <&pma8084_s2_corner_ao>;
+		krait0_hfpll-supply = <&pma8084_l12_ao>;
+		krait1_hfpll-supply = <&pma8084_l12_ao>;
+		krait2_hfpll-supply = <&pma8084_l12_ao>;
+		krait3_hfpll-supply = <&pma8084_l12_ao>;
+		l2_hfpll-supply = <&pma8084_l12_ao>;
+	};
+
+	qcom,ssusb@f9200000 {
+		ssusb_vdd_dig-supply = <&pma8084_s2_corner>;
+		SSUSB_1p8-supply = <&pma8084_l6>;
+		hsusb_vdd_dig-supply = <&pma8084_s2_corner>;
+		HSUSB_1p8-supply = <&pma8084_l6>;
+		HSUSB_3p3-supply = <&pma8084_l24>;
+	};
+
+	qcom,ehci-host@f9a55000 {
+		HSUSB_VDDCX-supply = <&pma8084_s2>;
+		HSUSB_1p8-supply = <&pma8084_l6>;
+		HSUSB_3p3-supply = <&pma8084_l24>;
+	};
+
+	qcom,gdsc@fd8c4024 {
+		parent-supply = <&pma8084_s7_corner>;
+	};
+
+	qcom,lpass@fe200000 {
+		vdd_cx-supply = <&pma8084_s2_corner>;
+	};
+
+	qcom,mss@fc880000 {
+		vdd_mss-supply = <&pma8084_s6>;
+		vdd_cx-supply = <&pma8084_s2_corner>;
+		vdd_mx-supply = <&pma8084_s1>;
+		vdd_pll-supply = <&pma8084_l12>;
+	};
+
+	qcom,pronto@fb21b000 {
+		vdd_pronto_pll-supply = <&pma8084_l12>;
+	};
+
+	qcom,wcnss-wlan@fb000000 {
+		qcom,pronto-vddmx-supply = <&pma8084_s1>;
+		qcom,pronto-vddcx-supply = <&pma8084_s2>;
+		qcom,pronto-vddpx-supply = <&pma8084_s4>;
+		qcom,iris-vddxo-supply = <&pma8084_l6>;
+		qcom,iris-vddrfa-supply = <&pma8084_l11>;
+		qcom,iris-vddpa-supply = <&pma8084_l19>;
+		qcom,iris-vdddig-supply = <&pma8084_s4>;
+	};
+
+	qcom,msm-thermal {
+		vdd_dig-supply = <&pma8084_s2_floor_corner>;
+		vdd_gfx-supply = <&pma8084_s7_floor_corner>;
+	};
+
+	qcom,lpm-resources {
+		qcom,lpm-resources@0 {
+			qcom,name = "vdd-dig";
+			qcom,type = <0x61706d73>;	/* "smpa" */
+			qcom,id = <2>;
+		};
+
+		qcom,lpm-resources@1 {
+			qcom,name = "vdd-mem";
+			qcom,type = <0x61706d73>;	/* "smpa" */
+			qcom,id = <1>;
+		};
+	};
+
+	sound {
+		qcom,cdc-mclk-gpios = <&pma8084_gpios 15 0>;
+	};
+};
+
+&krait_pdn {
+	qcom,use-phase-switching;
+};
+
+&tspp {
+	vdd_cx-supply = <&pma8084_s2_corner>;
+};
diff --git a/arch/arm/boot/dts/msm8974pro.dtsi b/arch/arm/boot/dts/msm8974pro.dtsi
index 96e78ac..b80eb0f 100644
--- a/arch/arm/boot/dts/msm8974pro.dtsi
+++ b/arch/arm/boot/dts/msm8974pro.dtsi
@@ -37,7 +37,7 @@
 /* GPU overrides */
 &msm_gpu {
 	/* Updated chip ID */
-	qcom,chipid = <0x03030001>;
+	qcom,chipid = <0x03030002>;
 
 	/* Updated bus bandwidth requirements */
 	qcom,msm-bus,vectors-KBps =
@@ -53,6 +53,55 @@
 		<26 512 0 7464000>, <89 604 0 5120000>,
 		/* Turbo */
 		<26 512 0 7464000>, <89 604 0 6400000>;
+
+       qcom,gpu-pwrlevels {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               compatible = "qcom,gpu-pwrlevels";
+
+               qcom,gpu-pwrlevel@0 {
+                       reg = <0>;
+                       qcom,gpu-freq = <550000000>;
+                       qcom,bus-freq = <5>;
+                       qcom,io-fraction = <33>;
+               };
+
+               qcom,gpu-pwrlevel@1 {
+                       reg = <1>;
+                       qcom,gpu-freq = <320000000>;
+                       qcom,bus-freq = <4>;
+                       qcom,io-fraction = <66>;
+               };
+
+               qcom,gpu-pwrlevel@2 {
+                       reg = <2>;
+                       qcom,gpu-freq = <320000000>;
+                       qcom,bus-freq = <3>;
+                       qcom,io-fraction = <66>;
+               };
+
+               qcom,gpu-pwrlevel@3 {
+                       reg = <3>;
+                       qcom,gpu-freq = <200000000>;
+                       qcom,bus-freq = <2>;
+                       qcom,io-fraction = <100>;
+               };
+
+               qcom,gpu-pwrlevel@4 {
+                       reg = <4>;
+                       qcom,gpu-freq = <200000000>;
+                       qcom,bus-freq = <1>;
+                       qcom,io-fraction = <100>;
+               };
+
+               qcom,gpu-pwrlevel@5 {
+                       reg = <5>;
+                       qcom,gpu-freq = <27000000>;
+                       qcom,bus-freq = <0>;
+                       qcom,io-fraction = <0>;
+               };
+       };
 };
 
 &mdss_mdp {
@@ -128,11 +177,3 @@
 					<0x42 0x2>,
 					<0x120 0x3>;
 };
-
-&krait_pdn {
-	qcom,use-phase-switching;
-};
-
-&tspp {
-	vdd_cx-supply = <&pm8841_s2_corner>;
-};
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 68f639f..f5e930d 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -173,7 +173,7 @@
 		qcom,msm-bus,vectors-KBps =
 				<87 512 0 0>,
 				<87 512 40000 640000>;
-		qcom,hsusb-log2-itc = <5>;
+		qcom,hsusb-log2-itc = <4>;
 	};
 
 	hsic_host: hsic@f9a15000 {
diff --git a/arch/arm/boot/dts/msmkrypton.dtsi b/arch/arm/boot/dts/msmkrypton.dtsi
index ba6377c..35d6d2a 100644
--- a/arch/arm/boot/dts/msmkrypton.dtsi
+++ b/arch/arm/boot/dts/msmkrypton.dtsi
@@ -50,6 +50,11 @@
 		reg = <0xfe807800 0x1000>; /* Address and size of IMEM */
 	};
 
+	qcom,msm-mem-hole {
+		compatible = "qcom,msm-mem-hole";
+		qcom,memblock-remove = <0x02000000 0x06000000>; /* Address and Size of Hole */
+	};
+
 	timer@f9020000 {
 		#address-cells = <1>;
 		#size-cells = <1>;
diff --git a/arch/arm/boot/dts/msmsamarium-sim.dts b/arch/arm/boot/dts/msmsamarium-sim.dts
index 4acffae..d23bd89 100644
--- a/arch/arm/boot/dts/msmsamarium-sim.dts
+++ b/arch/arm/boot/dts/msmsamarium-sim.dts
@@ -53,3 +53,7 @@
 
 	status = "ok";
 };
+
+&usb_otg {
+	status = "ok";
+};
diff --git a/arch/arm/boot/dts/msmsamarium.dtsi b/arch/arm/boot/dts/msmsamarium.dtsi
index e743989..fdf2680 100644
--- a/arch/arm/boot/dts/msmsamarium.dtsi
+++ b/arch/arm/boot/dts/msmsamarium.dtsi
@@ -177,6 +177,40 @@
 		};
 	};
 
+	android_usb@fe8050c8 {
+		compatible = "qcom,android-usb";
+		reg = <0xfe8050c8 0xc8>;
+		qcom,android-usb-swfi-latency = <1>;
+	};
+
+	usb_otg: usb@f9a55000 {
+		compatible = "qcom,hsusb-otg";
+		status = "disabled";
+
+		reg = <0xf9a55000 0x400>;
+		interrupts = <0 134 0>, <0 140 0>;
+		interrupt-names = "core_irq", "async_irq";
+		HSUSB_VDDCX-supply = "";
+		HSUSB_1p8-supply = "";
+		HSUSB_3p3-supply = "";
+		qcom,vdd-voltage-level = <1 5 7>;
+
+		qcom,hsusb-otg-phy-type = <2>;
+		qcom,hsusb-otg-phy-init-seq =
+			<0x44 0x80 0x68 0x81 0x24 0x82 0x13 0x83 0xffffffff>;
+		qcom,hsusb-otg-mode = <1>;
+		qcom,hsusb-otg-otg-control = <1>;
+		qcom,hsusb-otg-disable-reset;
+
+		qcom,msm-bus,name = "usb2";
+		qcom,msm-bus,num-cases = <3>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<87 512 0 0>,
+				<87 512 60000 960000>,
+				<87 512 6000  6000>;
+	};
+
 	qcom,bam_dmux@fc834000 {
 		compatible = "qcom,bam_dmux";
 		reg = <0xfc834000 0x7000>;
diff --git a/arch/arm/configs/mpq8092_defconfig b/arch/arm/configs/mpq8092_defconfig
index 5d05596..c870208 100644
--- a/arch/arm/configs/mpq8092_defconfig
+++ b/arch/arm/configs/mpq8092_defconfig
@@ -274,6 +274,7 @@
 CONFIG_ION_MSM=y
 CONFIG_MSM_KGSL=y
 CONFIG_FB=y
+CONFIG_FB_VIRTUAL=y
 CONFIG_FB_MSM=y
 # CONFIG_FB_MSM_BACKLIGHT is not set
 CONFIG_FB_MSM_MDSS=y
@@ -334,6 +335,7 @@
 CONFIG_QPNP_CLKDIV=y
 CONFIG_MSM_IOMMU_V1=y
 CONFIG_IOMMU_PGTABLES_L2=y
+CONFIG_IOMMU_NON_SECURE=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT3_FS=y
diff --git a/arch/arm/configs/msm8226-perf_defconfig b/arch/arm/configs/msm8226-perf_defconfig
index 0a4936d..452cd8a 100644
--- a/arch/arm/configs/msm8226-perf_defconfig
+++ b/arch/arm/configs/msm8226-perf_defconfig
@@ -244,6 +244,8 @@
 CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
 CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV=y
 CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE=y
+CONFIG_TOUCHSCREEN_FT5X06=y
+CONFIG_TOUCHSCREEN_GEN_VKEYS=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
 CONFIG_INPUT_GPIO=m
diff --git a/arch/arm/configs/msm8226_defconfig b/arch/arm/configs/msm8226_defconfig
index 1ae95da..fa86cc8 100644
--- a/arch/arm/configs/msm8226_defconfig
+++ b/arch/arm/configs/msm8226_defconfig
@@ -245,6 +245,8 @@
 CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
 CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV=y
 CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE=y
+CONFIG_TOUCHSCREEN_FT5X06=y
+CONFIG_TOUCHSCREEN_GEN_VKEYS=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
 CONFIG_INPUT_GPIO=m
diff --git a/arch/arm/configs/msm8610-perf_defconfig b/arch/arm/configs/msm8610-perf_defconfig
index 29ef385..894b0b9 100644
--- a/arch/arm/configs/msm8610-perf_defconfig
+++ b/arch/arm/configs/msm8610-perf_defconfig
@@ -241,6 +241,7 @@
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_QUP=y
+CONFIG_INPUT_MPU3050=y
 CONFIG_MSM_BUSPM_DEV=m
 CONFIG_SPI=y
 CONFIG_SPI_QUP=y
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index 1e1b35a..505e883 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -239,6 +239,7 @@
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_QUP=y
+CONFIG_INPUT_MPU3050=y
 CONFIG_MSM_BUSPM_DEV=m
 CONFIG_SPI=y
 CONFIG_SPI_QUP=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 174a576..a8eee29 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -429,6 +429,7 @@
 	select GPIO_MSM_V3
 	select MAY_HAVE_SPARSE_IRQ
 	select SPARSE_IRQ
+	select MEMORY_HOLE_CARVEOUT
 
 config ARCH_MSM8610
 	bool "MSM8610"
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 68e9282..e5a2bb84f 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -295,6 +295,7 @@
 obj-$(CONFIG_ARCH_MSM8226) += gdsc.o
 obj-$(CONFIG_ARCH_MSM8610) += gdsc.o
 obj-$(CONFIG_ARCH_MPQ8092) += gdsc.o
+obj-$(CONFIG_ARCH_APQ8084) += gdsc.o
 obj-$(CONFIG_ARCH_MSM8974) += krait-regulator.o
 obj-$(CONFIG_ARCH_MSMKRYPTON) += board-krypton.o board-krypton-gpiomux.o
 obj-$(CONFIG_ARCH_MSMSAMARIUM) += board-samarium.o board-samarium-gpiomux.o
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
index 1ec850f..8b0acc6 100644
--- a/arch/arm/mach-msm/Makefile.boot
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -57,6 +57,7 @@
         dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v2-fluid.dtb
         dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v2-liquid.dtb
         dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v2-mtp.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= apq8074-v2-cdp.dtb
         dtb-$(CONFIG_ARCH_MSM8974)	+= apq8074-v2-liquid.dtb
         dtb-$(CONFIG_ARCH_MSM8974)	+= apq8074-v2-dragonboard.dtb
 
@@ -119,7 +120,8 @@
    zreladdr-$(CONFIG_ARCH_MSM8610)	:= 0x00008000
         dtb-$(CONFIG_ARCH_MSM8610)	+= msm8610-rumi.dtb
         dtb-$(CONFIG_ARCH_MSM8610)	+= msm8610-sim.dtb
-        dtb-$(CONFIG_ARCH_MSM8610)	+= msm8610-qrd.dtb
+        dtb-$(CONFIG_ARCH_MSM8610)	+= msm8610-qrd-skuaa.dtb
+        dtb-$(CONFIG_ARCH_MSM8610)	+= msm8610-qrd-skuab.dtb
 
 # MSMSAMARIUM
    zreladdr-$(CONFIG_ARCH_MSMSAMARIUM)	:= 0x00008000
diff --git a/arch/arm/mach-msm/acpuclock-8974.c b/arch/arm/mach-msm/acpuclock-8974.c
index 98ed2d8..6d848d2 100644
--- a/arch/arm/mach-msm/acpuclock-8974.c
+++ b/arch/arm/mach-msm/acpuclock-8974.c
@@ -270,7 +270,7 @@
 	[7]  = { {  806400, HFPLL, 1,  42 }, LVL_NOM,   950000, 4 },
 	[8]  = { {  883200, HFPLL, 1,  46 }, LVL_NOM,   950000, 5 },
 	[9]  = { {  960000, HFPLL, 1,  50 }, LVL_NOM,   950000, 5 },
-	[10] = { { 1036800, HFPLL, 1,  54 }, LVL_NOM,   950000, 6 },
+	[10] = { { 1036800, HFPLL, 1,  54 }, LVL_NOM,   950000, 5 },
 	[11] = { { 1113600, HFPLL, 1,  58 }, LVL_HIGH, 1050000, 6 },
 	[12] = { { 1190400, HFPLL, 1,  62 }, LVL_HIGH, 1050000, 6 },
 	[13] = { { 1267200, HFPLL, 1,  66 }, LVL_HIGH, 1050000, 7 },
@@ -899,7 +899,7 @@
 	{ 0, { 0 } }
 };
 
-static struct acpu_level acpu_freq_tbl_v3_pvs0[] __initdata = {
+static struct acpu_level acpu_freq_tbl_pro_pvs0[] __initdata = {
 	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000, 999 },
 	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  800000, 999 },
 	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  800000, 999 },
@@ -971,17 +971,48 @@
 	[2][5] = { acpu_freq_tbl_2p2g_pvs5, sizeof(acpu_freq_tbl_2p2g_pvs5) },
 	[2][6] = { acpu_freq_tbl_2p2g_pvs6, sizeof(acpu_freq_tbl_2p2g_pvs6) },
 	[2][7] = { acpu_freq_tbl_2p2g_pvs6, sizeof(acpu_freq_tbl_2p2g_pvs6) },
+};
 
-	/* 8974v3 Bringup */
-	[3][0] = { acpu_freq_tbl_v3_pvs0, sizeof(acpu_freq_tbl_v3_pvs0) },
-	[3][1] = { acpu_freq_tbl_v3_pvs0, sizeof(acpu_freq_tbl_v3_pvs0) },
-	[3][2] = { acpu_freq_tbl_v3_pvs0, sizeof(acpu_freq_tbl_v3_pvs0) },
-	[3][3] = { acpu_freq_tbl_v3_pvs0, sizeof(acpu_freq_tbl_v3_pvs0) },
-	[3][4] = { acpu_freq_tbl_v3_pvs0, sizeof(acpu_freq_tbl_v3_pvs0) },
-	[3][5] = { acpu_freq_tbl_v3_pvs0, sizeof(acpu_freq_tbl_v3_pvs0) },
-	[3][6] = { acpu_freq_tbl_v3_pvs0, sizeof(acpu_freq_tbl_v3_pvs0) },
-	[3][7] = { acpu_freq_tbl_v3_pvs0, sizeof(acpu_freq_tbl_v3_pvs0) },
+static struct pvs_table pvs_pro[NUM_SPEED_BINS][NUM_PVS] __initdata = {
+	/* Not used by 8974Pro */
+	[0][0] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[0][1] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[0][2] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[0][3] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[0][4] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[0][5] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[0][6] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[0][7] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
 
+	/* 8974Pro AB Bringup */
+	[1][0] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[1][1] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[1][2] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[1][3] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[1][4] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[1][5] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[1][6] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[1][7] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+
+	/* Not used by 8974Pro */
+	[2][0] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[2][1] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[2][2] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[2][3] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[2][4] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[2][5] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[2][6] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[2][7] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+
+	/* 8974Pro Bringup */
+	[3][0] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[3][1] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[3][2] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[3][3] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[3][4] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[3][5] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[3][6] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
+	[3][7] = { acpu_freq_tbl_pro_pvs0, sizeof(acpu_freq_tbl_pro_pvs0) },
 };
 
 static struct msm_bus_scale_pdata bus_scale_data __initdata = {
@@ -1004,6 +1035,11 @@
 	.stby_khz = 300000,
 };
 
+static void __init apply_pro_bringup_workaround(void)
+{
+	acpuclk_8974_params.pvs_tables = pvs_pro;
+}
+
 static void __init apply_v1_l2_workaround(void)
 {
 	static struct l2_level resticted_l2_tbl[] __initdata = {
@@ -1023,9 +1059,13 @@
 	acpuclk_8974_params.l2_freq_tbl_size = sizeof(resticted_l2_tbl);
 }
 
+#define cpu_is_msm8974pro() (cpu_is_msm8974pro_aa() || cpu_is_msm8974pro_ab() \
+			     || cpu_is_msm8974pro_ac())
+
 static int __init acpuclk_8974_probe(struct platform_device *pdev)
 {
-	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 1) {
+	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 1
+	    && cpu_is_msm8974()) {
 		acpuclk_8974_params.pvs_tables = pvs_v1;
 		acpuclk_8974_params.l2_freq_tbl = l2_freq_tbl_v1;
 		bus_scale_data.usecase = bw_level_tbl_v1;
@@ -1043,6 +1083,9 @@
 			apply_v1_l2_workaround();
 	}
 
+	if (cpu_is_msm8974pro())
+		apply_pro_bringup_workaround();
+
 	return acpuclk_krait_init(&pdev->dev, &acpuclk_8974_params);
 }
 
diff --git a/arch/arm/mach-msm/board-8226-gpiomux.c b/arch/arm/mach-msm/board-8226-gpiomux.c
index a32031d..fd831fc 100644
--- a/arch/arm/mach-msm/board-8226-gpiomux.c
+++ b/arch/arm/mach-msm/board-8226-gpiomux.c
@@ -468,6 +468,91 @@
 	},
 };
 
+#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
+static struct gpiomux_setting sdc3_clk_actv_cfg = {
+	.func = GPIOMUX_FUNC_2,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting sdc3_cmd_data_0_3_actv_cfg = {
+	.func = GPIOMUX_FUNC_2,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting sdc3_suspend_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting sdc3_data_1_suspend_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct msm_gpiomux_config msm8226_sdc3_configs[] __initdata = {
+	{
+		/* DAT3 */
+		.gpio      = 39,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &sdc3_cmd_data_0_3_actv_cfg,
+			[GPIOMUX_SUSPENDED] = &sdc3_suspend_cfg,
+		},
+	},
+	{
+		/* DAT2 */
+		.gpio      = 40,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &sdc3_cmd_data_0_3_actv_cfg,
+			[GPIOMUX_SUSPENDED] = &sdc3_suspend_cfg,
+		},
+	},
+	{
+		/* DAT1 */
+		.gpio      = 41,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &sdc3_cmd_data_0_3_actv_cfg,
+			[GPIOMUX_SUSPENDED] = &sdc3_data_1_suspend_cfg,
+		},
+	},
+	{
+		/* DAT0 */
+		.gpio      = 42,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &sdc3_cmd_data_0_3_actv_cfg,
+			[GPIOMUX_SUSPENDED] = &sdc3_suspend_cfg,
+		},
+	},
+	{
+		/* CMD */
+		.gpio      = 43,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &sdc3_cmd_data_0_3_actv_cfg,
+			[GPIOMUX_SUSPENDED] = &sdc3_suspend_cfg,
+		},
+	},
+	{
+		/* CLK */
+		.gpio      = 44,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &sdc3_clk_actv_cfg,
+			[GPIOMUX_SUSPENDED] = &sdc3_suspend_cfg,
+		},
+	},
+};
+
+static void msm_gpiomux_sdc3_install(void)
+{
+	msm_gpiomux_install(msm8226_sdc3_configs,
+			    ARRAY_SIZE(msm8226_sdc3_configs));
+}
+#else
+static void msm_gpiomux_sdc3_install(void) {}
+#endif /* CONFIG_MMC_MSM_SDC3_SUPPORT */
+
 void __init msm8226_init_gpiomux(void)
 {
 	int rc;
@@ -500,4 +585,6 @@
 	if (of_board_is_cdp() || of_board_is_mtp() || of_board_is_xpm())
 		msm_gpiomux_install(usb_otg_sw_configs,
 					ARRAY_SIZE(usb_otg_sw_configs));
+
+	msm_gpiomux_sdc3_install();
 }
diff --git a/arch/arm/mach-msm/board-8226.c b/arch/arm/mach-msm/board-8226.c
index 5ad6175..0d62b7a 100644
--- a/arch/arm/mach-msm/board-8226.c
+++ b/arch/arm/mach-msm/board-8226.c
@@ -75,10 +75,14 @@
 			"msm_sdcc.1", NULL),
 	OF_DEV_AUXDATA("qcom,msm-sdcc", 0xF98A4000, \
 			"msm_sdcc.2", NULL),
+	OF_DEV_AUXDATA("qcom,msm-sdcc", 0xF9864000, \
+			"msm_sdcc.3", NULL),
 	OF_DEV_AUXDATA("qcom,sdhci-msm", 0xF9824900, \
 			"msm_sdcc.1", NULL),
 	OF_DEV_AUXDATA("qcom,sdhci-msm", 0xF98A4900, \
 			"msm_sdcc.2", NULL),
+	OF_DEV_AUXDATA("qcom,sdhci-msm", 0xF9864900, \
+			"msm_sdcc.3", NULL),
 	{}
 };
 
diff --git a/arch/arm/mach-msm/board-8610-gpiomux.c b/arch/arm/mach-msm/board-8610-gpiomux.c
index b261ce4..f8ca143 100644
--- a/arch/arm/mach-msm/board-8610-gpiomux.c
+++ b/arch/arm/mach-msm/board-8610-gpiomux.c
@@ -16,6 +16,7 @@
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/gpiomux.h>
+#include <mach/socinfo.h>
 
 static struct gpiomux_setting gpio_spi_config = {
 	.func = GPIOMUX_FUNC_1,
@@ -59,6 +60,30 @@
 	.pull = GPIOMUX_PULL_DOWN,
 };
 
+static struct gpiomux_setting focaltech_int_act_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting focaltech_int_sus_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting focaltech_reset_act_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_6MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting focaltech_reset_sus_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_6MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
 static struct gpiomux_setting wcnss_5wire_suspend_cfg = {
 	.func = GPIOMUX_FUNC_GPIO,
 	.drv  = GPIOMUX_DRV_2MA,
@@ -110,6 +135,31 @@
 	.pull = GPIOMUX_PULL_NONE,
 };
 
+/* define gpio used as interrupt input */
+static struct gpiomux_setting gpio_int_act_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_UP,
+	.dir = GPIOMUX_IN,
+};
+
+static struct gpiomux_setting gpio_int_sus_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_UP,
+	.dir = GPIOMUX_IN,
+};
+
+static struct msm_gpiomux_config msm_gpio_int_configs[] __initdata = {
+	{
+		.gpio = 84,
+		.settings = {
+			[GPIOMUX_ACTIVE]	= &gpio_int_act_cfg,
+			[GPIOMUX_SUSPENDED]	= &gpio_int_sus_cfg,
+		},
+	},
+};
+
 static struct msm_gpiomux_config msm_lcd_configs[] __initdata = {
 	{
 		.gpio = 41,
@@ -214,6 +264,48 @@
 	},
 };
 
+static struct msm_gpiomux_config msm_focaltech_configs[] __initdata = {
+	{
+		.gpio      = 0,		/* TOUCH RESET */
+		.settings = {
+			[GPIOMUX_ACTIVE] = &focaltech_reset_act_cfg,
+			[GPIOMUX_SUSPENDED] = &focaltech_reset_sus_cfg,
+		},
+	},
+	{
+		.gpio      = 1,		/* TOUCH INT */
+		.settings = {
+			[GPIOMUX_ACTIVE] = &focaltech_int_act_cfg,
+			[GPIOMUX_SUSPENDED] = &focaltech_int_sus_cfg,
+		},
+	},
+	{
+		.gpio      = 86,		/* BLSP1 QUP4 SPI_DATA_MOSI */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+	{
+		.gpio      = 87,		/* BLSP1 QUP4 SPI_DATA_MISO */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+	{
+		.gpio      = 89,		/* BLSP1 QUP4 SPI_CLK */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+	{
+		.gpio      = 88,		/* BLSP1 QUP4 SPI_CS */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+};
+
+
 static struct msm_gpiomux_config wcnss_5wire_interface[] = {
 	{
 		.gpio = 23,
@@ -430,8 +522,13 @@
 	}
 
 	msm_gpiomux_install(msm_blsp_configs, ARRAY_SIZE(msm_blsp_configs));
-	msm_gpiomux_install(msm_atmel_configs,
+	if (of_board_is_qrd()) {
+		msm_gpiomux_install(msm_focaltech_configs,
+			ARRAY_SIZE(msm_focaltech_configs));
+	} else {
+		msm_gpiomux_install(msm_atmel_configs,
 			ARRAY_SIZE(msm_atmel_configs));
+	}
 	msm_gpiomux_install(wcnss_5wire_interface,
 			ARRAY_SIZE(wcnss_5wire_interface));
 	msm_gpiomux_install(msm_lcd_configs, ARRAY_SIZE(msm_lcd_configs));
@@ -439,4 +536,6 @@
 				ARRAY_SIZE(msm_keypad_configs));
 	msm_gpiomux_install(sd_card_det, ARRAY_SIZE(sd_card_det));
 	msm_gpiomux_install(msm_sensor_configs, ARRAY_SIZE(msm_sensor_configs));
+	msm_gpiomux_install(msm_gpio_int_configs,
+			ARRAY_SIZE(msm_gpio_int_configs));
 }
diff --git a/arch/arm/mach-msm/board-8974-gpiomux.c b/arch/arm/mach-msm/board-8974-gpiomux.c
index 6432c93..fb2c12c 100644
--- a/arch/arm/mach-msm/board-8974-gpiomux.c
+++ b/arch/arm/mach-msm/board-8974-gpiomux.c
@@ -825,6 +825,135 @@
 	},
 };
 
+static struct msm_gpiomux_config msm_sensor_configs_dragonboard[] __initdata = {
+	{
+		.gpio = 15, /* CAM_MCLK0 */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+		},
+	},
+	{
+		.gpio = 16, /* CAM_MCLK1 */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+		},
+	},
+	{
+		.gpio = 17, /* CAM_MCLK2 */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+		},
+	},
+	{
+		.gpio = 18, /* WEBCAM1_RESET_N / CAM_MCLK3 */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &cam_settings[4],
+		},
+	},
+	{
+		.gpio = 19, /* CCI_I2C_SDA0 */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[0],
+		},
+	},
+	{
+		.gpio = 20, /* CCI_I2C_SCL0 */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[0],
+		},
+	},
+	{
+		.gpio = 21, /* CCI_I2C_SDA1 */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[0],
+		},
+	},
+	{
+		.gpio = 22, /* CCI_I2C_SCL1 */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[0],
+		},
+	},
+	{
+		.gpio = 23, /* FLASH_LED_EN */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[1],
+		},
+	},
+	{
+		.gpio = 24, /* FLASH_LED_NOW */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[1],
+		},
+	},
+	{
+		.gpio = 25, /* WEBCAM2_RESET_N */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[1],
+		},
+	},
+	{
+		.gpio = 26, /* CAM_IRQ */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &cam_settings[1],
+		},
+	},
+	{
+		.gpio = 27, /* OIS_SYNC */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[0],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[1],
+		},
+	},
+	{
+		.gpio = 28, /* WEBCAM1_STANDBY */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[1],
+		},
+	},
+	{
+		.gpio = 89, /* CAM1_STANDBY_N */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[1],
+		},
+	},
+	{
+		.gpio = 90, /* CAM1_RST_N */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[1],
+		},
+	},
+	{
+		.gpio = 91, /* CAM2_STANDBY_N */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[1],
+		},
+	},
+	{
+		.gpio = 94, /* CAM2_RST_N */
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &gpio_suspend_config[1],
+		},
+	},
+};
+
 static struct gpiomux_setting auxpcm_act_cfg = {
 	.func = GPIOMUX_FUNC_1,
 	.drv = GPIOMUX_DRV_8MA,
@@ -1198,7 +1327,9 @@
 	}
 
 #if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
-	msm_gpiomux_install(msm_eth_configs, ARRAY_SIZE(msm_eth_configs));
+	if (!(of_board_is_dragonboard() && machine_is_apq8074()))
+		msm_gpiomux_install(msm_eth_configs, \
+			ARRAY_SIZE(msm_eth_configs));
 #endif
 	msm_gpiomux_install(msm_blsp_configs, ARRAY_SIZE(msm_blsp_configs));
 	msm_gpiomux_install(msm_blsp2_uart7_configs,
@@ -1215,7 +1346,12 @@
 		msm_gpiomux_install(hap_lvl_shft_config,
 				ARRAY_SIZE(hap_lvl_shft_config));
 
-	msm_gpiomux_install(msm_sensor_configs, ARRAY_SIZE(msm_sensor_configs));
+	if (of_board_is_dragonboard() && machine_is_apq8074())
+		msm_gpiomux_install(msm_sensor_configs_dragonboard, \
+				ARRAY_SIZE(msm_sensor_configs_dragonboard));
+	else
+		msm_gpiomux_install(msm_sensor_configs, \
+				ARRAY_SIZE(msm_sensor_configs));
 
 	msm_gpiomux_install(&sd_card_det, 1);
 
@@ -1223,7 +1359,8 @@
 	    of_board_is_dragonboard()))
 		msm_gpiomux_sdc3_install();
 
-	msm_gpiomux_sdc4_install();
+	if (!(of_board_is_dragonboard() && machine_is_apq8074()))
+		msm_gpiomux_sdc4_install();
 
 	msm_gpiomux_install(msm_taiko_config, ARRAY_SIZE(msm_taiko_config));
 
diff --git a/arch/arm/mach-msm/board-9625.c b/arch/arm/mach-msm/board-9625.c
index fad2efc..36ad755 100644
--- a/arch/arm/mach-msm/board-9625.c
+++ b/arch/arm/mach-msm/board-9625.c
@@ -117,6 +117,10 @@
 			"usb_bam", NULL),
 	OF_DEV_AUXDATA("qcom,hsic-host", 0xF9A15000, \
 			"msm_hsic_host", NULL),
+	OF_DEV_AUXDATA("qcom,sdhci-msm", 0xF98A4900, \
+		       "msm_sdcc.2", NULL),
+	OF_DEV_AUXDATA("qcom,sdhci-msm", 0xF9864900, \
+		       "msm_sdcc.3", NULL),
 	{}
 };
 
diff --git a/arch/arm/mach-msm/board-krypton.c b/arch/arm/mach-msm/board-krypton.c
index 0d06b83..e80244b 100644
--- a/arch/arm/mach-msm/board-krypton.c
+++ b/arch/arm/mach-msm/board-krypton.c
@@ -31,6 +31,22 @@
 #include "clock.h"
 #include "devices.h"
 
+static struct memtype_reserve msmkrypton_reserve_table[] __initdata = {
+	[MEMTYPE_EBI1] = {
+		.flags = MEMTYPE_FLAGS_1M_ALIGN,
+	},
+};
+
+static int msmkrypton_paddr_to_memtype(unsigned int paddr)
+{
+	return MEMTYPE_EBI1;
+}
+
+static struct reserve_info msmkrypton_reserve_info __initdata = {
+	.memtype_reserve_table = msmkrypton_reserve_table,
+	.paddr_to_memtype = msmkrypton_paddr_to_memtype,
+};
+
 static struct of_dev_auxdata msmkrypton_auxdata_lookup[] __initdata = {
 	{}
 };
@@ -47,6 +63,11 @@
 	msm_clock_init(&msmkrypton_clock_init_data);
 }
 
+static void __init msmkrypton_early_memory(void)
+{
+	reserve_info = &msmkrypton_reserve_info;
+	of_scan_flat_dt(dt_scan_for_memory_hole, msmkrypton_reserve_table);
+}
 static void __init msmkrypton_map_io(void)
 {
 	msm_map_msmkrypton_io();
@@ -74,5 +95,6 @@
 	.handle_irq = gic_handle_irq,
 	.timer = &msm_dt_timer,
 	.dt_compat = msmkrypton_dt_match,
+	.init_very_early = msmkrypton_early_memory,
 	.restart = msm_restart,
 MACHINE_END
diff --git a/arch/arm/mach-msm/clock-8084.c b/arch/arm/mach-msm/clock-8084.c
index 605a7ae..c54c3db 100644
--- a/arch/arm/mach-msm/clock-8084.c
+++ b/arch/arm/mach-msm/clock-8084.c
@@ -310,20 +310,24 @@
 	CLK_DUMMY("iface_clk", mdss_ahb_clk.c, "fd900000.qcom,mdss_mdp", OFF),
 	CLK_DUMMY("bus_clk", mdss_axi_clk.c, "fd900000.qcom,mdss_mdp", OFF),
 	CLK_DUMMY("core_clk_src", mdp_clk_src.c, "fd900000.qcom,mdss_mdp", OFF),
-	CLK_DUMMY("",	mdss_byte0_clk.c,	"", OFF),
-	CLK_DUMMY("",	mdss_byte1_clk.c,	"", OFF),
 	CLK_DUMMY("",	mdss_edpaux_clk.c,	"", OFF),
 	CLK_DUMMY("",	mdss_edplink_clk.c,	"", OFF),
 	CLK_DUMMY("",	mdss_edppixel_clk.c,	"", OFF),
-	CLK_DUMMY("",	mdss_esc0_clk.c,	"", OFF),
-	CLK_DUMMY("",	mdss_esc1_clk.c,	"", OFF),
+	CLK_DUMMY("byte_clk", mdss_byte0_clk.c, "fd922800.qcom,mdss_dsi", OFF),
+	CLK_DUMMY("byte_clk", mdss_byte1_clk.c, "fd922e00.qcom,mdss_dsi", OFF),
+	CLK_DUMMY("core_clk", mdss_esc0_clk.c, "fd922800.qcom,mdss_dsi", OFF),
+	CLK_DUMMY("core_clk", mdss_esc1_clk.c, "fd922e00.qcom,mdss_dsi", OFF),
+	CLK_DUMMY("iface_clk", mdss_ahb_clk.c, "fd922800.qcom,mdss_dsi", OFF),
+	CLK_DUMMY("iface_clk", mdss_ahb_clk.c, "fd922e00.qcom,mdss_dsi", OFF),
+	CLK_DUMMY("bus_clk", mdss_axi_clk.c, "fd922800.qcom,mdss_dsi", OFF),
+	CLK_DUMMY("bus_clk", mdss_axi_clk.c, "fd922e00.qcom,mdss_dsi", OFF),
+	CLK_DUMMY("pixel_clk", mdss_pclk0_clk.c, "fd922800.qcom,mdss_dsi", OFF),
+	CLK_DUMMY("pixel_clk", mdss_pclk1_clk.c, "fd922e00.qcom,mdss_dsi", OFF),
 	CLK_DUMMY("",	mdss_extpclk_clk.c,	"", OFF),
 	CLK_DUMMY("",	mdss_hdmi_ahb_clk.c,	"", OFF),
 	CLK_DUMMY("",	mdss_hdmi_clk.c,	"", OFF),
 	CLK_DUMMY("core_clk", mdss_mdp_clk.c, "fd900000.qcom,mdss_mdp", OFF),
 	CLK_DUMMY("lut_clk", mdss_mdp_lut_clk.c, "fd900000.qcom,mdss_mdp", OFF),
-	CLK_DUMMY("",	mdss_pclk0_clk.c,	"", OFF),
-	CLK_DUMMY("",	mdss_pclk1_clk.c,	"", OFF),
 	CLK_DUMMY("vsync_clk", mdss_vsync_clk.c, "fd900000.qcom,mdss_mdp", OFF),
 	CLK_DUMMY("",	mmss_misc_ahb_clk.c,	"", OFF),
 	CLK_DUMMY("",	mmss_mmssnoc_ahb_clk.c,	"", OFF),
diff --git a/arch/arm/mach-msm/clock-8092.c b/arch/arm/mach-msm/clock-8092.c
index 9de97ea..f8150c4 100644
--- a/arch/arm/mach-msm/clock-8092.c
+++ b/arch/arm/mach-msm/clock-8092.c
@@ -290,6 +290,16 @@
 	CLK_DUMMY("",	vpu_sleep_clk.c,	"", OFF),
 	CLK_DUMMY("",	vpu_vdp_clk.c,	"", OFF),
 	CLK_DUMMY("",	vpu_vdp_xin_clk.c,	"", OFF),
+	CLK_DUMMY("iface_clk", NULL, "fda64000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk", NULL, "fda64000.qcom,iommu", OFF),
+	CLK_DUMMY("alt_core_clk", NULL, "fda64000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk", NULL, "fd928000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk", NULL, "fd928000.qcom,iommu", oFF),
+	CLK_DUMMY("core_clk", NULL, "fdb10000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk", NULL, "fdb10000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk", NULL, "fdc84000.qcom,iommu", OFF),
+	CLK_DUMMY("alt_core_clk", NULL, "fdc84000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk", NULL, "fdc84000.qcom,iommu", OFF),
 	/* BCSS broadcast */
 	CLK_DUMMY("",	bcc_dem_core_b_clk_src.c,	"", OFF),
 	CLK_DUMMY("",	adc_01_clk_src.c,	"", OFF),
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 1e91d5b..1514bba 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -3047,7 +3047,7 @@
 	return branch_reset(&to_pix_rdi_clk(c)->b, action);
 }
 
-static int pix_rdi_clk_list_rate(struct clk *c, unsigned n)
+static long pix_rdi_clk_list_rate(struct clk *c, unsigned n)
 {
 	if (pix_rdi_mux_map[n])
 		return n;
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 832e86f..11886a4 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -1401,7 +1401,7 @@
 	F_END
 };
 
-static struct clk_freq_tbl ftbl_gcc_ce1_v3_clk[] = {
+static struct clk_freq_tbl ftbl_gcc_ce1_pro_clk[] = {
 	F( 50000000,  gpll0,  12,   0,   0),
 	F( 75000000,  gpll0,   8,   0,   0),
 	F(100000000,  gpll0,   6,   0,   0),
@@ -1429,7 +1429,7 @@
 	F_END
 };
 
-static struct clk_freq_tbl ftbl_gcc_ce2_v3_clk[] = {
+static struct clk_freq_tbl ftbl_gcc_ce2_pro_clk[] = {
 	F( 50000000,  gpll0,  12,   0,   0),
 	F( 75000000,  gpll0,   8,   0,   0),
 	F(100000000,  gpll0,   6,   0,   0),
@@ -2945,12 +2945,12 @@
 	F_END
 };
 
-static struct clk_freq_tbl ftbl_camss_mclk0_3_v3_clk[] = {
+static struct clk_freq_tbl ftbl_camss_mclk0_3_pro_clk[] = {
 	F_MM( 4800000,    cxo,    4,   0,   0),
 	F_MM( 6000000,  gpll0,   10,   1,  10),
 	F_MM( 8000000,  gpll0,   15,   1,   5),
 	F_MM( 9600000,    cxo,    2,   0,   0),
-	F_MM(16000000,  gpll0,   10,   1,   5),
+	F_MM(16000000,  gpll0, 12.5,   1,   3),
 	F_MM(19200000,    cxo,    1,   0,   0),
 	F_MM(24000000,  gpll0,    5,   1,   5),
 	F_MM(32000000, mmpll0,    5,   1,   5),
@@ -4680,7 +4680,8 @@
 		clk->multiplier = 4;
 		clk_sel = 0x16A;
 
-		if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 1) {
+		if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 1 &&
+		    cpu_is_msm8974()) {
 			if (measure_mux[i].debug_mux == M_L2)
 				regval = BIT(7)|BIT(0);
 			else
@@ -5512,15 +5513,21 @@
 	.mn_ena_mask = BIT(24),
 	.main_output_val = BIT(0),
 	.main_output_mask = BIT(0),
+	.aux_output_val = BIT(1),
+	.aux_output_mask = BIT(1),
 };
 
+#define cpu_is_msm8974pro() (cpu_is_msm8974pro_aa() || cpu_is_msm8974pro_ab() \
+			     || cpu_is_msm8974pro_ac())
+
 static void __init reg_init(void)
 {
 	u32 regval;
 
 	configure_sr_hpm_lp_pll(&mmpll0_config, &mmpll0_regs, 1);
 
-	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2) {
+	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2
+	    || cpu_is_msm8974pro()) {
 		configure_sr_hpm_lp_pll(&mmpll1_v2_config, &mmpll1_regs, 1);
 		configure_sr_hpm_lp_pll(&mmpll3_v2_config, &mmpll3_regs, 0);
 	} else {
@@ -5537,7 +5544,8 @@
 	 * V2 requires additional votes to allow the LPASS and MMSS
 	 * controllers to use GPLL0.
 	 */
-	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2) {
+	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2
+	    || cpu_is_msm8974pro()) {
 		regval = readl_relaxed(
 				GCC_REG_BASE(APCS_CLOCK_BRANCH_ENA_VOTE));
 		writel_relaxed(regval | BIT(26) | BIT(25),
@@ -5547,7 +5555,8 @@
 
 static void __init msm8974_clock_post_init(void)
 {
-	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2) {
+	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2
+	    || cpu_is_msm8974pro()) {
 		clk_set_rate(&axi_clk_src.c, 291750000);
 		clk_set_rate(&ocmemnoc_clk_src.c, 291750000);
 	} else {
@@ -5661,35 +5670,44 @@
 		qup_i2c_clks[i][0]->parent =  qup_i2c_clks[i][1];
 }
 
-/* v2 to v3 clock changes */
-static void __init msm8974_v3_clock_override(void)
+/* v2 to pro clock changes */
+static void __init msm8974_pro_clock_override(void)
 {
 	ce1_clk_src.c.fmax[VDD_DIG_LOW] = 75000000;
 	ce1_clk_src.c.fmax[VDD_DIG_NOMINAL] = 150000000;
-	ce1_clk_src.freq_tbl = ftbl_gcc_ce1_v3_clk;
+	ce1_clk_src.freq_tbl = ftbl_gcc_ce1_pro_clk;
 	ce2_clk_src.c.fmax[VDD_DIG_LOW] = 75000000;
 	ce2_clk_src.c.fmax[VDD_DIG_NOMINAL] = 150000000;
-	ce2_clk_src.freq_tbl = ftbl_gcc_ce2_v3_clk;
+	ce2_clk_src.freq_tbl = ftbl_gcc_ce2_pro_clk;
 
-	sdcc1_apps_clk_src.c.fmax[VDD_DIG_LOW] = 200000000;
-	sdcc1_apps_clk_src.c.fmax[VDD_DIG_NOMINAL] = 400000000;
+	if (cpu_is_msm8974pro_ac()) {
+		sdcc1_apps_clk_src.c.fmax[VDD_DIG_LOW] = 200000000;
+		sdcc1_apps_clk_src.c.fmax[VDD_DIG_NOMINAL] = 400000000;
+	}
 
 	vfe0_clk_src.c.fmax[VDD_DIG_LOW] = 150000000;
 	vfe0_clk_src.c.fmax[VDD_DIG_NOMINAL] = 320000000;
-	vfe0_clk_src.c.fmax[VDD_DIG_HIGH] = 465000000;
 	vfe1_clk_src.c.fmax[VDD_DIG_LOW] = 150000000;
 	vfe1_clk_src.c.fmax[VDD_DIG_NOMINAL] = 320000000;
-	vfe1_clk_src.c.fmax[VDD_DIG_HIGH] = 465000000;
 	cpp_clk_src.c.fmax[VDD_DIG_LOW] = 150000000;
 	cpp_clk_src.c.fmax[VDD_DIG_NOMINAL] = 320000000;
-	cpp_clk_src.c.fmax[VDD_DIG_HIGH] = 465000000;
+
+	if (cpu_is_msm8974pro_ab() || cpu_is_msm8974pro_ac()) {
+		vfe0_clk_src.c.fmax[VDD_DIG_HIGH] = 465000000;
+		vfe1_clk_src.c.fmax[VDD_DIG_HIGH] = 465000000;
+		cpp_clk_src.c.fmax[VDD_DIG_HIGH] = 465000000;
+	} else if (cpu_is_msm8974pro_aa()) {
+		vfe0_clk_src.c.fmax[VDD_DIG_HIGH] = 320000000;
+		vfe1_clk_src.c.fmax[VDD_DIG_HIGH] = 320000000;
+		cpp_clk_src.c.fmax[VDD_DIG_HIGH] = 320000000;
+	}
 
 	mdp_clk_src.c.fmax[VDD_DIG_NOMINAL] = 266670000;
 
-	mclk0_clk_src.freq_tbl = ftbl_camss_mclk0_3_v3_clk;
-	mclk1_clk_src.freq_tbl = ftbl_camss_mclk0_3_v3_clk;
-	mclk2_clk_src.freq_tbl = ftbl_camss_mclk0_3_v3_clk;
-	mclk3_clk_src.freq_tbl = ftbl_camss_mclk0_3_v3_clk;
+	mclk0_clk_src.freq_tbl = ftbl_camss_mclk0_3_pro_clk;
+	mclk1_clk_src.freq_tbl = ftbl_camss_mclk0_3_pro_clk;
+	mclk2_clk_src.freq_tbl = ftbl_camss_mclk0_3_pro_clk;
+	mclk3_clk_src.freq_tbl = ftbl_camss_mclk0_3_pro_clk;
 	mclk0_clk_src.set_rate = set_rate_mnd;
 	mclk1_clk_src.set_rate = set_rate_mnd;
 	mclk2_clk_src.set_rate = set_rate_mnd;
@@ -5733,10 +5751,11 @@
 	msm8974_clock_init_data.size -= ARRAY_SIZE(msm_clocks_8974ac_only);
 
 	/* version specific changes */
-	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2)
+	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2
+	    || cpu_is_msm8974pro())
 		msm8974_v2_clock_override();
-	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 3) {
-		msm8974_v3_clock_override();
+	if (cpu_is_msm8974pro()) {
+		msm8974_pro_clock_override();
 		memcpy(msm_clocks_8974 + ARRAY_SIZE(msm_clocks_8974_common),
 		       msm_clocks_8974ac_only, sizeof(msm_clocks_8974ac_only));
 		msm8974_clock_init_data.size +=
diff --git a/arch/arm/mach-msm/clock-debug.c b/arch/arm/mach-msm/clock-debug.c
index 8ec87d1..c91af54 100644
--- a/arch/arm/mach-msm/clock-debug.c
+++ b/arch/arm/mach-msm/clock-debug.c
@@ -198,11 +198,12 @@
 static int list_rates_show(struct seq_file *m, void *unused)
 {
 	struct clk *clock = m->private;
-	int rate, level, fmax = 0, i = 0;
+	int level, i = 0;
+	unsigned long rate, fmax = 0;
 
 	/* Find max frequency supported within voltage constraints. */
 	if (!clock->vdd_class) {
-		fmax = INT_MAX;
+		fmax = ULONG_MAX;
 	} else {
 		for (level = 0; level < clock->num_fmax; level++)
 			if (clock->fmax[level])
@@ -213,9 +214,9 @@
 	 * List supported frequencies <= fmax. Higher frequencies may appear in
 	 * the frequency table, but are not valid and should not be listed.
 	 */
-	while ((rate = clock->ops->list_rate(clock, i++)) >= 0) {
+	while (!IS_ERR_VALUE(rate = clock->ops->list_rate(clock, i++))) {
 		if (rate <= fmax)
-			seq_printf(m, "%u\n", rate);
+			seq_printf(m, "%lu\n", rate);
 	}
 
 	return 0;
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index 0b8240c..18ea514 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -579,7 +579,7 @@
 }
 
 /* Return the nth supported frequency for a given clock. */
-static int rcg_clk_list_rate(struct clk *c, unsigned n)
+static long rcg_clk_list_rate(struct clk *c, unsigned n)
 {
 	struct rcg_clk *rcg = to_rcg_clk(c);
 
@@ -944,7 +944,7 @@
 	return rate > to_cdiv_clk(c)->max_div ? -EPERM : rate;
 }
 
-static int cdiv_clk_list_rate(struct clk *c, unsigned n)
+static long cdiv_clk_list_rate(struct clk *c, unsigned n)
 {
 	return n > to_cdiv_clk(c)->max_div ? -ENXIO : n;
 }
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index fd790e2..b7852fe 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -210,7 +210,7 @@
 }
 
 /* Return the nth supported frequency for a given clock. */
-static int rcg_clk_list_rate(struct clk *c, unsigned n)
+static long rcg_clk_list_rate(struct clk *c, unsigned n)
 {
 	struct rcg_clk *rcg = to_rcg_clk(c);
 
@@ -459,7 +459,7 @@
 	return clk_get_rate(c->parent);
 }
 
-static int branch_clk_list_rate(struct clk *c, unsigned n)
+static long branch_clk_list_rate(struct clk *c, unsigned n)
 {
 	int level, fmax = 0, rate;
 	struct branch_clk *branch = to_branch_clk(c);
@@ -934,7 +934,7 @@
 	return ERR_PTR(-EPERM);
 }
 
-static int cam_mux_clk_list_rate(struct clk *c, unsigned n)
+static long cam_mux_clk_list_rate(struct clk *c, unsigned n)
 {
 	struct cam_mux_clk *mux = to_cam_mux_clk(c);
 	int i;
diff --git a/arch/arm/mach-msm/clock-pll.c b/arch/arm/mach-msm/clock-pll.c
index 69c3751..a251784 100644
--- a/arch/arm/mach-msm/clock-pll.c
+++ b/arch/arm/mach-msm/clock-pll.c
@@ -694,6 +694,12 @@
 		regval |= config->main_output_val;
 	}
 
+	/* Enable the aux output */
+	if (config->aux_output_mask) {
+		regval &= ~config->aux_output_mask;
+		regval |= config->aux_output_val;
+	}
+
 	/* Set pre-divider and post-divider values */
 	regval &= ~config->pre_div_mask;
 	regval |= config->pre_div_val;
diff --git a/arch/arm/mach-msm/clock-pll.h b/arch/arm/mach-msm/clock-pll.h
index c4addb2..58c00b9 100644
--- a/arch/arm/mach-msm/clock-pll.h
+++ b/arch/arm/mach-msm/clock-pll.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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
@@ -184,6 +184,8 @@
 	u32 mn_ena_mask;
 	u32 main_output_val;
 	u32 main_output_mask;
+	u32 aux_output_val;
+	u32 aux_output_mask;
 };
 
 struct pll_config_regs {
diff --git a/arch/arm/mach-msm/cpr-regulator.c b/arch/arm/mach-msm/cpr-regulator.c
index 5550282..a2936c2 100644
--- a/arch/arm/mach-msm/cpr-regulator.c
+++ b/arch/arm/mach-msm/cpr-regulator.c
@@ -125,21 +125,7 @@
 #define CPR_FUSE_RO_SEL_BITS		3
 #define CPR_FUSE_RO_SEL_BITS_MASK	((1<<CPR_FUSE_RO_SEL_BITS)-1)
 
-#define CPR_FUSE_TARGET_QUOT_TURBO_SHIFT	0
-#define CPR_FUSE_TARGET_QUOT_NOMINAL_SHIFT	12
-#define CPR_FUSE_TARGET_QUOT_SVS_SHIFT		24
-
-#define CPR_FUSE_DISABLE_CPR_SHIFT		36
-#define CPR_FUSE_LOCAL_APPROACH_SHIFT		37
-#define CPR_FUSE_REDUNDANT_SHIFT		57
-
-/* PVS eFuse parameters */
-#define PVS_FUSE_REDUNDANT_SHIFT	24
-#define PVS_FUSE_REDUNDANT_BITS		3
-#define PVS_FUSE_REDUNDANT_MASK		((1<<PVS_FUSE_REDUNDANT_BITS)-1)
-
-#define PVS_FUSE_BINS_SHIFT		6
-#define PVS_FUSE_BINS_REDUNDANT_SHIFT	27
+#define BYTES_PER_FUSE_ROW		8
 
 enum voltage_change_dir {
 	NO_CHANGE,
@@ -154,9 +140,11 @@
 	int				corner;
 	int				ceiling_max;
 
+	/* eFuse parameters */
+	phys_addr_t	efuse_addr;
+	void __iomem	*efuse_base;
+
 	/* Process voltage parameters */
-	phys_addr_t	pvs_efuse;
-	u32		num_efuse_bits;
 	u32		pvs_bin_process[CPR_PVS_EFUSE_BINS_MAX];
 	u32		pvs_corner_v[NUM_APC_PVS][CPR_CORNER_MAX];
 	/* Process voltage variables */
@@ -173,12 +161,9 @@
 	int			vdd_mx_vmin;
 
 	/* CPR parameters */
-	phys_addr_t	cpr_fuse_addr;
 	u64		cpr_fuse_bits;
-	u64		cpr_fuse_bits_2;
 	bool		cpr_fuse_disable;
 	bool		cpr_fuse_local;
-	bool		cpr_fuse_redundancy;
 	int		cpr_fuse_target_quot[CPR_CORNER_MAX];
 	int		cpr_fuse_ro_sel[CPR_CORNER_MAX];
 	int		gcnt;
@@ -838,7 +823,7 @@
 #define cpr_regulator_resume NULL
 #endif
 
-static int cpr_config(struct cpr_regulator *cpr_vreg)
+static int __devinit cpr_config(struct cpr_regulator *cpr_vreg)
 {
 	int i;
 	u32 val, gcnt, reg;
@@ -928,47 +913,80 @@
 	return 0;
 }
 
-static int __init cpr_pvs_init(struct cpr_regulator *cpr_vreg)
+static int __devinit cpr_is_fuse_redundant(struct cpr_regulator *cpr_vreg,
+					 u32 redun_sel[4])
 {
-	void __iomem *efuse_base;
-	u32 efuse_bits, redundant, shift, mask;
-	int i, process;
+	u32 fuse_bits;
+	int redundant;
 
-	efuse_base = ioremap(cpr_vreg->pvs_efuse, 4);
-	if (!efuse_base) {
-		pr_err("Unable to map pvs_efuse 0x%08x\n",
-				cpr_vreg->pvs_efuse);
-		return -EINVAL;
+	fuse_bits = readl_relaxed(cpr_vreg->efuse_base
+				  + redun_sel[0] * BYTES_PER_FUSE_ROW);
+	fuse_bits = (fuse_bits >> redun_sel[1]) & ((1 << redun_sel[2]) - 1);
+	if (fuse_bits == redun_sel[3])
+		redundant = 1;
+	else
+		redundant = 0;
+
+	pr_info("[row:%d] = 0x%x @%d:%d = %d?: redundant=%d\n",
+		redun_sel[0], fuse_bits,
+		redun_sel[1], redun_sel[2], redun_sel[3], redundant);
+	return redundant;
+}
+
+static int __devinit cpr_pvs_init(struct platform_device *pdev,
+			       struct cpr_regulator *cpr_vreg)
+{
+	struct device_node *of_node = pdev->dev.of_node;
+	u32 efuse_bits;
+	int rc, process;
+	u32 pvs_fuse[3], pvs_fuse_redun_sel[4];
+	bool redundant;
+	size_t pvs_bins;
+
+	rc = of_property_read_u32_array(of_node, "qcom,pvs-fuse-redun-sel",
+					pvs_fuse_redun_sel, 4);
+	if (rc < 0) {
+		pr_err("pvs-fuse-redun-sel missing: rc=%d\n", rc);
+		return rc;
 	}
 
-	efuse_bits = readl_relaxed(efuse_base);
+	redundant = cpr_is_fuse_redundant(cpr_vreg, pvs_fuse_redun_sel);
+
+	if (redundant) {
+		rc = of_property_read_u32_array(of_node, "qcom,pvs-fuse-redun",
+						pvs_fuse, 3);
+		if (rc < 0) {
+			pr_err("pvs-fuse-redun missing: rc=%d\n", rc);
+			return rc;
+		}
+	} else {
+		rc = of_property_read_u32_array(of_node, "qcom,pvs-fuse",
+						pvs_fuse, 3);
+		if (rc < 0) {
+			pr_err("pvs-fuse missing: rc=%d\n", rc);
+			return rc;
+		}
+	}
 
 	/* Construct PVS process # from the efuse bits */
-	redundant = (efuse_bits >> PVS_FUSE_REDUNDANT_SHIFT)
-			& PVS_FUSE_REDUNDANT_MASK;
-	if (redundant == 2)
-		shift = PVS_FUSE_BINS_REDUNDANT_SHIFT;
-	else
-		shift = PVS_FUSE_BINS_SHIFT;
-	mask = (1 << cpr_vreg->num_efuse_bits) - 1;
-	cpr_vreg->pvs_bin = (efuse_bits >> shift) & mask;
+	efuse_bits = readl_relaxed(cpr_vreg->efuse_base +
+				   pvs_fuse[0] * BYTES_PER_FUSE_ROW);
+	cpr_vreg->pvs_bin = (efuse_bits >> pvs_fuse[1]) &
+				   ((1 << pvs_fuse[2]) - 1);
 
-	/* Set ceiling max and use it for APC_PVS_NO */
-	cpr_vreg->ceiling_max =
-		cpr_vreg->pvs_corner_v[APC_PVS_SLOW][CPR_CORNER_TURBO];
-
-	iounmap(efuse_base);
+	pvs_bins = 1 << pvs_fuse[2];
+	rc = of_property_read_u32_array(of_node, "qcom,pvs-bin-process",
+					cpr_vreg->pvs_bin_process,
+					pvs_bins);
+	if (rc < 0) {
+		pr_err("pvs-bin-process missing: rc=%d\n", rc);
+		return rc;
+	}
 
 	process = cpr_vreg->pvs_bin_process[cpr_vreg->pvs_bin];
-	pr_info("[0x%08X] = 0x%08X, n_bits=%d, bin=%d (%d) [redundant=%d]\n",
-		cpr_vreg->pvs_efuse, efuse_bits, cpr_vreg->num_efuse_bits,
-		cpr_vreg->pvs_bin, process, redundant);
-	for (i = APC_PVS_SLOW; i < NUM_APC_PVS; i++) {
-		pr_info("[%d] [%d %d %d] uV\n", i,
-			cpr_vreg->pvs_corner_v[i][CPR_CORNER_SVS],
-			cpr_vreg->pvs_corner_v[i][CPR_CORNER_NORMAL],
-			cpr_vreg->pvs_corner_v[i][CPR_CORNER_TURBO]);
-	}
+	pr_info("[row:%d] = 0x%08X, n_bits=%d, bin=%d (%d)\n",
+		pvs_fuse[0], efuse_bits, pvs_fuse[2],
+		cpr_vreg->pvs_bin, process);
 
 	if (process == APC_PVS_NO || process >= NUM_APC_PVS) {
 		pr_err("Bin=%d (%d) is out of spec. Assume SLOW.\n",
@@ -994,7 +1012,7 @@
 	}								\
 } while (0)
 
-static int __init cpr_apc_init(struct platform_device *pdev,
+static int __devinit cpr_apc_init(struct platform_device *pdev,
 			       struct cpr_regulator *cpr_vreg)
 {
 	struct device_node *of_node = pdev->dev.of_node;
@@ -1055,81 +1073,124 @@
 	}
 }
 
-static int __init cpr_init_cpr_efuse(struct cpr_regulator *cpr_vreg)
+static int __devinit cpr_init_cpr_efuse(struct platform_device *pdev,
+				     struct cpr_regulator *cpr_vreg)
 {
-	void __iomem *efuse_base;
+	struct device_node *of_node = pdev->dev.of_node;
+	int i, rc = 0;
+	bool redundant;
+	u32 cpr_fuse_redun_sel[4];
+	char *targ_quot_str, *ro_sel_str;
+	u32 cpr_fuse_row;
+	u32 bp_cpr_disable, bp_scheme;
+	int bp_target_quot[CPR_CORNER_MAX];
+	int bp_ro_sel[CPR_CORNER_MAX];
 	u32 ro_sel, val;
-	u64 fuse_bits;
-	int ro_sel_shift[CPR_CORNER_MAX];
+	u64 fuse_bits, fuse_bits_2;
 
-	efuse_base = ioremap(cpr_vreg->cpr_fuse_addr, 16);
-	if (!efuse_base) {
-		pr_err("Unable to map cpr_fuse_addr 0x%08x\n",
-				cpr_vreg->cpr_fuse_addr);
-		return -EINVAL;
+	rc = of_property_read_u32_array(of_node, "qcom,cpr-fuse-redun-sel",
+					cpr_fuse_redun_sel, 4);
+	if (rc < 0) {
+		pr_err("cpr-fuse-redun-sel missing: rc=%d\n", rc);
+		return rc;
 	}
 
-	cpr_vreg->cpr_fuse_bits = readll_relaxed(efuse_base);
-	cpr_vreg->cpr_fuse_bits_2 = readll_relaxed(efuse_base + 8);
+	redundant = cpr_is_fuse_redundant(cpr_vreg, cpr_fuse_redun_sel);
 
-	iounmap(efuse_base);
+	if (redundant) {
+		CPR_PROP_READ_U32(of_node, "cpr-fuse-redun-row",
+				  &cpr_fuse_row, rc);
+		targ_quot_str = "qcom,cpr-fuse-redun-target-quot";
+		ro_sel_str = "qcom,cpr-fuse-redun-ro-sel";
+	} else {
+		CPR_PROP_READ_U32(of_node, "cpr-fuse-row",
+				  &cpr_fuse_row, rc);
+		targ_quot_str = "qcom,cpr-fuse-target-quot";
+		ro_sel_str = "qcom,cpr-fuse-ro-sel";
+	}
+	if (rc)
+		return rc;
+
+	rc = of_property_read_u32_array(of_node,
+		targ_quot_str,
+		&bp_target_quot[CPR_CORNER_SVS],
+		CPR_CORNER_MAX - CPR_CORNER_SVS);
+	if (rc < 0) {
+		pr_err("missing %s: rc=%d\n", targ_quot_str, rc);
+		return rc;
+	}
+
+	rc = of_property_read_u32_array(of_node,
+		ro_sel_str,
+		&bp_ro_sel[CPR_CORNER_SVS],
+		CPR_CORNER_MAX - CPR_CORNER_SVS);
+	if (rc < 0) {
+		pr_err("missing %s: rc=%d\n", ro_sel_str, rc);
+		return rc;
+	}
 
 	/* Read the control bits of eFuse */
-	cpr_vreg->cpr_fuse_disable = (cpr_vreg->cpr_fuse_bits >>
-				      CPR_FUSE_DISABLE_CPR_SHIFT) & 0x01;
-	cpr_vreg->cpr_fuse_local = (cpr_vreg->cpr_fuse_bits >>
-				    CPR_FUSE_LOCAL_APPROACH_SHIFT) & 0x01;
-	cpr_vreg->cpr_fuse_redundancy = (cpr_vreg->cpr_fuse_bits >>
-					 CPR_FUSE_REDUNDANT_SHIFT) & 0x01;
+	fuse_bits = readll_relaxed(cpr_vreg->efuse_base
+				   + cpr_fuse_row * BYTES_PER_FUSE_ROW);
+	pr_info("[row:%d] = 0x%llx\n", cpr_fuse_row, fuse_bits);
 
-	pr_info("[0x%08X] = 0x%llx\n", cpr_vreg->cpr_fuse_addr,
-		cpr_vreg->cpr_fuse_bits);
-	pr_info("disable = %d, local = %d, redundancy = %d\n",
-			cpr_vreg->cpr_fuse_disable,
-			cpr_vreg->cpr_fuse_local,
-			cpr_vreg->cpr_fuse_redundancy);
-	pr_info("[0x%08X] = 0x%llx\n", cpr_vreg->cpr_fuse_addr + 8,
-		cpr_vreg->cpr_fuse_bits_2);
+	if (redundant) {
+		if (of_property_read_bool(of_node,
+				"qcom,cpr-fuse-redun-bp-cpr-disable")) {
+			CPR_PROP_READ_U32(of_node,
+					  "cpr-fuse-redun-bp-cpr-disable",
+					  &bp_cpr_disable, rc);
+			CPR_PROP_READ_U32(of_node,
+					  "cpr-fuse-redun-bp-scheme",
+					  &bp_scheme, rc);
+			if (rc)
+				return rc;
+			fuse_bits_2 = fuse_bits;
+		} else {
+			u32 temp_row;
 
-	if (cpr_vreg->cpr_fuse_redundancy == 0) {
-		fuse_bits = cpr_vreg->cpr_fuse_bits;
-		ro_sel_shift[CPR_CORNER_SVS] = 54;
-		ro_sel_shift[CPR_CORNER_NORMAL] = 38;
-		ro_sel_shift[CPR_CORNER_TURBO] = 41;
+			/* Use original fuse if no optional property */
+			CPR_PROP_READ_U32(of_node, "cpr-fuse-bp-cpr-disable",
+					  &bp_cpr_disable, rc);
+			CPR_PROP_READ_U32(of_node, "cpr-fuse-bp-scheme",
+					  &bp_scheme, rc);
+			CPR_PROP_READ_U32(of_node, "cpr-fuse-row",
+					  &temp_row, rc);
+			if (rc)
+				return rc;
+			fuse_bits_2 = readll_relaxed(cpr_vreg->efuse_base
+					+ temp_row * BYTES_PER_FUSE_ROW);
+			pr_info("[original row:%d] = 0x%llx\n",
+				temp_row, fuse_bits_2);
+		}
 	} else {
-		fuse_bits = cpr_vreg->cpr_fuse_bits_2;
-		ro_sel_shift[CPR_CORNER_SVS] = 46;
-		ro_sel_shift[CPR_CORNER_NORMAL] = 36;
-		ro_sel_shift[CPR_CORNER_TURBO] = 39;
+		CPR_PROP_READ_U32(of_node, "cpr-fuse-bp-cpr-disable",
+				  &bp_cpr_disable, rc);
+		CPR_PROP_READ_U32(of_node, "cpr-fuse-bp-scheme",
+				  &bp_scheme, rc);
+		if (rc)
+			return rc;
+		fuse_bits_2 = fuse_bits;
 	}
 
-	/* SVS */
-	ro_sel = (fuse_bits >> ro_sel_shift[CPR_CORNER_SVS])
-				& CPR_FUSE_RO_SEL_BITS_MASK;
-	val = (fuse_bits >> CPR_FUSE_TARGET_QUOT_SVS_SHIFT)
-				& CPR_FUSE_TARGET_QUOT_BITS_MASK;
-	cpr_vreg->cpr_fuse_target_quot[CPR_CORNER_SVS] = val;
-	cpr_vreg->cpr_fuse_ro_sel[CPR_CORNER_SVS] = ro_sel;
-	pr_info("SVS: ro_sel = %d, target quot = 0x%04x\n", ro_sel, val);
+	cpr_vreg->cpr_fuse_disable = (fuse_bits_2 >> bp_cpr_disable) & 0x01;
+	cpr_vreg->cpr_fuse_local = (fuse_bits_2 >> bp_scheme) & 0x01;
 
-	/* Nominal */
-	ro_sel = (fuse_bits >> ro_sel_shift[CPR_CORNER_NORMAL])
-				& CPR_FUSE_RO_SEL_BITS_MASK;
-	val = (fuse_bits >> CPR_FUSE_TARGET_QUOT_NOMINAL_SHIFT)
-				& CPR_FUSE_TARGET_QUOT_BITS_MASK;
-	cpr_vreg->cpr_fuse_target_quot[CPR_CORNER_NORMAL] = val;
-	cpr_vreg->cpr_fuse_ro_sel[CPR_CORNER_NORMAL] = ro_sel;
-	pr_info("Nominal: ro_sel = %d, target quot = 0x%04x\n", ro_sel, val);
+	pr_info("disable = %d, local = %d\n",
+		cpr_vreg->cpr_fuse_disable, cpr_vreg->cpr_fuse_local);
 
-	/* Turbo */
-	ro_sel = (fuse_bits >> ro_sel_shift[CPR_CORNER_TURBO])
+	for (i = CPR_CORNER_SVS; i < CPR_CORNER_MAX; i++) {
+		ro_sel = (fuse_bits >> bp_ro_sel[i])
 				& CPR_FUSE_RO_SEL_BITS_MASK;
-	val = (fuse_bits >> CPR_FUSE_TARGET_QUOT_TURBO_SHIFT)
+		val = (fuse_bits >> bp_target_quot[i])
 				& CPR_FUSE_TARGET_QUOT_BITS_MASK;
-	cpr_vreg->cpr_fuse_target_quot[CPR_CORNER_TURBO] = val;
-	cpr_vreg->cpr_fuse_ro_sel[CPR_CORNER_TURBO] = ro_sel;
-	pr_info("Turbo: ro_sel = %d, target quot = 0x%04x\n", ro_sel, val);
+		cpr_vreg->cpr_fuse_target_quot[i] = val;
+		cpr_vreg->cpr_fuse_ro_sel[i] = ro_sel;
+		pr_info("Corner[%d]: ro_sel = %d, target quot = %d\n",
+			i, ro_sel, val);
+	}
 
+	cpr_vreg->cpr_fuse_bits = fuse_bits;
 	if (!cpr_vreg->cpr_fuse_bits) {
 		cpr_vreg->cpr_fuse_disable = 1;
 		pr_err("cpr_fuse_bits = 0: set cpr_fuse_disable = 1\n");
@@ -1138,7 +1199,7 @@
 	return 0;
 }
 
-static int __init cpr_init_cpr_voltages(struct cpr_regulator *cpr_vreg)
+static int __devinit cpr_init_cpr_voltages(struct cpr_regulator *cpr_vreg)
 {
 	int i;
 
@@ -1155,7 +1216,7 @@
 	return 0;
 }
 
-static int __init cpr_init_cpr_parameters(struct platform_device *pdev,
+static int __devinit cpr_init_cpr_parameters(struct platform_device *pdev,
 					  struct cpr_regulator *cpr_vreg)
 {
 	struct device_node *of_node = pdev->dev.of_node;
@@ -1223,20 +1284,12 @@
 	return rc;
 }
 
-static int __init cpr_init_cpr(struct platform_device *pdev,
+static int __devinit cpr_init_cpr(struct platform_device *pdev,
 			       struct cpr_regulator *cpr_vreg)
 {
 	struct resource *res;
 	int rc = 0;
 
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-					   "cpr_efuse");
-	if (!res || !res->start) {
-		pr_err("cpr_efuse missing: res=%p\n", res);
-		return -EINVAL;
-	}
-	cpr_vreg->cpr_fuse_addr = res->start;
-
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rbcpr_clk");
 	if (!res || !res->start) {
 		pr_err("missing rbcpr_clk address: res=%p\n", res);
@@ -1244,7 +1297,7 @@
 	}
 	cpr_vreg->rbcpr_clk_addr = res->start;
 
-	rc = cpr_init_cpr_efuse(cpr_vreg);
+	rc = cpr_init_cpr_efuse(pdev, cpr_vreg);
 	if (rc)
 		return rc;
 
@@ -1287,44 +1340,41 @@
 	return 0;
 }
 
-static int __init cpr_pvs_parse_dt(struct platform_device *pdev,
-				   struct cpr_regulator *cpr_vreg)
+static int __devinit cpr_efuse_init(struct platform_device *pdev,
+				 struct cpr_regulator *cpr_vreg)
+{
+	struct resource *res;
+	int len;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "efuse_addr");
+	if (!res || !res->start) {
+		pr_err("efuse_addr missing: res=%p\n", res);
+		return -EINVAL;
+	}
+	cpr_vreg->efuse_addr = res->start;
+	len = res->end - res->start + 1;
+
+	pr_info("efuse_addr = 0x%x (len=0x%x)\n", res->start, len);
+
+	cpr_vreg->efuse_base = ioremap(cpr_vreg->efuse_addr, len);
+	if (!cpr_vreg->efuse_base) {
+		pr_err("Unable to map efuse_addr 0x%08x\n",
+				cpr_vreg->efuse_addr);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static void cpr_efuse_free(struct cpr_regulator *cpr_vreg)
+{
+	iounmap(cpr_vreg->efuse_base);
+}
+
+static int __devinit cpr_voltage_plan_init(struct platform_device *pdev,
+					struct cpr_regulator *cpr_vreg)
 {
 	struct device_node *of_node = pdev->dev.of_node;
-	struct resource *res;
-	int rc;
-	size_t pvs_bins;
-
-	/* Parse process voltage parameters */
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pvs_efuse");
-	if (!res || !res->start) {
-		pr_err("pvs_efuse missing: res=%p\n", res);
-		return -EINVAL;
-	}
-	cpr_vreg->pvs_efuse = res->start;
-
-	rc = of_property_read_u32(of_node, "qcom,num-efuse-bits",
-				&cpr_vreg->num_efuse_bits);
-	if (rc < 0) {
-		pr_err("num-efuse-bits missing: rc=%d\n", rc);
-		return rc;
-	}
-
-	if (cpr_vreg->num_efuse_bits == 0 ||
-	    cpr_vreg->num_efuse_bits > CPR_PVS_EFUSE_BITS_MAX) {
-		pr_err("invalid num-efuse-bits : %d\n",
-		       cpr_vreg->num_efuse_bits);
-		return -EINVAL;
-	}
-
-	pvs_bins = 1 << cpr_vreg->num_efuse_bits;
-	rc = of_property_read_u32_array(of_node, "qcom,pvs-bin-process",
-					cpr_vreg->pvs_bin_process,
-					pvs_bins);
-	if (rc < 0) {
-		pr_err("pvs-bin-process missing: rc=%d\n", rc);
-		return rc;
-	}
+	int rc, i;
 
 	rc = of_property_read_u32_array(of_node,
 		"qcom,pvs-corner-ceiling-slow",
@@ -1353,6 +1403,17 @@
 		return rc;
 	}
 
+	/* Set ceiling max and use it for APC_PVS_NO */
+	cpr_vreg->ceiling_max =
+		cpr_vreg->pvs_corner_v[APC_PVS_SLOW][CPR_CORNER_TURBO];
+
+	for (i = APC_PVS_SLOW; i < NUM_APC_PVS; i++) {
+		pr_info("[%d] [%d %d %d] uV\n", i,
+			cpr_vreg->pvs_corner_v[i][CPR_CORNER_SVS],
+			cpr_vreg->pvs_corner_v[i][CPR_CORNER_NORMAL],
+			cpr_vreg->pvs_corner_v[i][CPR_CORNER_TURBO]);
+	}
+
 	return 0;
 }
 
@@ -1386,31 +1447,39 @@
 		return -ENOMEM;
 	}
 
-	rc = cpr_pvs_parse_dt(pdev, cpr_vreg);
+	rc = cpr_efuse_init(pdev, cpr_vreg);
 	if (rc) {
-		pr_err("Wrong DT parameter specified: rc=%d\n", rc);
+		pr_err("Wrong eFuse address specified: rc=%d\n", rc);
 		return rc;
 	}
 
-	rc = cpr_pvs_init(cpr_vreg);
+	rc = cpr_voltage_plan_init(pdev, cpr_vreg);
+	if (rc) {
+		pr_err("Wrong DT parameter specified: rc=%d\n", rc);
+		goto err_out;
+	}
+
+	rc = cpr_pvs_init(pdev, cpr_vreg);
 	if (rc) {
 		pr_err("Initialize PVS wrong: rc=%d\n", rc);
-		return rc;
+		goto err_out;
 	}
 
 	rc = cpr_apc_init(pdev, cpr_vreg);
 	if (rc) {
 		if (rc != -EPROBE_DEFER)
 			pr_err("Initialize APC wrong: rc=%d\n", rc);
-		return rc;
+		goto err_out;
 	}
 
 	rc = cpr_init_cpr(pdev, cpr_vreg);
 	if (rc) {
 		pr_err("Initialize CPR failed: rc=%d\n", rc);
-		return rc;
+		goto err_out;
 	}
 
+	cpr_efuse_free(cpr_vreg);
+
 	mutex_init(&cpr_vreg->cpr_mutex);
 
 	rdesc			= &cpr_vreg->rdesc;
@@ -1433,6 +1502,10 @@
 	the_cpr = cpr_vreg;
 
 	return 0;
+
+err_out:
+	cpr_efuse_free(cpr_vreg);
+	return rc;
 }
 
 static int __devexit cpr_regulator_remove(struct platform_device *pdev)
diff --git a/arch/arm/mach-msm/include/mach/clk-provider.h b/arch/arm/mach-msm/include/mach/clk-provider.h
index 1fad7f6..72b5cc1 100644
--- a/arch/arm/mach-msm/include/mach/clk-provider.h
+++ b/arch/arm/mach-msm/include/mach/clk-provider.h
@@ -114,7 +114,7 @@
 	int (*set_max_rate)(struct clk *clk, unsigned long rate);
 	int (*set_flags)(struct clk *clk, unsigned flags);
 	unsigned long (*get_rate)(struct clk *clk);
-	int (*list_rate)(struct clk *clk, unsigned n);
+	long (*list_rate)(struct clk *clk, unsigned n);
 	int (*is_enabled)(struct clk *clk);
 	long (*round_rate)(struct clk *clk, unsigned long rate);
 	int (*set_parent)(struct clk *clk, struct clk *parent);
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index aba5fee..c0cca1d 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -2266,6 +2266,48 @@
 }
 
 /**
+ * msm_ipc_router_rx_data_wait() - Wait for new message destined to a local port.
+ * @port_ptr: Pointer to the local port
+ * @timeout: < 0 timeout indicates infinite wait till a message arrives.
+ *	     > 0 timeout indicates the wait time.
+ *	     0 indicates that we do not wait.
+ * @return: 0 if there are pending messages to read,
+ *	    standard Linux error code otherwise.
+ *
+ * Checks for the availability of messages that are destined to a local port.
+ * If no messages are present then waits as per @timeout.
+ */
+int msm_ipc_router_rx_data_wait(struct msm_ipc_port *port_ptr, long timeout)
+{
+	int ret = 0;
+
+	mutex_lock(&port_ptr->port_rx_q_lock_lhb3);
+	while (list_empty(&port_ptr->port_rx_q)) {
+		mutex_unlock(&port_ptr->port_rx_q_lock_lhb3);
+		if (timeout < 0) {
+			ret = wait_event_interruptible(
+					port_ptr->port_rx_wait_q,
+					!list_empty(&port_ptr->port_rx_q));
+			if (ret)
+				return ret;
+		} else if (timeout > 0) {
+			timeout = wait_event_interruptible_timeout(
+					port_ptr->port_rx_wait_q,
+					!list_empty(&port_ptr->port_rx_q),
+					timeout);
+			if (timeout < 0)
+				return -EFAULT;
+		}
+		if (timeout == 0)
+			return -ENOMSG;
+		mutex_lock(&port_ptr->port_rx_q_lock_lhb3);
+	}
+	mutex_unlock(&port_ptr->port_rx_q_lock_lhb3);
+
+	return ret;
+}
+
+/**
  * msm_ipc_router_recv_from() - Recieve messages destined to a local port.
  * @port_ptr: Pointer to the local port
  * @data : Pointer to the socket buffer head
@@ -2274,7 +2316,7 @@
  *	     > 0 timeout indicates the wait time.
  *	     0 indicates that we do not wait.
  * @return: = Number of bytes read(On successful read operation).
- *	    = 0 (If there are no pending messages and timeout is 0).
+ *	    = -ENOMSG (If there are no pending messages and timeout is 0).
  *	    = -EINVAL (If either of the arguments, port_ptr or data is invalid)
  *	    = -EFAULT (If there are no pending messages when timeout is > 0
  *	      and the wait_event_interruptible_timeout has returned value > 0)
@@ -2303,28 +2345,10 @@
 	}
 
 	*data = NULL;
-	mutex_lock(&port_ptr->port_rx_q_lock_lhb3);
-	while (list_empty(&port_ptr->port_rx_q)) {
-		mutex_unlock(&port_ptr->port_rx_q_lock_lhb3);
-		if (timeout < 0) {
-			ret = wait_event_interruptible(
-					port_ptr->port_rx_wait_q,
-					!list_empty(&port_ptr->port_rx_q));
-			if (ret)
-				return ret;
-		} else if (timeout > 0) {
-			timeout = wait_event_interruptible_timeout(
-					port_ptr->port_rx_wait_q,
-					!list_empty(&port_ptr->port_rx_q),
-					timeout);
-			if (timeout < 0)
-				return -EFAULT;
-		}
-		if (timeout == 0)
-			return 0;
-		mutex_lock(&port_ptr->port_rx_q_lock_lhb3);
-	}
-	mutex_unlock(&port_ptr->port_rx_q_lock_lhb3);
+
+	ret = msm_ipc_router_rx_data_wait(port_ptr, timeout);
+	if (ret)
+		return ret;
 
 	ret = msm_ipc_router_read(port_ptr, data, 0);
 	if (ret <= 0 || !(*data))
@@ -2358,12 +2382,10 @@
 
 	ret = msm_ipc_router_recv_from(port_ptr, &in_skb_head, src, 0);
 
-	if (ret == 0)
-		return -ENOMSG;
-
 	if (ret < 0) {
-		pr_err("%s: msm_ipc_router_recv_from failed - ret: %d\n",
-			__func__, ret);
+		if (ret != -ENOMSG)
+			pr_err("%s: msm_ipc_router_recv_from failed - ret: %d\n",
+				__func__, ret);
 		return ret;
 	}
 
diff --git a/arch/arm/mach-msm/ipc_router.h b/arch/arm/mach-msm/ipc_router.h
index 55aeade..7bfc52b 100644
--- a/arch/arm/mach-msm/ipc_router.h
+++ b/arch/arm/mach-msm/ipc_router.h
@@ -160,6 +160,8 @@
 
 void msm_ipc_sync_default_sec_rule(void *rule);
 
+int msm_ipc_router_rx_data_wait(struct msm_ipc_port *port_ptr, long timeout);
+
 #if defined CONFIG_MSM_IPC_ROUTER_SMD_XPRT
 extern void *msm_ipc_load_default_node(void);
 
diff --git a/arch/arm/mach-msm/ipc_socket.c b/arch/arm/mach-msm/ipc_socket.c
index 515dc92..ea27c71 100644
--- a/arch/arm/mach-msm/ipc_socket.c
+++ b/arch/arm/mach-msm/ipc_socket.c
@@ -411,33 +411,14 @@
 
 	lock_sock(sk);
 	timeout = sk->sk_rcvtimeo;
-	mutex_lock(&port_ptr->port_rx_q_lock_lhb3);
-	while (list_empty(&port_ptr->port_rx_q)) {
-		mutex_unlock(&port_ptr->port_rx_q_lock_lhb3);
-		release_sock(sk);
-		if (timeout < 0) {
-			ret = wait_event_interruptible(
-					port_ptr->port_rx_wait_q,
-					!list_empty(&port_ptr->port_rx_q));
-			if (ret)
-				return ret;
-		} else if (timeout > 0) {
-			timeout = wait_event_interruptible_timeout(
-					port_ptr->port_rx_wait_q,
-					!list_empty(&port_ptr->port_rx_q),
-					timeout);
-			if (timeout < 0)
-				return -EFAULT;
-		}
 
-		if (timeout == 0) {
+	ret = msm_ipc_router_rx_data_wait(port_ptr, timeout);
+	if (ret) {
+		release_sock(sk);
+		if (ret == -ENOMSG)
 			m->msg_namelen = 0;
-			return 0;
-		}
-		lock_sock(sk);
-		mutex_lock(&port_ptr->port_rx_q_lock_lhb3);
+		return ret;
 	}
-	mutex_unlock(&port_ptr->port_rx_q_lock_lhb3);
 
 	ret = msm_ipc_router_read(port_ptr, &msg, buf_len);
 	if (ret <= 0 || !msg) {
diff --git a/arch/arm/mach-msm/peripheral-loader.c b/arch/arm/mach-msm/peripheral-loader.c
index c572291..ff1fd4f 100644
--- a/arch/arm/mach-msm/peripheral-loader.c
+++ b/arch/arm/mach-msm/peripheral-loader.c
@@ -771,7 +771,7 @@
 		ret = request_threaded_irq(desc->proxy_unvote_irq,
 				  NULL,
 				  proxy_unvote_intr_handler,
-				  IRQF_TRIGGER_RISING|IRQF_SHARED,
+				  IRQF_TRIGGER_RISING,
 				  desc->name, desc);
 		if (ret < 0) {
 			dev_err(desc->dev,
diff --git a/arch/arm/mach-msm/pil-msa.c b/arch/arm/mach-msm/pil-msa.c
index a8f5b0e..3a26af9 100644
--- a/arch/arm/mach-msm/pil-msa.c
+++ b/arch/arm/mach-msm/pil-msa.c
@@ -292,25 +292,6 @@
 	.shutdown = pil_msa_pbl_shutdown,
 };
 
-static int pil_msa_mba_make_proxy_votes(struct pil_desc *pil)
-{
-	int ret;
-	struct mba_data *drv = container_of(pil, struct mba_data, desc);
-
-	ret = clk_prepare_enable(drv->xo);
-	if (ret) {
-		dev_err(pil->dev, "Failed to enable XO\n");
-		return ret;
-	}
-	return 0;
-}
-
-static void pil_msa_mba_remove_proxy_votes(struct pil_desc *pil)
-{
-	struct mba_data *drv = container_of(pil, struct mba_data, desc);
-	clk_disable_unprepare(drv->xo);
-}
-
 static int pil_msa_mba_init_image(struct pil_desc *pil,
 				  const u8 *metadata, size_t size)
 {
@@ -400,8 +381,6 @@
 
 struct pil_reset_ops pil_msa_mba_ops = {
 	.init_image = pil_msa_mba_init_image,
-	.proxy_vote = pil_msa_mba_make_proxy_votes,
-	.proxy_unvote = pil_msa_mba_remove_proxy_votes,
 	.verify_blob = pil_msa_mba_verify_blob,
 	.auth_and_reset = pil_msa_mba_auth,
 };
diff --git a/arch/arm/mach-msm/pil-q6v5-mss.c b/arch/arm/mach-msm/pil-q6v5-mss.c
index 4d76c08..1f03fd32 100644
--- a/arch/arm/mach-msm/pil-q6v5-mss.c
+++ b/arch/arm/mach-msm/pil-q6v5-mss.c
@@ -429,8 +429,6 @@
 	mba_desc->dev = &pdev->dev;
 	mba_desc->ops = &pil_msa_mba_ops;
 	mba_desc->owner = THIS_MODULE;
-	mba_desc->proxy_timeout = PROXY_TIMEOUT_MS;
-	mba_desc->proxy_unvote_irq = clk_ready;
 
 	ret = pil_desc_init(mba_desc);
 	if (ret)
diff --git a/arch/arm/mach-msm/test_qmi_client.c b/arch/arm/mach-msm/test_qmi_client.c
index d070e37..b701be8 100644
--- a/arch/arm/mach-msm/test_qmi_client.c
+++ b/arch/arm/mach-msm/test_qmi_client.c
@@ -61,6 +61,25 @@
 /* Variable to hold the test result */
 static int test_res;
 
+static unsigned int callback_count;
+static void test_async_resp_cb(struct qmi_handle *handle,
+			   unsigned int msg_id, void *msg,
+			   void *resp_cb_data, int stat)
+{
+	callback_count++;
+	if (stat == 0)
+		D("%s invoked %d time(s): [RESP_LEN] = %d, [RESP_VALID] = %d",
+			__func__, callback_count,
+			((struct test_data_resp_msg_v01 *)msg)->data_len,
+			((struct test_data_resp_msg_v01 *)msg)->data_valid);
+	else if (stat < 0)
+		pr_err("%s: Request Failed [MSG_ID]: %d, [ERR_ID]: %d, [Callback_count]: %d",
+			__func__, msg_id, stat,	callback_count);
+
+	kfree(msg);
+	kfree(resp_cb_data);
+}
+
 static int test_qmi_ping_pong_send_sync_msg(void)
 {
 	struct test_ping_req_msg_v01 req;
@@ -138,12 +157,68 @@
 	return rc;
 }
 
+static int test_qmi_data_send_async_msg(unsigned int data_len)
+{
+	struct test_data_req_msg_v01 *req;
+	struct test_data_resp_msg_v01 *resp;
+	struct msg_desc req_desc, *resp_desc;
+	int rc, i;
+
+	req = kzalloc(sizeof(struct test_data_req_msg_v01), GFP_KERNEL);
+	if (!req) {
+		pr_err("%s: Data req msg alloc failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	resp = kzalloc(sizeof(struct test_data_resp_msg_v01), GFP_KERNEL);
+	if (!resp) {
+		pr_err("%s: Data resp msg alloc failed\n", __func__);
+		kfree(req);
+		return -ENOMEM;
+	}
+
+	resp_desc = kzalloc(sizeof(struct msg_desc), GFP_KERNEL);
+	if (!resp_desc) {
+		pr_err("%s: Resp_desc msg alloc failed\n", __func__);
+		kfree(req);
+		kfree(resp);
+		return -ENOMEM;
+	}
+
+	req->data_len = data_len;
+	for (i = 0; i < data_len; i = i + sizeof(int))
+		memcpy(req->data + i, (uint8_t *)&i, sizeof(int));
+	req->client_name_valid = 0;
+
+	req_desc.max_msg_len = TEST_DATA_REQ_MAX_MSG_LEN_V01;
+	req_desc.msg_id = TEST_DATA_REQ_MSG_ID_V01;
+	req_desc.ei_array = test_data_req_msg_v01_ei;
+
+	resp_desc->max_msg_len = TEST_DATA_REQ_MAX_MSG_LEN_V01;
+	resp_desc->msg_id = TEST_DATA_REQ_MSG_ID_V01;
+	resp_desc->ei_array = test_data_resp_msg_v01_ei;
+
+	rc = qmi_send_req_nowait(test_clnt, &req_desc, req, sizeof(*req),
+			       resp_desc, resp, sizeof(*resp),
+			       test_async_resp_cb, (void *)resp_desc);
+	if (rc < 0) {
+		pr_err("%s: send req failed\n", __func__);
+		kfree(resp);
+		kfree(resp_desc);
+	}
+	kfree(req);
+	return rc;
+}
+
 static void test_clnt_recv_msg(struct work_struct *work)
 {
 	int rc;
 
-	rc = qmi_recv_msg(test_clnt);
-	if (rc < 0)
+	do {
+		D("%s: Notified about a Receive Event", __func__);
+	} while ((rc = qmi_recv_msg(test_clnt)) == 0);
+
+	if (rc != -ENOMSG)
 		pr_err("%s: Error receiving message\n", __func__);
 }
 
@@ -280,6 +355,32 @@
 				} while (test_clnt_reset);
 			}
 		}
+	} else if (!strncmp(cmd, "data_async", sizeof(cmd))) {
+		int i;
+		callback_count = 0;
+		for (i = 0; i < test_rep_cnt; i++) {
+			test_res = test_qmi_data_send_async_msg(test_data_sz);
+			if (test_res == -ENETRESET || test_clnt_reset) {
+				--i;
+				do {
+					msleep(50);
+				} while (test_clnt_reset);
+			} else if (test_res < 0) {
+				--i;
+				pr_err("%s: Error sending txn, aborting now",
+					__func__);
+				break;
+			}
+		}
+		while (callback_count < i) {
+			if (test_clnt_reset) {
+				pr_err("%s: Service Exited", __func__);
+				break;
+			}
+			msleep(50);
+		}
+		D("%s complete\n", __func__);
+		callback_count = 0;
 	} else {
 		test_res = -EINVAL;
 	}
diff --git a/block/blk-core.c b/block/blk-core.c
index 8e12c45..40d9b35 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -2058,10 +2058,8 @@
 			 * not be passed by new incoming requests
 			 */
 			rq->cmd_flags |= REQ_STARTED;
-			if (rq->cmd_flags & REQ_URGENT) {
-				WARN_ON(q->dispatched_urgent);
+			if (rq->cmd_flags & REQ_URGENT)
 				q->dispatched_urgent = true;
-			}
 			trace_block_rq_issue(q, rq);
 		}
 
@@ -3153,7 +3151,7 @@
 		q->rpm_status = RPM_ACTIVE;
 		__blk_run_queue(q);
 		pm_runtime_mark_last_busy(q->dev);
-		pm_runtime_autosuspend(q->dev);
+		pm_request_autosuspend(q->dev);
 	} else {
 		q->rpm_status = RPM_SUSPENDED;
 	}
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 32629e2..b4711cb 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -239,6 +239,9 @@
 	unsigned long workload_expires;
 	struct cfq_group *serving_group;
 
+	unsigned int nr_urgent_pending;
+	unsigned int nr_urgent_in_flight;
+
 	/*
 	 * Each priority tree is sorted by next_request position.  These
 	 * trees are used when determining if two or more queues are
@@ -2091,6 +2094,14 @@
 	(RQ_CFQG(rq))->dispatched++;
 	elv_dispatch_sort(q, rq);
 
+	if (rq->cmd_flags & REQ_URGENT) {
+		if (!cfqd->nr_urgent_pending)
+			WARN_ON(1);
+		else
+			cfqd->nr_urgent_pending--;
+		cfqd->nr_urgent_in_flight++;
+	}
+
 	cfqd->rq_in_flight[cfq_cfqq_sync(cfqq)]++;
 	cfqq->nr_sectors += blk_rq_sectors(rq);
 	cfq_blkiocg_update_dispatch_stats(&cfqq->cfqg->blkg, blk_rq_bytes(rq),
@@ -3194,6 +3205,69 @@
 	}
 }
 
+/*
+ * Called when a request (rq) is reinserted (to cfqq). Check if there's
+ * something we should do about it
+ */
+static void
+cfq_rq_requeued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
+		struct request *rq)
+{
+	struct cfq_io_cq *cic = RQ_CIC(rq);
+
+	cfqd->rq_queued++;
+	if (rq->cmd_flags & REQ_PRIO)
+		cfqq->prio_pending++;
+
+	cfqq->dispatched--;
+	(RQ_CFQG(rq))->dispatched--;
+
+	cfqd->rq_in_flight[cfq_cfqq_sync(cfqq)]--;
+
+	cfq_update_io_thinktime(cfqd, cfqq, cic);
+	cfq_update_io_seektime(cfqd, cfqq, rq);
+	cfq_update_idle_window(cfqd, cfqq, cic);
+
+	cfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq);
+
+	if (cfqq == cfqd->active_queue) {
+		if (cfq_cfqq_wait_request(cfqq)) {
+			if (blk_rq_bytes(rq) > PAGE_CACHE_SIZE ||
+			    cfqd->busy_queues > 1) {
+				cfq_del_timer(cfqd, cfqq);
+				cfq_clear_cfqq_wait_request(cfqq);
+			} else {
+				cfq_blkiocg_update_idle_time_stats(
+						&cfqq->cfqg->blkg);
+				cfq_mark_cfqq_must_dispatch(cfqq);
+			}
+		}
+	} else if (cfq_should_preempt(cfqd, cfqq, rq)) {
+		cfq_preempt_queue(cfqd, cfqq);
+	}
+}
+
+static int cfq_reinsert_request(struct request_queue *q, struct request *rq)
+{
+	struct cfq_data *cfqd = q->elevator->elevator_data;
+	struct cfq_queue *cfqq = RQ_CFQQ(rq);
+
+	if (!cfqq || cfqq->cfqd != cfqd)
+		return -EIO;
+
+	cfq_log_cfqq(cfqd, cfqq, "re-insert_request");
+	list_add(&rq->queuelist, &cfqq->fifo);
+	cfq_add_rq_rb(rq);
+
+	cfq_rq_requeued(cfqd, cfqq, rq);
+	if (rq->cmd_flags & REQ_URGENT) {
+			if (cfqd->nr_urgent_in_flight)
+				cfqd->nr_urgent_in_flight--;
+			cfqd->nr_urgent_pending++;
+	}
+	return 0;
+}
+
 static void cfq_insert_request(struct request_queue *q, struct request *rq)
 {
 	struct cfq_data *cfqd = q->elevator->elevator_data;
@@ -3208,7 +3282,45 @@
 	cfq_blkiocg_update_io_add_stats(&(RQ_CFQG(rq))->blkg,
 			&cfqd->serving_group->blkg, rq_data_dir(rq),
 			rq_is_sync(rq));
+
 	cfq_rq_enqueued(cfqd, cfqq, rq);
+
+	if (rq->cmd_flags & REQ_URGENT) {
+		WARN_ON(1);
+		blk_dump_rq_flags(rq, "");
+		rq->cmd_flags &= ~REQ_URGENT;
+	}
+
+	/* Request is considered URGENT if:
+	 * 1. The queue being served is of a lower IO priority then the new
+	 *    request
+	 * OR:
+	 * 2. The workload being performed is ASYNC
+	 * Only READ requests may be considered as URGENT
+	 */
+	if ((cfqd->active_queue &&
+		 cfqq->ioprio_class < cfqd->active_queue->ioprio_class) ||
+		(cfqd->serving_type == ASYNC_WORKLOAD &&
+		 rq_data_dir(rq) == READ)) {
+		rq->cmd_flags |= REQ_URGENT;
+		cfqd->nr_urgent_pending++;
+	}
+}
+
+
+/**
+ * cfq_urgent_pending() - Return TRUE if there is an urgent
+ *			  request on scheduler
+ * @q:	requests queue
+ */
+static bool cfq_urgent_pending(struct request_queue *q)
+{
+	struct cfq_data *cfqd = q->elevator->elevator_data;
+
+	if (cfqd->nr_urgent_pending && !cfqd->nr_urgent_in_flight)
+		return true;
+
+	return false;
 }
 
 /*
@@ -3292,6 +3404,14 @@
 	const int sync = rq_is_sync(rq);
 	unsigned long now;
 
+	if (rq->cmd_flags & REQ_URGENT) {
+		if (!cfqd->nr_urgent_in_flight)
+			WARN_ON(1);
+		else
+			cfqd->nr_urgent_in_flight--;
+		rq->cmd_flags &= ~REQ_URGENT;
+	}
+
 	now = jiffies;
 	cfq_log_cfqq(cfqd, cfqq, "complete rqnoidle %d",
 		     !!(rq->cmd_flags & REQ_NOIDLE));
@@ -3859,6 +3979,8 @@
 		.elevator_bio_merged_fn =	cfq_bio_merged,
 		.elevator_dispatch_fn =		cfq_dispatch_requests,
 		.elevator_add_req_fn =		cfq_insert_request,
+		.elevator_reinsert_req_fn	= cfq_reinsert_request,
+		.elevator_is_urgent_fn		= cfq_urgent_pending,
 		.elevator_activate_req_fn =	cfq_activate_request,
 		.elevator_deactivate_req_fn =	cfq_deactivate_request,
 		.elevator_completed_req_fn =	cfq_completed_request,
diff --git a/block/elevator.c b/block/elevator.c
index 44193a8..55f1f1e 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -842,7 +842,6 @@
 
 	if (rq->cmd_flags & REQ_URGENT) {
 		q->notified_urgent = false;
-		WARN_ON(!q->dispatched_urgent);
 		q->dispatched_urgent = false;
 	}
 	/*
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 7513c7b..8df1b49 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -306,9 +306,10 @@
 
 	mutex_lock(&driver->diagchar_mutex);
 	driver->ref_count--;
-	/* On Client exit, try to destroy all 3 pools */
+	/* On Client exit, try to destroy all 4 pools */
 	diagmem_exit(driver, POOL_TYPE_COPY);
 	diagmem_exit(driver, POOL_TYPE_HDLC);
+	diagmem_exit(driver, POOL_TYPE_USER);
 	diagmem_exit(driver, POOL_TYPE_WRITE_STRUCT);
 	for (i = 0; i < driver->num_clients; i++) {
 		if (NULL != diagpriv_data && diagpriv_data->pid ==
@@ -1527,11 +1528,14 @@
 		err = copy_from_user(user_space_data, buf + 4, payload_size);
 		if (err) {
 			pr_alert("diag: copy failed for DCI data\n");
+			diagmem_free(driver, user_space_data, POOL_TYPE_USER);
+			user_space_data = NULL;
 			return DIAG_DCI_SEND_DATA_FAIL;
 		}
 		err = diag_process_dci_transaction(user_space_data,
 							payload_size);
 		diagmem_free(driver, user_space_data, POOL_TYPE_USER);
+		user_space_data = NULL;
 		return err;
 	}
 	if (pkt_type == CALLBACK_DATA_TYPE) {
@@ -1542,16 +1546,19 @@
 			return -EBADMSG;
 		}
 
+		mutex_lock(&driver->diagchar_mutex);
 		buf_copy = diagmem_alloc(driver, payload_size, POOL_TYPE_COPY);
 		if (!buf_copy) {
 			driver->dropped_count++;
+			mutex_unlock(&driver->diagchar_mutex);
 			return -ENOMEM;
 		}
 
 		err = copy_from_user(buf_copy, buf + 4, payload_size);
 		if (err) {
 			pr_err("diag: copy failed for user space data\n");
-			return -EIO;
+			ret = -EIO;
+			goto fail_free_copy;
 		}
 		/* Check for proc_type */
 		remote_proc = diag_get_remote(*(int *)buf_copy);
@@ -1560,8 +1567,7 @@
 			wait_event_interruptible(driver->wait_q,
 				 (driver->in_busy_pktdata == 0));
 			ret = diag_process_apps_pkt(buf_copy, payload_size);
-			diagmem_free(driver, buf_copy, POOL_TYPE_COPY);
-			return ret;
+			goto fail_free_copy;
 		}
 		/* The packet is for the remote processor */
 		token_offset = 4;
@@ -1574,20 +1580,20 @@
 							1 + payload_size);
 		send.terminate = 1;
 
-		mutex_lock(&driver->diagchar_mutex);
+
 		if (!buf_hdlc)
 			buf_hdlc = diagmem_alloc(driver, HDLC_OUT_BUF_SIZE,
 							POOL_TYPE_HDLC);
 		if (!buf_hdlc) {
 			ret = -ENOMEM;
-			goto fail_free_hdlc;
+			driver->used = 0;
+			goto fail_free_copy;
 		}
 		if (HDLC_OUT_BUF_SIZE < (2 * payload_size) + 3) {
 			pr_err("diag: Dropping packet, HDLC encoded packet payload size crosses buffer limit. Current payload size %d\n",
 					((2*payload_size) + 3));
 			driver->dropped_count++;
 			ret = -EBADMSG;
-			diagmem_free(driver, buf_hdlc, POOL_TYPE_HDLC);
 			goto fail_free_hdlc;
 		}
 		enc.dest = buf_hdlc + driver->used;
@@ -1652,13 +1658,7 @@
 			}
 		}
 #endif
-		diagmem_free(driver, buf_copy, POOL_TYPE_COPY);
-		diagmem_free(driver, buf_hdlc, POOL_TYPE_HDLC);
-		buf_copy = NULL;
-		buf_hdlc = NULL;
-		driver->used = 0;
-		mutex_unlock(&driver->diagchar_mutex);
-		return ret;
+		goto fail_free_hdlc;
 	}
 	if (pkt_type == USER_SPACE_DATA_TYPE) {
 		user_space_data = diagmem_alloc(driver, payload_size,
@@ -1672,6 +1672,7 @@
 		if (err) {
 			pr_err("diag: copy failed for user space data\n");
 			diagmem_free(driver, user_space_data, POOL_TYPE_USER);
+			user_space_data = NULL;
 			return -EIO;
 		}
 		/* Check for proc_type */
@@ -1690,6 +1691,7 @@
 				pr_alert("diag: mask request Invalid\n");
 				diagmem_free(driver, user_space_data,
 							POOL_TYPE_USER);
+				user_space_data = NULL;
 				return -EFAULT;
 			}
 		}
@@ -1767,6 +1769,7 @@
 							err);
 					diagmem_free(driver, user_space_data,
 								POOL_TYPE_USER);
+					user_space_data = NULL;
 					return err;
 				}
 			}
@@ -1777,6 +1780,7 @@
 			diag_process_hdlc((void *)
 				(user_space_data + token_offset), payload_size);
 		diagmem_free(driver, user_space_data, POOL_TYPE_USER);
+		user_space_data = NULL;
 		return 0;
 	}
 
@@ -1788,9 +1792,11 @@
 		return -EBADMSG;
 	}
 
+	mutex_lock(&driver->diagchar_mutex);
 	buf_copy = diagmem_alloc(driver, payload_size, POOL_TYPE_COPY);
 	if (!buf_copy) {
 		driver->dropped_count++;
+		mutex_unlock(&driver->diagchar_mutex);
 		return -ENOMEM;
 	}
 
@@ -1834,13 +1840,13 @@
 			length++;
 	}
 #endif
-	mutex_lock(&driver->diagchar_mutex);
 	if (!buf_hdlc)
 		buf_hdlc = diagmem_alloc(driver, HDLC_OUT_BUF_SIZE,
 						 POOL_TYPE_HDLC);
 	if (!buf_hdlc) {
 		ret = -ENOMEM;
-		goto fail_free_hdlc;
+		driver->used = 0;
+		goto fail_free_copy;
 	}
 	if (HDLC_OUT_BUF_SIZE < (2*payload_size) + 3) {
 		pr_err("diag: Dropping packet, HDLC encoded packet payload size crosses buffer limit. Current payload size %d\n",
@@ -1853,7 +1859,6 @@
 		err = diag_device_write(buf_hdlc, APPS_DATA, NULL);
 		if (err) {
 			/*Free the buffer right away if write failed */
-			diagmem_free(driver, buf_hdlc, POOL_TYPE_HDLC);
 			if (driver->logging_mode == USB_MODE)
 				diagmem_free(driver, (unsigned char *)driver->
 					write_ptr_svc, POOL_TYPE_WRITE_STRUCT);
@@ -1866,7 +1871,7 @@
 							 POOL_TYPE_HDLC);
 		if (!buf_hdlc) {
 			ret = -ENOMEM;
-			goto fail_free_hdlc;
+			goto fail_free_copy;
 		}
 	}
 
@@ -1882,7 +1887,6 @@
 		err = diag_device_write(buf_hdlc, APPS_DATA, NULL);
 		if (err) {
 			/*Free the buffer right away if write failed */
-			diagmem_free(driver, buf_hdlc, POOL_TYPE_HDLC);
 			if (driver->logging_mode == USB_MODE)
 				diagmem_free(driver, (unsigned char *)driver->
 					write_ptr_svc, POOL_TYPE_WRITE_STRUCT);
@@ -1895,7 +1899,7 @@
 							 POOL_TYPE_HDLC);
 		if (!buf_hdlc) {
 			ret = -ENOMEM;
-			goto fail_free_hdlc;
+			goto fail_free_copy;
 		}
 		enc.dest = buf_hdlc + driver->used;
 		enc.dest_last = (void *)(buf_hdlc + driver->used +
@@ -1908,7 +1912,6 @@
 		err = diag_device_write(buf_hdlc, APPS_DATA, NULL);
 		if (err) {
 			/*Free the buffer right away if write failed */
-			diagmem_free(driver, buf_hdlc, POOL_TYPE_HDLC);
 			if (driver->logging_mode == USB_MODE)
 				diagmem_free(driver, (unsigned char *)driver->
 					write_ptr_svc, POOL_TYPE_WRITE_STRUCT);
@@ -1920,6 +1923,7 @@
 	}
 
 	diagmem_free(driver, buf_copy, POOL_TYPE_COPY);
+	buf_copy = NULL;
 	mutex_unlock(&driver->diagchar_mutex);
 	if (!timer_in_progress)	{
 		timer_in_progress = 1;
@@ -1928,14 +1932,18 @@
 	return 0;
 
 fail_free_hdlc:
+	diagmem_free(driver, buf_hdlc, POOL_TYPE_HDLC);
 	buf_hdlc = NULL;
 	driver->used = 0;
 	diagmem_free(driver, buf_copy, POOL_TYPE_COPY);
+	buf_copy = NULL;
 	mutex_unlock(&driver->diagchar_mutex);
 	return ret;
 
 fail_free_copy:
 	diagmem_free(driver, buf_copy, POOL_TYPE_COPY);
+	buf_copy = NULL;
+	mutex_unlock(&driver->diagchar_mutex);
 	return ret;
 }
 
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index afb11c2..e316742 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1775,12 +1775,17 @@
 	int status = -EINVAL;
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	unsigned int state = device->state;
+	unsigned int regulator_left_on = 0;
 
 	kgsl_cffdump_open(device);
 
 	if (KGSL_STATE_DUMP_AND_FT != device->state)
 		kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
 
+	regulator_left_on = (regulator_is_enabled(device->pwrctrl.gpu_reg) ||
+				(device->pwrctrl.gpu_cx &&
+				regulator_is_enabled(device->pwrctrl.gpu_cx)));
+
 	/* Power up the device */
 	kgsl_pwrctrl_enable(device);
 
@@ -1808,6 +1813,14 @@
 		goto error_mmu_off;
 	}
 
+	if (regulator_left_on && adreno_dev->gpudev->soft_reset) {
+		/*
+		 * Reset the GPU for A3xx. A2xx does a soft reset in
+		 * the start function.
+		 */
+		adreno_dev->gpudev->soft_reset(adreno_dev);
+	}
+
 	/* Start the GPU */
 	adreno_dev->gpudev->start(adreno_dev);
 
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index ace6121..7af4575 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -38,6 +38,7 @@
 
 static struct kgsl_iommu_register_list kgsl_iommuv0_reg[KGSL_IOMMU_REG_MAX] = {
 	{ 0, 0 },			/* GLOBAL_BASE */
+	{ 0x0, 1 },			/* SCTLR */
 	{ 0x10, 1 },			/* TTBR0 */
 	{ 0x14, 1 },			/* TTBR1 */
 	{ 0x20, 1 },			/* FSR */
@@ -54,6 +55,7 @@
 
 static struct kgsl_iommu_register_list kgsl_iommuv1_reg[KGSL_IOMMU_REG_MAX] = {
 	{ 0, 0 },			/* GLOBAL_BASE */
+	{ 0x0, 1 },			/* SCTLR */
 	{ 0x20, 1 },			/* TTBR0 */
 	{ 0x28, 1 },			/* TTBR1 */
 	{ 0x58, 1 },			/* FSR */
@@ -1581,6 +1583,8 @@
 	int status;
 	struct kgsl_iommu *iommu = mmu->priv;
 	int i, j;
+	int sctlr_val = 0;
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(mmu->device);
 
 	if (mmu->flags & KGSL_FLAGS_STARTED)
 		return 0;
@@ -1632,6 +1636,25 @@
 	for (i = 0; i < iommu->unit_count; i++) {
 		struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
 		for (j = 0; j < iommu_unit->dev_count; j++) {
+
+			/*
+			 * For IOMMU V1 do not halt IOMMU on pagefault if
+			 * FT pagefault policy is set accordingly
+			 */
+			if ((!msm_soc_version_supports_iommu_v0()) &&
+				(!(adreno_dev->ft_pf_policy &
+				   KGSL_FT_PAGEFAULT_GPUHALT_ENABLE))) {
+				sctlr_val = KGSL_IOMMU_GET_CTX_REG(iommu,
+						iommu_unit,
+						iommu_unit->dev[j].ctx_id,
+						SCTLR);
+				sctlr_val |= (0x1 <<
+						KGSL_IOMMU_SCTLR_HUPCF_SHIFT);
+				KGSL_IOMMU_SET_CTX_REG(iommu,
+						iommu_unit,
+						iommu_unit->dev[j].ctx_id,
+						SCTLR, sctlr_val);
+			}
 			if (sizeof(phys_addr_t) > sizeof(unsigned long)) {
 				iommu_unit->dev[j].default_ttbr0 =
 						KGSL_IOMMU_GET_CTX_REG_LL(iommu,
diff --git a/drivers/gpu/msm/kgsl_iommu.h b/drivers/gpu/msm/kgsl_iommu.h
index 5c4b17e..7dca40e 100644
--- a/drivers/gpu/msm/kgsl_iommu.h
+++ b/drivers/gpu/msm/kgsl_iommu.h
@@ -61,8 +61,12 @@
 #define KGSL_IOMMU_IMPLDEF_MICRO_MMU_CTRL_HALT BIT(2)
 #define KGSL_IOMMU_IMPLDEF_MICRO_MMU_CTRL_IDLE BIT(3)
 
+/* SCTLR fields */
+#define KGSL_IOMMU_SCTLR_HUPCF_SHIFT		8
+
 enum kgsl_iommu_reg_map {
 	KGSL_IOMMU_GLOBAL_BASE = 0,
+	KGSL_IOMMU_CTX_SCTLR,
 	KGSL_IOMMU_CTX_TTBR0,
 	KGSL_IOMMU_CTX_TTBR1,
 	KGSL_IOMMU_CTX_FSR,
diff --git a/drivers/hwmon/qpnp-adc-current.c b/drivers/hwmon/qpnp-adc-current.c
index 9570327..27818b4 100644
--- a/drivers/hwmon/qpnp-adc-current.c
+++ b/drivers/hwmon/qpnp-adc-current.c
@@ -530,6 +530,9 @@
 	uint16_t raw_data;
 	uint32_t mode_sel = 0;
 
+	if (!iadc || !iadc->iadc_initialized)
+		return -EPROBE_DEFER;
+
 	mutex_lock(&iadc->adc->adc_lock);
 
 	rc = qpnp_iadc_configure(GAIN_CALIBRATION_17P857MV,
@@ -541,11 +544,22 @@
 
 	iadc->adc->calib.gain_raw = raw_data;
 
-	rc = qpnp_iadc_configure(OFFSET_CALIBRATION_CSP2_CSN2,
+	if (iadc->external_rsense) {
+		/* external offset calculation */
+		rc = qpnp_iadc_configure(OFFSET_CALIBRATION_CSP_CSN,
 						&raw_data, mode_sel);
-	if (rc < 0) {
-		pr_err("qpnp adc result read failed with %d\n", rc);
-		goto fail;
+		if (rc < 0) {
+			pr_err("qpnp adc result read failed with %d\n", rc);
+			goto fail;
+		}
+	} else {
+		/* internal offset calculation */
+		rc = qpnp_iadc_configure(OFFSET_CALIBRATION_CSP2_CSN2,
+						&raw_data, mode_sel);
+		if (rc < 0) {
+			pr_err("qpnp adc result read failed with %d\n", rc);
+			goto fail;
+		}
 	}
 
 	iadc->adc->calib.offset_raw = raw_data;
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 1464dab..a052bd3 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -654,4 +654,42 @@
           If you say yes here you get support for STMicroelectronics's
           acceleration sensors LIS3DH.
 
+config BMP18X
+       tristate "BMP18X digital pressure sensor"
+       depends on (I2C ) && SYSFS
+       help
+         If you say yes here you get support for Bosch Sensortec
+	 digital pressure sensors BMP085, BMP180.
+
+         To compile this driver as a module, choose M here: the
+         module will be called bmp18x-core.
+
+config BMP18X_I2C
+       tristate "support I2C bus connection"
+       depends on BMP18X && I2C
+       help
+         Say Y here if you want to support Bosch Sensortec digital pressure
+         sensor hooked to an I2C bus.
+
+         To compile this driver as a module, choose M here: the
+         module will be called bmp18x-i2c.
+
+config SENSORS_MMA8X5X
+	tristate "MMA8451/MMA8452/MMA8453/MMA8652/MMA8653 device driver"
+	depends on I2C && SYSFS
+	select INPUT_POLLDEV
+	default n
+	help
+	  If you say yes here you get support for the Freescale MMA8451/
+	  MMA8452/MMA8453/MMA8652/MMA8653  sensors.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called mma8x5x.
+
+config SENSORS_MMA_POSITION
+	int "MMA8x5x Accelerate Sensor Position Setting"
+	depends on SENSORS_MMA8X5X
+	default "0"
+	help
+	  this provide the sensor position setting , value is between 0~7
 endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 96c9288..4f29e05 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -61,3 +61,6 @@
 obj-$(CONFIG_INPUT_PMIC8058_VIBRA_MEMLESS) += pmic8058-vib-memless.o
 obj-$(CONFIG_BOSCH_BMA150)              += bma150.o
 obj-$(CONFIG_STM_LIS3DH)		+= lis3dh_acc.o
+obj-$(CONFIG_BMP18X)			+= bmp18x-core.o
+obj-$(CONFIG_BMP18X_I2C)		+= bmp18x-i2c.o
+obj-$(CONFIG_SENSORS_MMA8X5X)	  	+= mma8x5x.o
diff --git a/drivers/input/misc/bmp18x-core.c b/drivers/input/misc/bmp18x-core.c
new file mode 100644
index 0000000..bac9059
--- /dev/null
+++ b/drivers/input/misc/bmp18x-core.c
@@ -0,0 +1,705 @@
+/*  Copyright (c) 2011  Bosch Sensortec GmbH
+    Copyright (c) 2011  Unixphere
+
+    Based on:
+    BMP085 driver, bmp085.c
+    Copyright (c) 2010  Christoph Mair <christoph.mair@gmail.com>
+
+    This driver supports the bmp18x digital barometric pressure
+    and temperature sensors from Bosch Sensortec.
+
+    A pressure measurement is issued by reading from pressure0_input.
+    The return value ranges from 30000 to 110000 pascal with a resulution
+    of 1 pascal (0.01 millibar) which enables measurements from 9000m above
+    to 500m below sea level.
+
+    The temperature can be read from temp0_input. Values range from
+    -400 to 850 representing the ambient temperature in degree celsius
+    multiplied by 10.The resolution is 0.1 celsius.
+
+    Because ambient pressure is temperature dependent, a temperature
+    measurement will be executed automatically even if the user is reading
+    from pressure0_input. This happens if the last temperature measurement
+    has been executed more then one second ago.
+
+    To decrease RMS noise from pressure measurements, the bmp18x can
+    autonomously calculate the average of up to eight samples. This is
+    set up by writing to the oversampling sysfs file. Accepted values
+    are 0, 1, 2 and 3. 2^x when x is the value written to this file
+    specifies the number of samples used to calculate the ambient pressure.
+    RMS noise is specified with six pascal (without averaging) and decreases
+    down to 3 pascal when using an oversampling setting of 3.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/module.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include "bmp18x.h"
+
+#define BMP18X_CHIP_ID			0x55
+
+#define BMP18X_CALIBRATION_DATA_START	0xAA
+#define BMP18X_CALIBRATION_DATA_LENGTH	11	/* 16 bit values */
+#define BMP18X_CHIP_ID_REG		0xD0
+#define BMP18X_CTRL_REG			0xF4
+#define BMP18X_TEMP_MEASUREMENT		0x2E
+#define BMP18X_PRESSURE_MEASUREMENT	0x34
+#define BMP18X_CONVERSION_REGISTER_MSB	0xF6
+#define BMP18X_CONVERSION_REGISTER_LSB	0xF7
+#define BMP18X_CONVERSION_REGISTER_XLSB	0xF8
+#define BMP18X_TEMP_CONVERSION_TIME	5
+
+#define ABS_MIN_PRESSURE	30000
+#define ABS_MAX_PRESSURE	120000
+#define BMP_DELAY_DEFAULT   200
+
+struct bmp18x_calibration_data {
+	s16 AC1, AC2, AC3;
+	u16 AC4, AC5, AC6;
+	s16 B1, B2;
+	s16 MB, MC, MD;
+};
+
+/* Each client has this additional data */
+struct bmp18x_data {
+	struct	bmp18x_data_bus data_bus;
+	struct	device *dev;
+	struct	mutex lock;
+	struct	bmp18x_calibration_data calibration;
+	u8	oversampling_setting;
+	u8	sw_oversampling_setting;
+	u32	raw_temperature;
+	u32	raw_pressure;
+	u32	temp_measurement_period;
+	u32	last_temp_measurement;
+	s32	b6; /* calculated temperature correction coefficient */
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	struct early_suspend early_suspend;
+#endif
+	struct input_dev	*input;
+	struct delayed_work work;
+	u32					delay;
+	u32					enable;
+};
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void bmp18x_early_suspend(struct early_suspend *h);
+static void bmp18x_late_resume(struct early_suspend *h);
+#endif
+
+static s32 bmp18x_read_calibration_data(struct bmp18x_data *data)
+{
+	u16 tmp[BMP18X_CALIBRATION_DATA_LENGTH];
+	struct bmp18x_calibration_data *cali = &(data->calibration);
+	s32 status = data->data_bus.bops->read_block(data->data_bus.client,
+				BMP18X_CALIBRATION_DATA_START,
+				BMP18X_CALIBRATION_DATA_LENGTH*sizeof(u16),
+				(u8 *)tmp);
+	if (status < 0)
+		return status;
+
+	if (status != BMP18X_CALIBRATION_DATA_LENGTH*sizeof(u16))
+		return -EIO;
+
+	cali->AC1 =  be16_to_cpu(tmp[0]);
+	cali->AC2 =  be16_to_cpu(tmp[1]);
+	cali->AC3 =  be16_to_cpu(tmp[2]);
+	cali->AC4 =  be16_to_cpu(tmp[3]);
+	cali->AC5 =  be16_to_cpu(tmp[4]);
+	cali->AC6 = be16_to_cpu(tmp[5]);
+	cali->B1 = be16_to_cpu(tmp[6]);
+	cali->B2 = be16_to_cpu(tmp[7]);
+	cali->MB = be16_to_cpu(tmp[8]);
+	cali->MC = be16_to_cpu(tmp[9]);
+	cali->MD = be16_to_cpu(tmp[10]);
+	return 0;
+}
+
+
+static s32 bmp18x_update_raw_temperature(struct bmp18x_data *data)
+{
+	u16 tmp;
+	s32 status;
+
+	mutex_lock(&data->lock);
+	status = data->data_bus.bops->write_byte(data->data_bus.client,
+				BMP18X_CTRL_REG, BMP18X_TEMP_MEASUREMENT);
+	if (status != 0) {
+		dev_err(data->dev,
+			"Error while requesting temperature measurement.\n");
+		goto exit;
+	}
+	msleep(BMP18X_TEMP_CONVERSION_TIME);
+
+	status = data->data_bus.bops->read_block(data->data_bus.client,
+		BMP18X_CONVERSION_REGISTER_MSB, sizeof(tmp), (u8 *)&tmp);
+	if (status < 0)
+		goto exit;
+	if (status != sizeof(tmp)) {
+		dev_err(data->dev,
+			"Error while reading temperature measurement result\n");
+		status = -EIO;
+		goto exit;
+	}
+	data->raw_temperature = be16_to_cpu(tmp);
+	data->last_temp_measurement = jiffies;
+	status = 0;	/* everything ok, return 0 */
+
+exit:
+	mutex_unlock(&data->lock);
+	return status;
+}
+
+static s32 bmp18x_update_raw_pressure(struct bmp18x_data *data)
+{
+	u32 tmp = 0;
+	s32 status;
+
+	mutex_lock(&data->lock);
+	status = data->data_bus.bops->write_byte(data->data_bus.client,
+		BMP18X_CTRL_REG, BMP18X_PRESSURE_MEASUREMENT +
+		(data->oversampling_setting<<6));
+	if (status != 0) {
+		dev_err(data->dev,
+			"Error while requesting pressure measurement.\n");
+		goto exit;
+	}
+
+	/* wait for the end of conversion */
+	msleep(2+(3 << data->oversampling_setting));
+
+	/* copy data into a u32 (4 bytes), but skip the first byte. */
+	status = data->data_bus.bops->read_block(data->data_bus.client,
+			BMP18X_CONVERSION_REGISTER_MSB, 3, ((u8 *)&tmp)+1);
+	if (status < 0)
+		goto exit;
+	if (status != 3) {
+		dev_err(data->dev,
+			"Error while reading pressure measurement results\n");
+		status = -EIO;
+		goto exit;
+	}
+	data->raw_pressure = be32_to_cpu((tmp));
+	data->raw_pressure >>= (8-data->oversampling_setting);
+	status = 0;	/* everything ok, return 0 */
+
+exit:
+	mutex_unlock(&data->lock);
+	return status;
+}
+
+
+/*
+ * This function starts the temperature measurement and returns the value
+ * in tenth of a degree celsius.
+ */
+static s32 bmp18x_get_temperature(struct bmp18x_data *data, int *temperature)
+{
+	struct bmp18x_calibration_data *cali = &data->calibration;
+	long x1, x2;
+	int status;
+
+	status = bmp18x_update_raw_temperature(data);
+	if (status != 0)
+		goto exit;
+
+	x1 = ((data->raw_temperature - cali->AC6) * cali->AC5) >> 15;
+	x2 = (cali->MC << 11) / (x1 + cali->MD);
+	data->b6 = x1 + x2 - 4000;
+	/* if NULL just update b6. Used for pressure only measurements */
+	if (temperature != NULL)
+		*temperature = (x1+x2+8) >> 4;
+
+exit:
+	return status;
+}
+
+/*
+ * This function starts the pressure measurement and returns the value
+ * in millibar. Since the pressure depends on the ambient temperature,
+ * a temperature measurement is executed according to the given temperature
+ * measurememt period (default is 1 sec boundary). This period could vary
+ * and needs to be adjusted accoring to the sensor environment, i.e. if big
+ * temperature variations then the temperature needs to be read out often.
+ */
+static s32 bmp18x_get_pressure(struct bmp18x_data *data, int *pressure)
+{
+	struct bmp18x_calibration_data *cali = &data->calibration;
+	s32 x1, x2, x3, b3;
+	u32 b4, b7;
+	s32 p;
+	int status;
+	int i_loop, i;
+	u32 p_tmp;
+
+	/* update the ambient temperature according to the given meas. period */
+	if (data->last_temp_measurement +
+			data->temp_measurement_period < jiffies) {
+		status = bmp18x_get_temperature(data, NULL);
+		if (status != 0)
+			goto exit;
+	}
+
+	if ((data->oversampling_setting == 3)
+		&& (data->sw_oversampling_setting == 1)) {
+		i_loop = 3;
+	} else {
+		i_loop = 1;
+	}
+
+	p_tmp = 0;
+	for (i = 0; i < i_loop; i++) {
+		status = bmp18x_update_raw_pressure(data);
+		if (status != 0)
+			goto exit;
+		p_tmp += data->raw_pressure;
+	}
+
+	data->raw_pressure = (p_tmp + (i_loop >> 1)) / i_loop;
+
+	x1 = (data->b6 * data->b6) >> 12;
+	x1 *= cali->B2;
+	x1 >>= 11;
+
+	x2 = cali->AC2 * data->b6;
+	x2 >>= 11;
+
+	x3 = x1 + x2;
+
+	b3 = (((((s32)cali->AC1) * 4 + x3) << data->oversampling_setting) + 2);
+	b3 >>= 2;
+
+	x1 = (cali->AC3 * data->b6) >> 13;
+	x2 = (cali->B1 * ((data->b6 * data->b6) >> 12)) >> 16;
+	x3 = (x1 + x2 + 2) >> 2;
+	b4 = (cali->AC4 * (u32)(x3 + 32768)) >> 15;
+
+	b7 = ((u32)data->raw_pressure - b3) *
+					(50000 >> data->oversampling_setting);
+	p = ((b7 < 0x80000000) ? ((b7 << 1) / b4) : ((b7 / b4) * 2));
+
+	x1 = p >> 8;
+	x1 *= x1;
+	x1 = (x1 * 3038) >> 16;
+	x2 = (-7357 * p) >> 16;
+	p += (x1 + x2 + 3791) >> 4;
+
+	*pressure = p;
+
+exit:
+	return status;
+}
+
+/*
+ * This function sets the chip-internal oversampling. Valid values are 0..3.
+ * The chip will use 2^oversampling samples for internal averaging.
+ * This influences the measurement time and the accuracy; larger values
+ * increase both. The datasheet gives on overview on how measurement time,
+ * accuracy and noise correlate.
+ */
+static void bmp18x_set_oversampling(struct bmp18x_data *data,
+						unsigned char oversampling)
+{
+	if (oversampling > 3)
+		oversampling = 3;
+	data->oversampling_setting = oversampling;
+}
+
+/*
+ * Returns the currently selected oversampling. Range: 0..3
+ */
+static unsigned char bmp18x_get_oversampling(struct bmp18x_data *data)
+{
+	return data->oversampling_setting;
+}
+
+/* sysfs callbacks */
+static ssize_t set_oversampling(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+	unsigned long oversampling;
+	int success = kstrtoul(buf, 10, &oversampling);
+	if (success == 0) {
+		mutex_lock(&data->lock);
+		bmp18x_set_oversampling(data, oversampling);
+		if (oversampling != 3)
+			data->sw_oversampling_setting = 0;
+		mutex_unlock(&data->lock);
+		return count;
+	}
+	return success;
+}
+
+static ssize_t show_oversampling(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+	return snprintf(buf, PAGE_SIZE,
+		"%u\n", bmp18x_get_oversampling(data));
+}
+static DEVICE_ATTR(oversampling, S_IWUSR | S_IRUGO,
+					show_oversampling, set_oversampling);
+
+static ssize_t set_sw_oversampling(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+	unsigned long sw_oversampling;
+	int success = kstrtoul(buf, 10, &sw_oversampling);
+	if (success == 0) {
+		mutex_lock(&data->lock);
+		data->sw_oversampling_setting = sw_oversampling ? 1 : 0;
+		mutex_unlock(&data->lock);
+	}
+	return success;
+}
+
+static ssize_t show_sw_oversampling(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+	return snprintf(buf, PAGE_SIZE,
+		"%u\n", data->sw_oversampling_setting);
+}
+static DEVICE_ATTR(sw_oversampling, S_IWUSR | S_IRUGO,
+				show_sw_oversampling, set_sw_oversampling);
+
+static ssize_t show_delay(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+	return snprintf(buf, PAGE_SIZE, "%u\n", data->delay);
+}
+
+static ssize_t set_delay(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+	unsigned long delay;
+	int success = kstrtoul(buf, 10, &delay);
+	if (success == 0) {
+		mutex_lock(&data->lock);
+		data->delay = delay;
+		mutex_unlock(&data->lock);
+	}
+	return success;
+}
+static DEVICE_ATTR(delay, S_IWUSR | S_IRUGO,
+				show_delay, set_delay);
+
+static ssize_t show_enable(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+	return snprintf(buf, PAGE_SIZE, "%u\n", data->enable);
+}
+
+static ssize_t set_enable(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+	unsigned long enable;
+	int success = kstrtoul(buf, 10, &enable);
+	if (success == 0) {
+		mutex_lock(&data->lock);
+		data->enable = enable ? 1 : 0;
+
+		if (data->enable) {
+			bmp18x_enable(dev);
+			schedule_delayed_work(&data->work,
+						msecs_to_jiffies(data->delay));
+		} else {
+			cancel_delayed_work_sync(&data->work);
+			bmp18x_disable(dev);
+		}
+		mutex_unlock(&data->lock);
+
+	}
+	return success;
+}
+static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
+				show_enable, set_enable);
+
+static ssize_t show_temperature(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	int temperature;
+	int status;
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+
+	status = bmp18x_get_temperature(data, &temperature);
+	if (status != 0)
+		return status;
+	else
+		return snprintf(buf, PAGE_SIZE,
+			"%d\n", temperature);
+}
+static DEVICE_ATTR(temp0_input, S_IRUGO, show_temperature, NULL);
+
+
+static ssize_t show_pressure(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	int pressure;
+	int status;
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+
+	status = bmp18x_get_pressure(data, &pressure);
+	if (status != 0)
+		return status;
+	else
+		return snprintf(buf, PAGE_SIZE, "%d\n", pressure);
+}
+static DEVICE_ATTR(pressure0_input, S_IRUGO, show_pressure, NULL);
+
+
+static struct attribute *bmp18x_attributes[] = {
+	&dev_attr_temp0_input.attr,
+	&dev_attr_pressure0_input.attr,
+	&dev_attr_oversampling.attr,
+	&dev_attr_sw_oversampling.attr,
+	&dev_attr_delay.attr,
+	&dev_attr_enable.attr,
+	NULL
+};
+
+static const struct attribute_group bmp18x_attr_group = {
+	.attrs = bmp18x_attributes,
+};
+
+static void bmp18x_work_func(struct work_struct *work)
+{
+	struct bmp18x_data *client_data =
+		container_of((struct delayed_work *)work,
+		struct bmp18x_data, work);
+	unsigned long delay = msecs_to_jiffies(client_data->delay);
+	unsigned long j1 = jiffies;
+	int pressure;
+	int status;
+
+	status = bmp18x_get_pressure(client_data, &pressure);
+
+	if (status == 0) {
+		input_report_abs(client_data->input, ABS_PRESSURE, pressure);
+		input_sync(client_data->input);
+	}
+
+	schedule_delayed_work(&client_data->work, delay-(jiffies-j1));
+}
+
+static int bmp18x_input_init(struct bmp18x_data *data)
+{
+	struct input_dev *dev;
+	int err;
+
+	dev = input_allocate_device();
+	if (!dev)
+		return -ENOMEM;
+	dev->name = BMP18X_NAME;
+	dev->id.bustype = BUS_I2C;
+
+	input_set_capability(dev, EV_ABS, ABS_MISC);
+	input_set_abs_params(dev, ABS_PRESSURE,
+		ABS_MIN_PRESSURE, ABS_MAX_PRESSURE, 0, 0);
+	input_set_drvdata(dev, data);
+
+	err = input_register_device(dev);
+	if (err < 0) {
+		input_free_device(dev);
+		return err;
+	}
+	data->input = dev;
+
+	return 0;
+}
+
+static void bmp18x_input_delete(struct bmp18x_data *data)
+{
+	struct input_dev *dev = data->input;
+
+	input_unregister_device(dev);
+	input_free_device(dev);
+}
+
+static int bmp18x_init_client(struct bmp18x_data *data,
+			      struct bmp18x_platform_data *pdata)
+{
+	int status = bmp18x_read_calibration_data(data);
+	if (status != 0)
+		goto exit;
+	data->last_temp_measurement = 0;
+	data->temp_measurement_period =
+		pdata ? (pdata->temp_measurement_period/1000)*HZ : 1*HZ;
+	data->oversampling_setting = pdata ? pdata->default_oversampling : 3;
+	if (data->oversampling_setting == 3)
+		data->sw_oversampling_setting
+			= pdata ? pdata->default_sw_oversampling : 0;
+	mutex_init(&data->lock);
+exit:
+	return status;
+}
+
+__devinit int bmp18x_probe(struct device *dev, struct bmp18x_data_bus *data_bus)
+{
+	struct bmp18x_data *data;
+	struct bmp18x_platform_data *pdata = dev->platform_data;
+	u8 chip_id = pdata && pdata->chip_id ? pdata->chip_id : BMP18X_CHIP_ID;
+	int err = 0;
+
+	if (pdata && pdata->init_hw) {
+		err = pdata->init_hw();
+		if (err) {
+			printk(KERN_ERR "%s: init_hw failed!\n",
+				BMP18X_NAME);
+			goto exit;
+		}
+	}
+
+	if (data_bus->bops->read_byte(data_bus->client,
+			BMP18X_CHIP_ID_REG) != chip_id) {
+		printk(KERN_ERR "%s: chip_id failed!\n", BMP18X_NAME);
+		err = -ENODEV;
+		goto exit;
+	}
+
+	data = kzalloc(sizeof(struct bmp18x_data), GFP_KERNEL);
+	if (!data) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	dev_set_drvdata(dev, data);
+	data->data_bus = *data_bus;
+	data->dev = dev;
+
+	/* Initialize the BMP18X chip */
+	err = bmp18x_init_client(data, pdata);
+	if (err != 0)
+		goto exit_free;
+
+	/* Initialize the BMP18X input device */
+	err = bmp18x_input_init(data);
+	if (err != 0)
+		goto exit_free;
+
+	/* Register sysfs hooks */
+	err = sysfs_create_group(&data->input->dev.kobj, &bmp18x_attr_group);
+	if (err)
+		goto error_sysfs;
+	/* workqueue init */
+	INIT_DELAYED_WORK(&data->work, bmp18x_work_func);
+	data->delay  = BMP_DELAY_DEFAULT;
+	data->enable = 0;
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+	data->early_suspend.suspend = bmp18x_early_suspend;
+	data->early_suspend.resume = bmp18x_late_resume;
+	register_early_suspend(&data->early_suspend);
+#endif
+
+	dev_info(dev, "Succesfully initialized bmp18x!\n");
+	return 0;
+
+error_sysfs:
+	bmp18x_input_delete(data);
+exit_free:
+	kfree(data);
+exit:
+	if (pdata && pdata->deinit_hw)
+		pdata->deinit_hw();
+	return err;
+}
+EXPORT_SYMBOL(bmp18x_probe);
+
+int bmp18x_remove(struct device *dev)
+{
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	unregister_early_suspend(&data->early_suspend);
+#endif
+	sysfs_remove_group(&data->input->dev.kobj, &bmp18x_attr_group);
+	kfree(data);
+
+	return 0;
+}
+EXPORT_SYMBOL(bmp18x_remove);
+
+#ifdef CONFIG_PM
+int bmp18x_disable(struct device *dev)
+{
+	struct bmp18x_platform_data *pdata = dev->platform_data;
+
+	if (pdata && pdata->deinit_hw)
+		pdata->deinit_hw();
+
+	return 0;
+}
+EXPORT_SYMBOL(bmp18x_disable);
+
+int bmp18x_enable(struct device *dev)
+{
+	struct bmp18x_platform_data *pdata = dev->platform_data;
+
+	if (pdata && pdata->init_hw)
+		return pdata->init_hw();
+
+	return 0;
+}
+EXPORT_SYMBOL(bmp18x_enable);
+#endif
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void bmp18x_early_suspend(struct early_suspend *h)
+{
+	struct bmp18x_data *data =
+		container_of(h, struct bmp18x_data, early_suspend);
+	if (data->enable) {
+		cancel_delayed_work_sync(&data->work);
+		(void) bmp18x_disable(data->dev);
+	}
+}
+
+static void bmp18x_late_resume(struct early_suspend *h)
+{
+	struct bmp18x_data *data =
+		container_of(h, struct bmp18x_data, early_suspend);
+
+	if (data->enable) {
+		(void) bmp18x_enable(data->dev);
+		schedule_delayed_work(&data->work,
+					msecs_to_jiffies(data->delay));
+	}
+
+}
+#endif
+
+MODULE_AUTHOR("Eric Andersson <eric.andersson@unixphere.com>");
+MODULE_DESCRIPTION("BMP18X driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/bmp18x-i2c.c b/drivers/input/misc/bmp18x-i2c.c
new file mode 100644
index 0000000..6c01ad3
--- /dev/null
+++ b/drivers/input/misc/bmp18x-i2c.c
@@ -0,0 +1,122 @@
+/*  Copyright (c) 2011  Bosch Sensortec GmbH
+    Copyright (c) 2011  Unixphere
+
+    Based on:
+    BMP085 driver, bmp085.c
+    Copyright (c) 2010  Christoph Mair <christoph.mair@gmail.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include "bmp18x.h"
+
+static int bmp18x_i2c_read_block(void *client, u8 reg, int len, char *buf)
+{
+	return i2c_smbus_read_i2c_block_data(client, reg, len, buf);
+}
+
+static int bmp18x_i2c_read_byte(void *client, u8 reg)
+{
+	return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int bmp18x_i2c_write_byte(void *client, u8 reg, u8 value)
+{
+	return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static const struct bmp18x_bus_ops bmp18x_i2c_bus_ops = {
+	.read_block	= bmp18x_i2c_read_block,
+	.read_byte	= bmp18x_i2c_read_byte,
+	.write_byte	= bmp18x_i2c_write_byte
+};
+
+static int __devinit bmp18x_i2c_probe(struct i2c_client *client,
+				      const struct i2c_device_id *id)
+{
+	struct bmp18x_data_bus data_bus = {
+		.bops = &bmp18x_i2c_bus_ops,
+		.client = client
+	};
+
+	return bmp18x_probe(&client->dev, &data_bus);
+}
+
+static void bmp18x_i2c_shutdown(struct i2c_client *client)
+{
+	bmp18x_disable(&client->dev);
+}
+
+static int bmp18x_i2c_remove(struct i2c_client *client)
+{
+	return bmp18x_remove(&client->dev);
+}
+
+#ifdef CONFIG_PM
+static int bmp18x_i2c_suspend(struct device *dev)
+{
+	return bmp18x_disable(dev);
+}
+
+static int bmp18x_i2c_resume(struct device *dev)
+{
+	return bmp18x_enable(dev);
+}
+
+static const struct dev_pm_ops bmp18x_i2c_pm_ops = {
+	.suspend	= bmp18x_i2c_suspend,
+	.resume		= bmp18x_i2c_resume
+};
+#endif
+
+static const struct i2c_device_id bmp18x_id[] = {
+	{ BMP18X_NAME, 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, bmp18x_id);
+
+static struct i2c_driver bmp18x_i2c_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= BMP18X_NAME,
+#ifdef CONFIG_PM
+		.pm	= &bmp18x_i2c_pm_ops,
+#endif
+	},
+	.id_table	= bmp18x_id,
+	.probe		= bmp18x_i2c_probe,
+	.shutdown	= bmp18x_i2c_shutdown,
+	.remove		= __devexit_p(bmp18x_i2c_remove)
+};
+
+static int __init bmp18x_i2c_init(void)
+{
+	return i2c_add_driver(&bmp18x_i2c_driver);
+}
+
+static void __exit bmp18x_i2c_exit(void)
+{
+	i2c_del_driver(&bmp18x_i2c_driver);
+}
+
+
+MODULE_AUTHOR("Eric Andersson <eric.andersson@unixphere.com>");
+MODULE_DESCRIPTION("BMP18X I2C bus driver");
+MODULE_LICENSE("GPL");
+
+module_init(bmp18x_i2c_init);
+module_exit(bmp18x_i2c_exit);
diff --git a/drivers/input/misc/bmp18x.h b/drivers/input/misc/bmp18x.h
new file mode 100644
index 0000000..f9d55ec
--- /dev/null
+++ b/drivers/input/misc/bmp18x.h
@@ -0,0 +1,64 @@
+/*  Copyright (c) 2010  Christoph Mair <christoph.mair@gmail.com>
+    Copyright (c) 2011  Bosch Sensortec GmbH
+    Copyright (c) 2011  Unixphere AB
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef _BMP18X_H
+#define _BMP18X_H
+
+#define BMP18X_NAME "bmp18x"
+
+/**
+ * struct bmp18x_platform_data - represents platform data for the bmp18x driver
+ * @chip_id: Configurable chip id for non-default chip revisions
+ * @default_oversampling: Default oversampling value to be used at startup,
+ * value range is 0-3 with rising sensitivity.
+ * @default_sw_oversampling: Default software oversampling value to be used
+ * at startup,value range is 0(Disabled) or 1(Enabled). Only take effect
+ * when default_oversampling is 3.
+ * @temp_measurement_period: Temperature measurement period (milliseconds), set
+ * to zero if unsure.
+ * @init_hw: Callback for hw specific startup
+ * @deinit_hw: Callback for hw specific shutdown
+ */
+struct bmp18x_platform_data {
+	u8	chip_id;
+	u8	default_oversampling;
+	u8	default_sw_oversampling;
+	u32	temp_measurement_period;
+	int	(*init_hw)(void);
+	void	(*deinit_hw)(void);
+};
+
+struct bmp18x_bus_ops {
+	int	(*read_block)(void *client, u8 reg, int len, char *buf);
+	int	(*read_byte)(void *client, u8 reg);
+	int	(*write_byte)(void *client, u8 reg, u8 value);
+};
+
+struct bmp18x_data_bus {
+	const struct bmp18x_bus_ops	*bops;
+	void	*client;
+};
+
+int bmp18x_probe(struct device *dev, struct bmp18x_data_bus *data_bus);
+int bmp18x_remove(struct device *dev);
+#ifdef CONFIG_PM
+int bmp18x_enable(struct device *dev);
+int bmp18x_disable(struct device *dev);
+#endif
+
+#endif
diff --git a/drivers/input/misc/mma8x5x.c b/drivers/input/misc/mma8x5x.c
new file mode 100644
index 0000000..8a0d4ab
--- /dev/null
+++ b/drivers/input/misc/mma8x5x.c
@@ -0,0 +1,645 @@
+/*
+ *  mma8x5x.c - Linux kernel modules for 3-Axis Orientation/Motion
+ *  Detection Sensor MMA8451/MMA8452/MMA8453
+ *
+ *  Copyright (C) 2010-2011 Freescale Semiconductor, Inc. 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 as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  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.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/pm.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/input-polldev.h>
+#include <linux/regulator/consumer.h>
+
+#define MMA8X5X_I2C_ADDR	0x1D
+#define MMA8451_ID			0x1A
+#define MMA8452_ID			0x2A
+#define MMA8453_ID			0x3A
+#define MMA8652_ID			0x4A
+#define MMA8653_ID			0x5A
+
+
+#define POLL_INTERVAL_MIN	1
+#define POLL_INTERVAL_MAX	500
+#define POLL_INTERVAL		100 /* msecs */
+
+/* if sensor is standby ,set POLL_STOP_TIME to slow down the poll */
+#define POLL_STOP_TIME		200
+#define INPUT_FUZZ			32
+#define INPUT_FLAT			32
+#define MODE_CHANGE_DELAY_MS	100
+
+#define MMA8X5X_STATUS_ZYXDR	0x08
+#define MMA8X5X_BUF_SIZE	7
+
+struct sensor_regulator {
+	struct regulator *vreg;
+	const char *name;
+	u32	min_uV;
+	u32	max_uV;
+};
+
+static struct sensor_regulator mma_vreg[] = {
+	{NULL, "vdd", 2850000, 2850000},
+	{NULL, "vio", 1800000, 1800000},
+};
+
+/* register enum for mma8x5x registers */
+enum {
+	MMA8X5X_STATUS = 0x00,
+	MMA8X5X_OUT_X_MSB,
+	MMA8X5X_OUT_X_LSB,
+	MMA8X5X_OUT_Y_MSB,
+	MMA8X5X_OUT_Y_LSB,
+	MMA8X5X_OUT_Z_MSB,
+	MMA8X5X_OUT_Z_LSB,
+
+	MMA8X5X_F_SETUP = 0x09,
+	MMA8X5X_TRIG_CFG,
+	MMA8X5X_SYSMOD,
+	MMA8X5X_INT_SOURCE,
+	MMA8X5X_WHO_AM_I,
+	MMA8X5X_XYZ_DATA_CFG,
+	MMA8X5X_HP_FILTER_CUTOFF,
+
+	MMA8X5X_PL_STATUS,
+	MMA8X5X_PL_CFG,
+	MMA8X5X_PL_COUNT,
+	MMA8X5X_PL_BF_ZCOMP,
+	MMA8X5X_P_L_THS_REG,
+
+	MMA8X5X_FF_MT_CFG,
+	MMA8X5X_FF_MT_SRC,
+	MMA8X5X_FF_MT_THS,
+	MMA8X5X_FF_MT_COUNT,
+
+	MMA8X5X_TRANSIENT_CFG = 0x1D,
+	MMA8X5X_TRANSIENT_SRC,
+	MMA8X5X_TRANSIENT_THS,
+	MMA8X5X_TRANSIENT_COUNT,
+
+	MMA8X5X_PULSE_CFG,
+	MMA8X5X_PULSE_SRC,
+	MMA8X5X_PULSE_THSX,
+	MMA8X5X_PULSE_THSY,
+	MMA8X5X_PULSE_THSZ,
+	MMA8X5X_PULSE_TMLT,
+	MMA8X5X_PULSE_LTCY,
+	MMA8X5X_PULSE_WIND,
+
+	MMA8X5X_ASLP_COUNT,
+	MMA8X5X_CTRL_REG1,
+	MMA8X5X_CTRL_REG2,
+	MMA8X5X_CTRL_REG3,
+	MMA8X5X_CTRL_REG4,
+	MMA8X5X_CTRL_REG5,
+
+	MMA8X5X_OFF_X,
+	MMA8X5X_OFF_Y,
+	MMA8X5X_OFF_Z,
+
+	MMA8X5X_REG_END,
+};
+
+/* The sensitivity is represented in counts/g. In 2g mode the
+sensitivity is 1024 counts/g. In 4g mode the sensitivity is 512
+counts/g and in 8g mode the sensitivity is 256 counts/g.
+ */
+enum {
+	MODE_2G = 0,
+	MODE_4G,
+	MODE_8G,
+};
+
+enum {
+	MMA_STANDBY = 0,
+	MMA_ACTIVED,
+};
+struct mma8x5x_data_axis {
+	short x;
+	short y;
+	short z;
+};
+struct mma8x5x_data {
+	struct i2c_client *client;
+	struct input_polled_dev *poll_dev;
+	struct mutex data_lock;
+	int active;
+	int position;
+	u8 chip_id;
+	int mode;
+};
+/* Addresses scanned */
+static const unsigned short normal_i2c[] = {0x1c, 0x1d, I2C_CLIENT_END};
+
+static int mma8x5x_chip_id[] = {
+	MMA8451_ID,
+	MMA8452_ID,
+	MMA8453_ID,
+	MMA8652_ID,
+	MMA8653_ID,
+};
+static char *mma8x5x_names[] = {
+	"mma8451",
+	"mma8452",
+	"mma8453",
+	"mma8652",
+	"mma8653",
+};
+static int mma8x5x_position_setting[8][3][3] = {
+	{{ 0, -1,  0}, { 1,  0,	0}, {0, 0,	1} },
+	{{-1,  0,  0}, { 0, -1,	0}, {0, 0,	1} },
+	{{ 0,  1,  0}, {-1,  0,	0}, {0, 0,	1} },
+	{{ 1,  0,  0}, { 0,  1,	0}, {0, 0,	1} },
+	{{ 0, -1,  0}, {-1,  0,	0}, {0, 0,  -1} },
+	{{-1,  0,  0}, { 0,  1,	0}, {0, 0,  -1} },
+	{{ 0,  1,  0}, { 1,  0,	0}, {0, 0,  -1} },
+	{{ 1,  0,  0}, { 0, -1,	0}, {0, 0,  -1} },
+};
+
+static int mma8x5x_config_regulator(struct i2c_client *client, bool on)
+{
+	int rc = 0, i;
+	int num_vreg = sizeof(mma_vreg)/sizeof(struct sensor_regulator);
+
+	if (on) {
+		for (i = 0; i < num_vreg; i++) {
+			mma_vreg[i].vreg = regulator_get(&client->dev,
+					mma_vreg[i].name);
+			if (IS_ERR(mma_vreg[i].vreg)) {
+				rc = PTR_ERR(mma_vreg[i].vreg);
+				dev_err(&client->dev, "%s:regulator get failed rc=%d\n",
+						__func__, rc);
+				mma_vreg[i].vreg = NULL;
+				goto error_vdd;
+			}
+			if (regulator_count_voltages(mma_vreg[i].vreg) > 0) {
+				rc = regulator_set_voltage(mma_vreg[i].vreg,
+					mma_vreg[i].min_uV, mma_vreg[i].max_uV);
+				if (rc) {
+					dev_err(&client->dev, "%s:set_voltage failed rc=%d\n",
+							__func__, rc);
+					regulator_put(mma_vreg[i].vreg);
+					mma_vreg[i].vreg = NULL;
+					goto error_vdd;
+				}
+			}
+			rc = regulator_enable(mma_vreg[i].vreg);
+			if (rc) {
+				dev_err(&client->dev, "%s: regulator_enable failed rc =%d\n",
+						__func__, rc);
+				if (regulator_count_voltages(mma_vreg[i].vreg)
+						> 0) {
+					regulator_set_voltage(mma_vreg[i].vreg,
+							0, mma_vreg[i].max_uV);
+				}
+				regulator_put(mma_vreg[i].vreg);
+				mma_vreg[i].vreg = NULL;
+				goto error_vdd;
+			}
+		}
+		return rc;
+	} else {
+		i = num_vreg;
+	}
+error_vdd:
+	while (--i >= 0) {
+		if (!IS_ERR_OR_NULL(mma_vreg[i].vreg)) {
+			if (regulator_count_voltages(
+				mma_vreg[i].vreg) > 0) {
+				regulator_set_voltage(mma_vreg[i].vreg, 0,
+						mma_vreg[i].max_uV);
+			}
+			regulator_disable(mma_vreg[i].vreg);
+			regulator_put(mma_vreg[i].vreg);
+			mma_vreg[i].vreg = NULL;
+		}
+	}
+	return rc;
+}
+
+static int mma8x5x_data_convert(struct mma8x5x_data *pdata,
+		struct mma8x5x_data_axis *axis_data)
+{
+	short rawdata[3], data[3];
+	int i, j;
+	int position = pdata->position ;
+	if (position < 0 || position > 7)
+		position = 0;
+	rawdata[0] = axis_data->x;
+	rawdata[1] = axis_data->y;
+	rawdata[2] = axis_data->z;
+	for (i = 0; i < 3 ; i++) {
+		data[i] = 0;
+		for (j = 0; j < 3; j++)
+			data[i] += rawdata[j] *
+				mma8x5x_position_setting[position][i][j];
+	}
+	axis_data->x = data[0];
+	axis_data->y = data[1];
+	axis_data->z = data[2];
+	return 0;
+}
+static int mma8x5x_check_id(int id)
+{
+	int i = 0;
+	for (i = 0; i < sizeof(mma8x5x_chip_id)/sizeof(mma8x5x_chip_id[0]);
+			i++)
+		if (id == mma8x5x_chip_id[i])
+			return 1;
+	return 0;
+}
+static char *mma8x5x_id2name(u8 id)
+{
+	return mma8x5x_names[(id >> 4)-1];
+}
+static int mma8x5x_device_init(struct i2c_client *client)
+{
+	int result;
+	struct mma8x5x_data *pdata = i2c_get_clientdata(client);
+	result = i2c_smbus_write_byte_data(client, MMA8X5X_CTRL_REG1, 0);
+	if (result < 0)
+		goto out;
+
+	result = i2c_smbus_write_byte_data(client, MMA8X5X_XYZ_DATA_CFG,
+					   pdata->mode);
+	if (result < 0)
+		goto out;
+	pdata->active = MMA_STANDBY;
+	msleep(MODE_CHANGE_DELAY_MS);
+	return 0;
+out:
+	dev_err(&client->dev, "error when init mma8x5x:(%d)", result);
+	return result;
+}
+static int mma8x5x_device_stop(struct i2c_client *client)
+{
+	u8 val;
+	val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
+	i2c_smbus_write_byte_data(client, MMA8X5X_CTRL_REG1, val & 0xfe);
+	return 0;
+}
+
+static int mma8x5x_read_data(struct i2c_client *client,
+		struct mma8x5x_data_axis *data)
+{
+	u8 tmp_data[MMA8X5X_BUF_SIZE];
+	int ret;
+
+	ret = i2c_smbus_read_i2c_block_data(client,
+					    MMA8X5X_OUT_X_MSB, 7, tmp_data);
+	if (ret < MMA8X5X_BUF_SIZE) {
+		dev_err(&client->dev, "i2c block read failed\n");
+		return -EIO;
+	}
+	data->x = ((tmp_data[0] << 8) & 0xff00) | tmp_data[1];
+	data->y = ((tmp_data[2] << 8) & 0xff00) | tmp_data[3];
+	data->z = ((tmp_data[4] << 8) & 0xff00) | tmp_data[5];
+	return 0;
+}
+
+static void mma8x5x_report_data(struct mma8x5x_data *pdata)
+{
+	struct input_polled_dev *poll_dev = pdata->poll_dev;
+	struct mma8x5x_data_axis data;
+	mutex_lock(&pdata->data_lock);
+	if (pdata->active == MMA_STANDBY) {
+		poll_dev->poll_interval = POLL_STOP_TIME;
+		/* if standby ,set as 10s to slow the poll. */
+		goto out;
+	} else {
+		if (poll_dev->poll_interval == POLL_STOP_TIME)
+			poll_dev->poll_interval = POLL_INTERVAL;
+	}
+	if (mma8x5x_read_data(pdata->client, &data) != 0)
+		goto out;
+	mma8x5x_data_convert(pdata, &data);
+	input_report_abs(poll_dev->input, ABS_X, data.x);
+	input_report_abs(poll_dev->input, ABS_Y, data.y);
+	input_report_abs(poll_dev->input, ABS_Z, data.z);
+	input_sync(poll_dev->input);
+out:
+	mutex_unlock(&pdata->data_lock);
+}
+
+static void mma8x5x_dev_poll(struct input_polled_dev *dev)
+{
+	struct mma8x5x_data *pdata = (struct mma8x5x_data *)dev->private;
+	mma8x5x_report_data(pdata);
+}
+
+static ssize_t mma8x5x_enable_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct input_polled_dev *poll_dev = dev_get_drvdata(dev);
+	struct mma8x5x_data *pdata = (struct mma8x5x_data *)(poll_dev->private);
+	struct i2c_client *client = pdata->client;
+	u8 val;
+	int enable;
+
+	mutex_lock(&pdata->data_lock);
+	val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
+	if ((val & 0x01) && pdata->active == MMA_ACTIVED)
+		enable = 1;
+	else
+		enable = 0;
+	mutex_unlock(&pdata->data_lock);
+	return snprintf(buf, PAGE_SIZE, "%d\n", enable);
+}
+
+static ssize_t mma8x5x_enable_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	struct input_polled_dev *poll_dev = dev_get_drvdata(dev);
+	struct mma8x5x_data *pdata = (struct mma8x5x_data *)(poll_dev->private);
+	struct i2c_client *client = pdata->client;
+	int ret;
+	unsigned long enable;
+	u8 val = 0;
+	ret = kstrtoul(buf, 10, &enable);
+	if (ret)
+		return ret;
+	mutex_lock(&pdata->data_lock);
+	enable = (enable > 0) ? 1 : 0;
+	if (enable && pdata->active == MMA_STANDBY) {
+		val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
+		ret = i2c_smbus_write_byte_data(client,
+				MMA8X5X_CTRL_REG1, val|0x01);
+		if (!ret) {
+			pdata->active = MMA_ACTIVED;
+			printk(KERN_INFO "mma enable setting active\n");
+		}
+	} else if (enable == 0  && pdata->active == MMA_ACTIVED) {
+		val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
+		ret = i2c_smbus_write_byte_data(client,
+			MMA8X5X_CTRL_REG1, val & 0xFE);
+		if (!ret) {
+			pdata->active = MMA_STANDBY;
+			printk(KERN_INFO "mma enable setting inactive\n");
+		}
+	}
+	mutex_unlock(&pdata->data_lock);
+	return count;
+}
+static ssize_t mma8x5x_position_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct input_polled_dev *poll_dev = dev_get_drvdata(dev);
+	struct mma8x5x_data *pdata = (struct mma8x5x_data *)(poll_dev->private);
+	int position = 0;
+	mutex_lock(&pdata->data_lock);
+	position = pdata->position ;
+	mutex_unlock(&pdata->data_lock);
+	return snprintf(buf, PAGE_SIZE, "%d\n", position);
+}
+
+static ssize_t mma8x5x_position_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	struct input_polled_dev *poll_dev = dev_get_drvdata(dev);
+	struct mma8x5x_data *pdata = (struct mma8x5x_data *)(poll_dev->private);
+	int position;
+	int ret;
+	ret = kstrtoint(buf, 10, &position);
+	if (ret)
+		return ret;
+	mutex_lock(&pdata->data_lock);
+	pdata->position = position;
+	mutex_unlock(&pdata->data_lock);
+	return count;
+}
+
+static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
+		   mma8x5x_enable_show, mma8x5x_enable_store);
+static DEVICE_ATTR(position, S_IWUSR | S_IRUGO,
+		   mma8x5x_position_show, mma8x5x_position_store);
+
+static struct attribute *mma8x5x_attributes[] = {
+	&dev_attr_enable.attr,
+	&dev_attr_position.attr,
+	NULL
+};
+
+static const struct attribute_group mma8x5x_attr_group = {
+	.attrs = mma8x5x_attributes,
+};
+static int mma8x5x_detect(struct i2c_client *client,
+			  struct i2c_board_info *info)
+{
+	struct i2c_adapter *adapter = client->adapter;
+	int chip_id;
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA))
+		return -ENODEV;
+	chip_id = i2c_smbus_read_byte_data(client, MMA8X5X_WHO_AM_I);
+	if (!mma8x5x_check_id(chip_id))
+		return -ENODEV;
+	printk(KERN_INFO "check %s i2c address 0x%x\n",
+		mma8x5x_id2name(chip_id), client->addr);
+	strlcpy(info->type, "mma8x5x", I2C_NAME_SIZE);
+	return 0;
+}
+static int __devinit mma8x5x_probe(struct i2c_client *client,
+				   const struct i2c_device_id *id)
+{
+	int result, chip_id;
+	struct input_dev *idev;
+	struct mma8x5x_data *pdata;
+	struct i2c_adapter *adapter;
+	struct input_polled_dev *poll_dev;
+	adapter = to_i2c_adapter(client->dev.parent);
+	/* power on the device */
+	result = mma8x5x_config_regulator(client, 1);
+	if (result)
+		goto err_power_on;
+
+	result = i2c_check_functionality(adapter,
+					 I2C_FUNC_SMBUS_BYTE |
+					 I2C_FUNC_SMBUS_BYTE_DATA);
+	if (!result)
+		goto err_out;
+
+	chip_id = i2c_smbus_read_byte_data(client, MMA8X5X_WHO_AM_I);
+
+	if (!mma8x5x_check_id(chip_id)) {
+		dev_err(&client->dev,
+			"read chip ID 0x%x is not equal to 0x%x,0x%x,0x%x,0x%x,0x%x!\n",
+			chip_id, MMA8451_ID, MMA8452_ID, MMA8453_ID,
+			MMA8652_ID, MMA8653_ID);
+		result = -EINVAL;
+		goto err_out;
+	}
+	/* set the private data */
+	pdata = kzalloc(sizeof(struct mma8x5x_data), GFP_KERNEL);
+	if (!pdata) {
+		result = -ENOMEM;
+		dev_err(&client->dev, "alloc data memory error!\n");
+		goto err_out;
+	}
+	/* Initialize the MMA8X5X chip */
+	pdata->client = client;
+	pdata->chip_id = chip_id;
+	pdata->mode = MODE_2G;
+	pdata->position = CONFIG_SENSORS_MMA_POSITION;
+	mutex_init(&pdata->data_lock);
+	i2c_set_clientdata(client, pdata);
+	/* Initialize the MMA8X5X chip */
+	mma8x5x_device_init(client);
+	/* create the input poll device */
+	poll_dev = input_allocate_polled_device();
+	if (!poll_dev) {
+		result = -ENOMEM;
+		dev_err(&client->dev, "alloc poll device failed!\n");
+		goto err_alloc_poll_device;
+	}
+	poll_dev->poll = mma8x5x_dev_poll;
+	poll_dev->poll_interval = POLL_STOP_TIME;
+	poll_dev->poll_interval_min = POLL_INTERVAL_MIN;
+	poll_dev->poll_interval_max = POLL_INTERVAL_MAX;
+	poll_dev->private = pdata;
+	idev = poll_dev->input;
+	idev->name = "accelerometer";
+	idev->uniq = mma8x5x_id2name(pdata->chip_id);
+	idev->id.bustype = BUS_I2C;
+	idev->evbit[0] = BIT_MASK(EV_ABS);
+	input_set_abs_params(idev, ABS_X, -0x7fff, 0x7fff, 0, 0);
+	input_set_abs_params(idev, ABS_Y, -0x7fff, 0x7fff, 0, 0);
+	input_set_abs_params(idev, ABS_Z, -0x7fff, 0x7fff, 0, 0);
+	pdata->poll_dev = poll_dev;
+	result = input_register_polled_device(pdata->poll_dev);
+	if (result) {
+		dev_err(&client->dev, "register poll device failed!\n");
+		goto err_register_polled_device;
+	}
+	result = sysfs_create_group(&idev->dev.kobj, &mma8x5x_attr_group);
+	if (result) {
+		dev_err(&client->dev, "create device file failed!\n");
+		result = -EINVAL;
+		goto err_create_sysfs;
+	}
+	printk(KERN_INFO "mma8x5x device driver probe successfully\n");
+	return 0;
+err_create_sysfs:
+	input_unregister_polled_device(pdata->poll_dev);
+err_register_polled_device:
+	input_free_polled_device(poll_dev);
+err_alloc_poll_device:
+	kfree(pdata);
+err_out:
+	mma8x5x_config_regulator(client, 0);
+err_power_on:
+	return result;
+}
+static int __devexit mma8x5x_remove(struct i2c_client *client)
+{
+	struct mma8x5x_data *pdata = i2c_get_clientdata(client);
+	struct input_polled_dev *poll_dev;
+	mma8x5x_device_stop(client);
+	if (pdata) {
+		poll_dev = pdata->poll_dev;
+		input_unregister_polled_device(poll_dev);
+		input_free_polled_device(poll_dev);
+		kfree(pdata);
+	}
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mma8x5x_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mma8x5x_data *pdata = i2c_get_clientdata(client);
+	if (pdata->active == MMA_ACTIVED)
+		mma8x5x_device_stop(client);
+	return 0;
+}
+
+static int mma8x5x_resume(struct device *dev)
+{
+	int val = 0;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mma8x5x_data *pdata = i2c_get_clientdata(client);
+	if (pdata->active == MMA_ACTIVED) {
+		val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
+		i2c_smbus_write_byte_data(client, MMA8X5X_CTRL_REG1, val|0x01);
+	}
+	return 0;
+
+}
+#endif
+
+static const struct i2c_device_id mma8x5x_id[] = {
+	{"mma8x5x", 0},
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, mma8x5x_id);
+
+static const struct of_device_id mma8x5x_of_match[] = {
+	{ .compatible = "fsl,mma8x5x", },
+	{ },
+};
+
+static SIMPLE_DEV_PM_OPS(mma8x5x_pm_ops, mma8x5x_suspend, mma8x5x_resume);
+static struct i2c_driver mma8x5x_driver = {
+	.class  = I2C_CLASS_HWMON,
+	.driver = {
+		.name = "mma8x5x",
+		.owner = THIS_MODULE,
+		.pm = &mma8x5x_pm_ops,
+		.of_match_table = mma8x5x_of_match,
+	},
+	.probe = mma8x5x_probe,
+	.remove = __devexit_p(mma8x5x_remove),
+	.id_table = mma8x5x_id,
+	.detect = mma8x5x_detect,
+	.address_list = normal_i2c,
+};
+
+static int __init mma8x5x_init(void)
+{
+	/* register driver */
+	int res;
+
+	res = i2c_add_driver(&mma8x5x_driver);
+	if (res < 0) {
+		printk(KERN_INFO "add mma8x5x i2c driver failed\n");
+		return -ENODEV;
+	}
+	return res;
+}
+
+static void __exit mma8x5x_exit(void)
+{
+	i2c_del_driver(&mma8x5x_driver);
+}
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MMA8X5X 3-Axis Orientation/Motion Detection Sensor driver");
+MODULE_LICENSE("GPL");
+
+module_init(mma8x5x_init);
+module_exit(mma8x5x_exit);
diff --git a/drivers/input/misc/mpu3050.c b/drivers/input/misc/mpu3050.c
index 6c64a57..519b7e4 100644
--- a/drivers/input/misc/mpu3050.c
+++ b/drivers/input/misc/mpu3050.c
@@ -43,8 +43,8 @@
 #include <linux/gpio.h>
 #include <linux/input/mpu3050.h>
 #include <linux/regulator/consumer.h>
-
-#define MPU3050_CHIP_ID		0x69
+#include <linux/of_gpio.h>
+#include <mach/gpiomux.h>
 
 #define MPU3050_AUTO_DELAY	1000
 
@@ -124,6 +124,8 @@
 	u32    use_poll;
 	u32    poll_interval;
 	u32    dlpf_index;
+	u32    enable_gpio;
+	u32    enable;
 };
 
 struct sensor_regulator {
@@ -138,6 +140,11 @@
 	{NULL, "vlogic", 1800000, 1800000},
 };
 
+static const int mpu3050_chip_ids[] = {
+	0x68,
+	0x69,
+};
+
 struct dlpf_cfg_tb {
 	u8  cfg;	/* cfg index */
 	u32 lpf_bw;	/* low pass filter bandwidth in Hz */
@@ -293,11 +300,42 @@
 	return size;
 }
 
-static struct device_attribute attributes[] = {
+/**
+ *  Set/get enable function is just needed by sensor HAL.
+ *  Normally, the open function does all the initialization
+ *  and power work. And close undo that open does.
+ *  Just keeping the function simple.
+ */
 
+static ssize_t mpu3050_attr_set_enable(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+	struct mpu3050_sensor *sensor = dev_get_drvdata(dev);
+	unsigned long val;
+
+	if (kstrtoul(buf, 10, &val))
+		return -EINVAL;
+	sensor->enable = (u32)val;
+
+	return count;
+}
+
+static ssize_t mpu3050_attr_get_enable(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct mpu3050_sensor *sensor = dev_get_drvdata(dev);
+
+	return snprintf(buf, 4, "%d\n", sensor->enable);
+}
+
+static struct device_attribute attributes[] = {
 	__ATTR(pollrate_ms, 0664,
 		mpu3050_attr_get_polling_rate,
 		mpu3050_attr_set_polling_rate),
+	__ATTR(enable, 0644,
+		mpu3050_attr_get_enable,
+		mpu3050_attr_set_enable),
 };
 
 static int create_sysfs_interfaces(struct device *dev)
@@ -390,10 +428,12 @@
 static void mpu3050_set_power_mode(struct i2c_client *client, u8 val)
 {
 	u8 value;
+	struct mpu3050_sensor *sensor = i2c_get_clientdata(client);
 
 	if (val) {
 		mpu3050_config_regulator(client, 1);
 		udelay(10);
+		gpio_set_value(sensor->enable_gpio, 1);
 	}
 
 	value = i2c_smbus_read_byte_data(client, MPU3050_PWR_MGM);
@@ -404,6 +444,8 @@
 
 	if (!val) {
 		udelay(10);
+		gpio_set_value(sensor->enable_gpio, 0);
+		udelay(10);
 		mpu3050_config_regulator(client, 0);
 	}
 }
@@ -550,6 +592,37 @@
 
 	return 0;
 }
+#ifdef CONFIG_OF
+static int mpu3050_parse_dt(struct device *dev,
+			struct mpu3050_gyro_platform_data *pdata)
+{
+	int rc = 0;
+
+	rc = of_property_read_u32(dev->of_node, "invn,poll-interval",
+				&pdata->poll_interval);
+	if (rc) {
+		dev_err(dev, "Failed to read poll-interval\n");
+		return rc;
+	}
+
+	/* check gpio_int later, if it is invalid, just use poll */
+	pdata->gpio_int = of_get_named_gpio_flags(dev->of_node,
+				"invn,gpio-int", 0, NULL);
+
+	pdata->gpio_en = of_get_named_gpio_flags(dev->of_node,
+				"invn,gpio-en", 0, NULL);
+	if (!gpio_is_valid(pdata->gpio_en))
+		return -EINVAL;
+
+	return 0;
+}
+#else
+static int mpu3050_parse_dt(struct device *dev,
+			struct mpu3050_gyro_platform_data *pdata)
+{
+	return -EINVAL;
+}
+#endif
 
 /**
  *	mpu3050_probe	-	device detection callback
@@ -566,8 +639,10 @@
 {
 	struct mpu3050_sensor *sensor;
 	struct input_dev *idev;
+	struct mpu3050_gyro_platform_data *pdata;
 	int ret;
 	int error;
+	u32 i;
 
 	sensor = kzalloc(sizeof(struct mpu3050_sensor), GFP_KERNEL);
 	idev = input_allocate_device();
@@ -580,10 +655,29 @@
 	sensor->client = client;
 	sensor->dev = &client->dev;
 	sensor->idev = idev;
-	sensor->platform_data = client->dev.platform_data;
 	i2c_set_clientdata(client, sensor);
+
+	if (client->dev.of_node) {
+		pdata = devm_kzalloc(&client->dev,
+			sizeof(struct mpu3050_gyro_platform_data), GFP_KERNEL);
+		if (!pdata) {
+			dev_err(&client->dev, "Failed to allcated memory\n");
+			error = -ENOMEM;
+			goto err_free_mem;
+		}
+		ret = mpu3050_parse_dt(&client->dev, pdata);
+		if (ret) {
+			dev_err(&client->dev, "Failed to parse device tree\n");
+			error = ret;
+			goto err_free_mem;
+		}
+	} else
+		pdata = client->dev.platform_data;
+	sensor->platform_data = pdata;
+
 	if (sensor->platform_data) {
 		u32 interval = sensor->platform_data->poll_interval;
+		sensor->enable_gpio = sensor->platform_data->gpio_en;
 
 		if ((interval < MPU3050_MIN_POLL_INTERVAL) ||
 			(interval > MPU3050_MAX_POLL_INTERVAL))
@@ -592,6 +686,12 @@
 			sensor->poll_interval = interval;
 	} else {
 		sensor->poll_interval = MPU3050_DEFAULT_POLL_INTERVAL;
+		sensor->enable_gpio = -EINVAL;
+	}
+
+	if (gpio_is_valid(sensor->enable_gpio)) {
+		ret = gpio_request(sensor->enable_gpio, "GYRO_EN_PM");
+		gpio_direction_output(sensor->enable_gpio, 1);
 	}
 
 	mpu3050_set_power_mode(client, 1);
@@ -604,7 +704,11 @@
 		goto err_free_mem;
 	}
 
-	if (ret != MPU3050_CHIP_ID) {
+	for (i = 0; i < ARRAY_SIZE(mpu3050_chip_ids); i++)
+		if (ret == mpu3050_chip_ids[i])
+			break;
+
+	if (i == ARRAY_SIZE(mpu3050_chip_ids)) {
 		dev_err(&client->dev, "unsupported chip id\n");
 		error = -ENXIO;
 		goto err_free_mem;
@@ -617,7 +721,7 @@
 	idev->open = mpu3050_input_open;
 	idev->close = mpu3050_input_close;
 
-	__set_bit(EV_ABS, idev->evbit);
+	input_set_capability(idev, EV_ABS, ABS_MISC);
 	input_set_abs_params(idev, ABS_X,
 			     MPU3050_MIN_VALUE, MPU3050_MAX_VALUE, 0, 0);
 	input_set_abs_params(idev, ABS_Y,
@@ -657,6 +761,11 @@
 				__func__, sensor->platform_data->gpio_int);
 				goto err_free_gpio;
 			}
+			client->irq = gpio_to_irq(
+					sensor->platform_data->gpio_int);
+		} else {
+			ret = -EINVAL;
+			goto err_pm_set_suspended;
 		}
 
 		error = request_threaded_irq(client->irq,
@@ -677,14 +786,20 @@
 		goto err_free_irq;
 	}
 
-	error = create_sysfs_interfaces(&client->dev);
+	error = create_sysfs_interfaces(&idev->dev);
 	if (error < 0) {
 		dev_err(&client->dev, "failed to create sysfs\n");
 		goto err_input_cleanup;
 	}
 
-	pm_runtime_enable(&client->dev);
-	pm_runtime_set_autosuspend_delay(&client->dev, MPU3050_AUTO_DELAY);
+	if (sensor->use_poll)
+		schedule_delayed_work(&sensor->input_work,
+				msecs_to_jiffies(sensor->poll_interval));
+	else
+		i2c_smbus_write_byte_data(sensor->client, MPU3050_INT_CFG,
+				MPU3050_ACTIVE_LOW |
+				MPU3050_OPEN_DRAIN |
+				MPU3050_RAW_RDY_EN);
 
 	return 0;
 
@@ -722,6 +837,8 @@
 		free_irq(client->irq, sensor);
 
 	remove_sysfs_interfaces(&client->dev);
+	if (gpio_is_valid(sensor->enable_gpio))
+		gpio_free(sensor->enable_gpio);
 	input_unregister_device(sensor->idev);
 
 	kfree(sensor);
diff --git a/drivers/input/touchscreen/ft5x06_ts.c b/drivers/input/touchscreen/ft5x06_ts.c
index 8dbac64..8de6b1e 100644
--- a/drivers/input/touchscreen/ft5x06_ts.c
+++ b/drivers/input/touchscreen/ft5x06_ts.c
@@ -308,7 +308,7 @@
 			event->pressure = 0;
 		}
 
-		input_mt_slot(data->input_dev, i);
+		input_mt_slot(data->input_dev, event->finger_id[i]);
 		input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER,
 					!!event->pressure);
 
@@ -317,10 +317,6 @@
 					 event->x[i]);
 			input_report_abs(data->input_dev, ABS_MT_POSITION_Y,
 					 event->y[i]);
-			input_report_abs(data->input_dev, ABS_MT_PRESSURE,
-					 event->pressure);
-			input_report_abs(data->input_dev, ABS_MT_TRACKING_ID,
-					 event->finger_id[i]);
 			input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR,
 					 event->pressure);
 		}
@@ -493,7 +489,7 @@
 static int ft5x06_ts_suspend(struct device *dev)
 {
 	struct ft5x06_ts_data *data = dev_get_drvdata(dev);
-	char txbuf[2];
+	char txbuf[2], i;
 
 	if (data->loading_fw) {
 		dev_info(dev, "Firmware loading in process...\n");
@@ -507,6 +503,14 @@
 
 	disable_irq(data->client->irq);
 
+	/* release all touches */
+	for (i = 0; i < CFG_MAX_TOUCH_POINTS; i++) {
+		input_mt_slot(data->input_dev, i);
+		input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, 0);
+	}
+	input_report_key(data->input_dev, BTN_TOUCH, 0);
+	input_sync(data->input_dev);
+
 	if (gpio_is_valid(data->pdata->reset_gpio)) {
 		txbuf[0] = FT_REG_PMODE;
 		txbuf[1] = FT_PMODE_HIBERNATE;
@@ -1231,7 +1235,6 @@
 	input_set_abs_params(input_dev, ABS_MT_POSITION_Y, pdata->y_min,
 			     pdata->y_max, 0, 0);
 	input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, FT_PRESS, 0, 0);
-	input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, FT_PRESS, 0, 0);
 
 	err = input_register_device(input_dev);
 	if (err) {
@@ -1306,7 +1309,7 @@
 	err = ft5x06_i2c_read(client, &reg_addr, 1, &reg_value, 1);
 	if (err < 0) {
 		dev_err(&client->dev, "version read failed");
-		return err;
+		goto free_reset_gpio;
 	}
 
 	dev_info(&client->dev, "Device ID = 0x%x\n", reg_value);
diff --git a/drivers/input/touchscreen/synaptics_fw_update.c b/drivers/input/touchscreen/synaptics_fw_update.c
index c01ab0e..2a5fea7 100644
--- a/drivers/input/touchscreen/synaptics_fw_update.c
+++ b/drivers/input/touchscreen/synaptics_fw_update.c
@@ -1722,7 +1722,7 @@
 static struct bin_attribute dev_attr_data = {
 	.attr = {
 		.name = "data",
-		.mode = (S_IRUGO | S_IWUGO),
+		.mode = (S_IRUGO | S_IWUSR | S_IWGRP),
 	},
 	.size = 0,
 	.read = fwu_sysfs_show_image,
@@ -1730,25 +1730,25 @@
 };
 
 static struct device_attribute attrs[] = {
-	__ATTR(fw_name, S_IWUGO | S_IRUGO,
+	__ATTR(fw_name, S_IRUGO | S_IWUSR | S_IWGRP,
 			fwu_sysfs_fw_name_show,
 			fwu_sysfs_fw_name_store),
-	__ATTR(force_update_fw, S_IWUGO,
+	__ATTR(force_update_fw, S_IRUGO | S_IWUSR | S_IWGRP,
 			synaptics_rmi4_show_error,
 			fwu_sysfs_force_reflash_store),
-	__ATTR(update_fw, S_IWUGO,
+	__ATTR(update_fw, S_IRUGO | S_IWUSR | S_IWGRP,
 			synaptics_rmi4_show_error,
 			fwu_sysfs_do_reflash_store),
-	__ATTR(writeconfig, S_IWUGO,
+	__ATTR(writeconfig, S_IRUGO | S_IWUSR | S_IWGRP,
 			synaptics_rmi4_show_error,
 			fwu_sysfs_write_config_store),
-	__ATTR(readconfig, S_IWUGO,
+	__ATTR(readconfig, S_IRUGO | S_IWUSR | S_IWGRP,
 			synaptics_rmi4_show_error,
 			fwu_sysfs_read_config_store),
-	__ATTR(configarea, S_IWUGO,
+	__ATTR(configarea, S_IRUGO | S_IWUSR | S_IWGRP,
 			synaptics_rmi4_show_error,
 			fwu_sysfs_config_area_store),
-	__ATTR(imagesize, S_IWUGO,
+	__ATTR(imagesize, S_IRUGO | S_IWUSR | S_IWGRP,
 			synaptics_rmi4_show_error,
 			fwu_sysfs_image_size_store),
 	__ATTR(blocksize, S_IRUGO,
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.c b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
index 9da095a..ba0be2b 100644
--- a/drivers/input/touchscreen/synaptics_i2c_rmi4.c
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
@@ -235,11 +235,11 @@
 
 static struct device_attribute attrs[] = {
 #ifdef CONFIG_PM
-	__ATTR(full_pm_cycle, (S_IRUGO | S_IWUGO),
+	__ATTR(full_pm_cycle, (S_IRUGO | S_IWUSR | S_IWGRP),
 			synaptics_rmi4_full_pm_cycle_show,
 			synaptics_rmi4_full_pm_cycle_store),
 #endif
-	__ATTR(reset, S_IWUGO,
+	__ATTR(reset, S_IRUGO | S_IWUSR | S_IWGRP,
 			synaptics_rmi4_show_error,
 			synaptics_rmi4_f01_reset_store),
 	__ATTR(productinfo, S_IRUGO,
@@ -251,13 +251,13 @@
 	__ATTR(flashprog, S_IRUGO,
 			synaptics_rmi4_f01_flashprog_show,
 			synaptics_rmi4_store_error),
-	__ATTR(0dbutton, (S_IRUGO | S_IWUGO),
+	__ATTR(0dbutton, (S_IRUGO | S_IWUSR | S_IWGRP),
 			synaptics_rmi4_0dbutton_show,
 			synaptics_rmi4_0dbutton_store),
-	__ATTR(flipx, (S_IRUGO | S_IWUGO),
+	__ATTR(flipx, (S_IRUGO | S_IWUSR | S_IWGRP),
 			synaptics_rmi4_flipx_show,
 			synaptics_rmi4_flipx_store),
-	__ATTR(flipy, (S_IRUGO | S_IWUGO),
+	__ATTR(flipy, (S_IRUGO | S_IWUSR | S_IWGRP),
 			synaptics_rmi4_flipy_show,
 			synaptics_rmi4_flipy_store),
 };
diff --git a/drivers/input/touchscreen/synaptics_rmi_dev.c b/drivers/input/touchscreen/synaptics_rmi_dev.c
index c6b8a1c..c60ca23 100644
--- a/drivers/input/touchscreen/synaptics_rmi_dev.c
+++ b/drivers/input/touchscreen/synaptics_rmi_dev.c
@@ -73,19 +73,19 @@
 };
 
 static struct device_attribute attrs[] = {
-	__ATTR(open, S_IWUGO,
+	__ATTR(open, S_IRUGO | S_IWUSR | S_IWGRP,
 			synaptics_rmi4_show_error,
 			rmidev_sysfs_open_store),
-	__ATTR(release, S_IWUGO,
+	__ATTR(release, S_IRUGO | S_IWUSR | S_IWGRP,
 			synaptics_rmi4_show_error,
 			rmidev_sysfs_release_store),
-	__ATTR(address, S_IWUGO,
+	__ATTR(address, S_IRUGO | S_IWUSR | S_IWGRP,
 			synaptics_rmi4_show_error,
 			rmidev_sysfs_address_store),
-	__ATTR(length, S_IWUGO,
+	__ATTR(length, S_IRUGO | S_IWUSR | S_IWGRP,
 			synaptics_rmi4_show_error,
 			rmidev_sysfs_length_store),
-	__ATTR(data, (S_IRUGO | S_IWUGO),
+	__ATTR(data, (S_IRUGO | S_IWUSR | S_IWGRP),
 			rmidev_sysfs_data_show,
 			rmidev_sysfs_data_store),
 };
diff --git a/drivers/media/platform/msm/wfd/wfd-ioctl.c b/drivers/media/platform/msm/wfd/wfd-ioctl.c
index 30a666d..6554947 100644
--- a/drivers/media/platform/msm/wfd/wfd-ioctl.c
+++ b/drivers/media/platform/msm/wfd/wfd-ioctl.c
@@ -715,6 +715,11 @@
 	if (rc)
 		WFD_MSG_ERR("Failed to stop MDP\n");
 
+	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
+			ENCODE_FLUSH, (void *)inst->venc_inst);
+	if (rc)
+		WFD_MSG_ERR("Failed to flush encoder\n");
+
 	WFD_MSG_DBG("vsg stop\n");
 	rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core, ioctl,
 			 VSG_STOP, NULL);
@@ -723,10 +728,6 @@
 
 	complete(&inst->stop_mdp_thread);
 	kthread_stop(inst->mdp_task);
-	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
-			ENCODE_FLUSH, (void *)inst->venc_inst);
-	if (rc)
-		WFD_MSG_ERR("Failed to flush encoder\n");
 	WFD_MSG_DBG("enc stop\n");
 	rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
 			ENCODE_STOP, (void *)inst->venc_inst);
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 6ea2346..9d0bc61 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -605,11 +605,12 @@
 	memcpy(req.app_name, load_img_req.img_name, MAX_APP_NAME_SIZE);
 
 	ret = __qseecom_check_app_exists(req);
-	if (ret < 0)
+	if (ret < 0) {
+		qsee_disable_clock_vote(data, CLK_SFPB);
 		return ret;
-	else
-		app_id = ret;
+	}
 
+	app_id = ret;
 	if (app_id) {
 		pr_debug("App id %d (%s) already exists\n", app_id,
 			(char *)(req.app_name));
@@ -2008,14 +2009,15 @@
 		pr_err("set_cpus_allowed_ptr failed : ret %d\n",
 				set_cpu_ret);
 		ret = -EFAULT;
-		goto qseecom_load_external_elf_set_cpu_err;
+		goto exit_ion_free;
 	}
+
 	/* Vote for the SFPB clock */
 	ret = qsee_vote_for_clock(data, CLK_SFPB);
 	if (ret) {
 		pr_err("Unable to vote for SFPB clock: ret = %d", ret);
 		ret = -EIO;
-		goto qseecom_load_external_elf_set_cpu_err;
+		goto exit_cpu_restore;
 	}
 	msm_ion_do_cache_op(qseecom.ion_clnt, ihandle, NULL, len,
 				ION_IOC_CLEAN_INV_CACHES);
@@ -2027,23 +2029,32 @@
 		pr_err("scm_call to load failed : ret %d\n",
 				ret);
 		ret = -EFAULT;
-		goto qseecom_load_external_elf_scm_err;
+		goto exit_disable_clock;
 	}
 
-	if (resp.result == QSEOS_RESULT_INCOMPLETE) {
+	switch (resp.result) {
+	case QSEOS_RESULT_SUCCESS:
+		break;
+	case QSEOS_RESULT_INCOMPLETE:
+		pr_err("%s: qseos result incomplete\n", __func__);
 		ret = __qseecom_process_incomplete_cmd(data, &resp);
 		if (ret)
-			pr_err("process_incomplete_cmd failed err: %d\n",
-					ret);
-	} else {
-		if (resp.result != QSEOS_RESULT_SUCCESS) {
-			pr_err("scm_call to load image failed resp.result =%d\n",
-						resp.result);
-			ret = -EFAULT;
-		}
+			pr_err("process_incomplete_cmd failed: err: %d\n", ret);
+		break;
+	case QSEOS_RESULT_FAILURE:
+		pr_err("scm_call rsp.result is QSEOS_RESULT_FAILURE\n");
+		ret = -EFAULT;
+		break;
+	default:
+		pr_err("scm_call response result %d not supported\n",
+							resp.result);
+		ret = -EFAULT;
+		break;
 	}
 
-qseecom_load_external_elf_scm_err:
+exit_disable_clock:
+	qsee_disable_clock_vote(data, CLK_SFPB);
+exit_cpu_restore:
 	/* Restore the CPU mask */
 	mask = CPU_MASK_ALL;
 	set_cpu_ret = set_cpus_allowed_ptr(current, &mask);
@@ -2052,12 +2063,10 @@
 				set_cpu_ret);
 		ret = -EFAULT;
 	}
-
-qseecom_load_external_elf_set_cpu_err:
+exit_ion_free:
 	/* Deallocate the handle */
 	if (!IS_ERR_OR_NULL(ihandle))
 		ion_free(qseecom.ion_clnt, ihandle);
-	qsee_disable_clock_vote(data, CLK_SFPB);
 	return ret;
 }
 
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index d975543..da07947 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1363,7 +1363,7 @@
 	pr_debug("%s: %s - SANITIZE IN PROGRESS...\n",
 		mmc_hostname(card->host), __func__);
 
-	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+	err = mmc_switch_ignore_timeout(card, EXT_CSD_CMD_SET_NORMAL,
 					EXT_CSD_SANITIZE_START, 1,
 					MMC_SANITIZE_REQ_TIMEOUT);
 
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 04687fa..064d5ec 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -59,6 +59,9 @@
  */
 #define MMC_BKOPS_MAX_TIMEOUT	(30 * 1000) /* max time to wait in ms */
 
+/* Flushing a large amount of cached data may take a long time. */
+#define MMC_FLUSH_REQ_TIMEOUT_MS 30000 /* msec */
+
 static struct workqueue_struct *workqueue;
 
 /*
@@ -785,21 +788,13 @@
 		cmd = mrq->cmd;
 
 		/*
-		 * If host has timed out waiting for the blocking BKOPs
-		 * to complete, card might be still in programming state
-		 * so let's try to bring the card out of programming state.
+		 * If host has timed out waiting for the commands which can be
+		 * HPIed then let the caller handle the timeout error as it may
+		 * want to send the HPI command to bring the card out of
+		 * programming state.
 		 */
-		if (cmd->bkops_busy && cmd->error == -ETIMEDOUT) {
-			if (!mmc_interrupt_hpi(host->card)) {
-				pr_warning("%s: %s: Interrupted blocking bkops\n",
-					   mmc_hostname(host), __func__);
-				cmd->error = 0;
-				break;
-			} else {
-				pr_err("%s: %s: Failed to interrupt blocking bkops\n",
-				       mmc_hostname(host), __func__);
-			}
-		}
+		if (cmd->ignore_timeout && cmd->error == -ETIMEDOUT)
+			break;
 
 		if (!cmd->error || !cmd->retries ||
 		    mmc_card_removed(host->card))
@@ -1064,8 +1059,6 @@
 	}
 
 	err = mmc_send_hpi_cmd(card, &status);
-	if (err)
-		goto out;
 
 	prg_wait = jiffies + msecs_to_jiffies(card->ext_csd.out_of_int_time);
 	do {
@@ -2594,7 +2587,7 @@
 	if (mmc_card_sdio(card))
 		return 0;
 
-	if (mmc_card_mmc(card)) {
+	if (mmc_card_mmc(card) && (card->host->caps & MMC_CAP_HW_RESET)) {
 		rst_n_function = card->ext_csd.rst_n_function;
 		if ((rst_n_function & EXT_CSD_RST_N_EN_MASK) !=
 		    EXT_CSD_RST_N_ENABLED)
@@ -2611,9 +2604,6 @@
 	if (!host->bus_ops->power_restore)
 		return -EOPNOTSUPP;
 
-	if (!(host->caps & MMC_CAP_HW_RESET))
-		return -EOPNOTSUPP;
-
 	if (!card)
 		return -EINVAL;
 
@@ -2623,10 +2613,10 @@
 	mmc_host_clk_hold(host);
 	mmc_set_clock(host, host->f_init);
 
-	if (mmc_card_sd(card))
-		mmc_power_cycle(host);
-	else if (host->ops->hw_reset)
+	if (mmc_card_mmc(card) && host->ops->hw_reset)
 		host->ops->hw_reset(host);
+	else
+		mmc_power_cycle(host);
 
 	/* If the reset has happened, then a status command will fail */
 	if (check) {
@@ -3336,7 +3326,7 @@
 int mmc_flush_cache(struct mmc_card *card)
 {
 	struct mmc_host *host = card->host;
-	int err = 0;
+	int err = 0, rc;
 
 	if (!(host->caps2 & MMC_CAP2_CACHE_CTRL))
 		return err;
@@ -3344,11 +3334,20 @@
 	if (mmc_card_mmc(card) &&
 			(card->ext_csd.cache_size > 0) &&
 			(card->ext_csd.cache_ctrl & 1)) {
-		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-				EXT_CSD_FLUSH_CACHE, 1, 0);
-		if (err)
+		err = mmc_switch_ignore_timeout(card, EXT_CSD_CMD_SET_NORMAL,
+						EXT_CSD_FLUSH_CACHE, 1,
+						MMC_FLUSH_REQ_TIMEOUT_MS);
+		if (err == -ETIMEDOUT) {
+			pr_debug("%s: cache flush timeout\n",
+					mmc_hostname(card->host));
+			rc = mmc_interrupt_hpi(card);
+			if (rc)
+				pr_err("%s: mmc_interrupt_hpi() failed (%d)\n",
+						mmc_hostname(host), rc);
+		} else if (err) {
 			pr_err("%s: cache flush error %d\n",
 					mmc_hostname(card->host), err);
+		}
 	}
 
 	return err;
@@ -3364,8 +3363,8 @@
 int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
 {
 	struct mmc_card *card = host->card;
-	unsigned int timeout;
-	int err = 0;
+	unsigned int timeout = card->ext_csd.generic_cmd6_time;
+	int err = 0, rc;
 
 	if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) ||
 			mmc_card_is_removable(host))
@@ -3376,16 +3375,28 @@
 		enable = !!enable;
 
 		if (card->ext_csd.cache_ctrl ^ enable) {
-			timeout = enable ? card->ext_csd.generic_cmd6_time : 0;
-			err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+			if (!enable)
+				timeout = MMC_FLUSH_REQ_TIMEOUT_MS;
+
+			err = mmc_switch_ignore_timeout(card,
+					EXT_CSD_CMD_SET_NORMAL,
 					EXT_CSD_CACHE_CTRL, enable, timeout);
-			if (err)
+
+			if (err == -ETIMEDOUT && !enable) {
+				pr_debug("%s:cache disable operation timeout\n",
+						mmc_hostname(card->host));
+				rc = mmc_interrupt_hpi(card);
+				if (rc)
+					pr_err("%s: mmc_interrupt_hpi() failed (%d)\n",
+							mmc_hostname(host), rc);
+			} else if (err) {
 				pr_err("%s: cache %s error %d\n",
 						mmc_hostname(card->host),
 						enable ? "on" : "off",
 						err);
-			else
+			} else {
 				card->ext_csd.cache_ctrl = enable;
+			}
 		}
 	}
 
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 9b9c1ed..2e9db1f 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -892,9 +892,12 @@
 				MMC_SEND_TUNING_BLOCK_HS200);
 		mmc_host_clk_release(card->host);
 
-		if (err)
-			pr_warn("%s: %s: tuning execution failed %d\n",
-				   mmc_hostname(card->host), __func__, err);
+		if (err) {
+			pr_warn("%s: %s: tuning execution failed %d. Restoring to previous clock %lu\n",
+				   mmc_hostname(card->host), __func__, err,
+				   host->clk_scaling.curr_freq);
+			mmc_set_clock(host, host->clk_scaling.curr_freq);
+		}
 	}
 out:
 	mmc_release_host(host);
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 8087ea6..164c418 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -378,13 +378,13 @@
  *	@timeout_ms: timeout (ms) for operation performed by register write,
  *                   timeout of zero implies maximum possible timeout
  *	@use_busy_signal: use the busy signal as response type
- *	@bkops_busy: set this to indicate that we are starting blocking bkops
+ *	@ignore_timeout: set this flag only for commands which can be HPIed
  *
  *	Modifies the EXT_CSD register for selected card.
  */
 int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
 		 unsigned int timeout_ms, bool use_busy_signal,
-		 bool bkops_busy)
+		 bool ignore_timeout)
 {
 	int err;
 	struct mmc_command cmd = {0};
@@ -407,7 +407,7 @@
 
 
 	cmd.cmd_timeout_ms = timeout_ms;
-	cmd.bkops_busy = bkops_busy;
+	cmd.ignore_timeout = ignore_timeout;
 
 	err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
 	if (err)
@@ -458,6 +458,13 @@
 }
 EXPORT_SYMBOL_GPL(mmc_switch);
 
+int mmc_switch_ignore_timeout(struct mmc_card *card, u8 set, u8 index, u8 value,
+		unsigned int timeout_ms)
+{
+	return __mmc_switch(card, set, index, value, timeout_ms, true, true);
+}
+EXPORT_SYMBOL(mmc_switch_ignore_timeout);
+
 int mmc_send_status(struct mmc_card *card, u32 *status)
 {
 	int err;
@@ -608,7 +615,7 @@
 
 	err = mmc_wait_for_cmd(card->host, &cmd, 0);
 	if (err) {
-		pr_warn("%s: error %d interrupting operation. "
+		pr_debug("%s: error %d interrupting operation. "
 			"HPI command response %#x\n", mmc_hostname(card->host),
 			err, cmd.resp[0]);
 		return err;
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index ddf9a87..a4498d2 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -666,9 +666,12 @@
 				MMC_SEND_TUNING_BLOCK);
 		mmc_host_clk_release(card->host);
 
-		if (err)
-			pr_warn("%s: %s: tuning execution failed %d\n",
-				   mmc_hostname(card->host), __func__, err);
+		if (err) {
+			pr_warn("%s: %s: tuning execution failed %d. Restoring to previous clock %lu\n",
+				   mmc_hostname(card->host), __func__, err,
+				   host->clk_scaling.curr_freq);
+			mmc_set_clock(host, host->clk_scaling.curr_freq);
+		}
 	}
 
 out:
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 476e75c..89e3472 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -4319,56 +4319,6 @@
 	return rc;
 }
 
-/*
- * Work around of the unavailability of a power_reset functionality in SD cards
- * by turning the OFF & back ON the regulators supplying the SD card.
- */
-void msmsdcc_hw_reset(struct mmc_host *mmc)
-{
-	struct mmc_card *card = mmc->card;
-	struct msmsdcc_host *host = mmc_priv(mmc);
-	int rc;
-
-	/* Write-protection bits would be lost on a hardware reset in emmc */
-	if (!card || !mmc_card_sd(card))
-		return;
-
-	pr_debug("%s: Starting h/w reset\n", mmc_hostname(host->mmc));
-
-	if (host->plat->translate_vdd || host->plat->vreg_data) {
-
-		/* Disable the regulators */
-		if (host->plat->translate_vdd)
-			rc = host->plat->translate_vdd(mmc_dev(mmc), 0);
-		else if (host->plat->vreg_data)
-			rc = msmsdcc_setup_vreg(host, false, false);
-
-		if (rc) {
-			pr_err("%s: Failed to disable voltage regulator\n",
-				mmc_hostname(host->mmc));
-			BUG_ON(rc);
-		}
-
-		/* 10ms delay for supply to reach the desired voltage level */
-		usleep_range(10000, 12000);
-
-		/* Enable the regulators */
-		if (host->plat->translate_vdd)
-			rc = host->plat->translate_vdd(mmc_dev(mmc), 1);
-		else if (host->plat->vreg_data)
-			rc = msmsdcc_setup_vreg(host, true, false);
-
-		if (rc) {
-			pr_err("%s: Failed to enable voltage regulator\n",
-				mmc_hostname(host->mmc));
-			BUG_ON(rc);
-		}
-
-		/* 10ms delay for supply to reach the desired voltage level */
-		usleep_range(10000, 12000);
-	}
-}
-
 /**
  *	msmsdcc_stop_request - stops ongoing request
  *	@mmc: MMC host, running the request
@@ -4476,7 +4426,6 @@
 	.enable_sdio_irq = msmsdcc_enable_sdio_irq,
 	.start_signal_voltage_switch = msmsdcc_switch_io_voltage,
 	.execute_tuning = msmsdcc_execute_tuning,
-	.hw_reset = msmsdcc_hw_reset,
 	.stop_request = msmsdcc_stop_request,
 	.get_xfer_remain = msmsdcc_get_xfer_remain,
 	.notify_load = msmsdcc_notify_load,
@@ -5364,7 +5313,7 @@
 	mrq = host->curr.mrq;
 
 	if (mrq && mrq->cmd) {
-		if (!mrq->cmd->bkops_busy) {
+		if (!mrq->cmd->ignore_timeout) {
 			pr_info("%s: CMD%d: Request timeout\n",
 				mmc_hostname(host->mmc), mrq->cmd->opcode);
 			msmsdcc_dump_sdcc_state(host);
@@ -6116,6 +6065,10 @@
 
 	msmsdcc_msm_bus_cancel_work_and_set_vote(host, &mmc->ios);
 
+	/* Disable SDHCi mode if supported */
+	if (is_sdhci_supported(host))
+		writel_relaxed(0, (host->base + MCI_CORE_HC_MODE));
+
 	/* Apply Hard reset to SDCC to put it in power on default state */
 	msmsdcc_hard_reset(host);
 
@@ -6161,7 +6114,6 @@
 	mmc->caps |= plat->mmc_bus_width;
 	mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
 	mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE;
-	mmc->caps |= MMC_CAP_HW_RESET;
 	/*
 	 * If we send the CMD23 before multi block write/read command
 	 * then we need not to send CMD12 at the end of the transfer.
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index bcfde57..3668d75 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -197,6 +197,8 @@
 #define MAX_TESTBUS		8
 #define MCI_TESTBUS_ENA		(1 << 3)
 
+#define MCI_CORE_HC_MODE	0x78
+
 #define MCI_SDCC_DEBUG_REG	0x124
 
 #define MCI_IRQENABLE	\
@@ -456,6 +458,7 @@
 #define MSMSDCC_SW_RST_CFG_BROKEN	(1 << 11)
 #define MSMSDCC_DATA_PEND_FOR_CMD53	(1 << 12)
 #define MSMSDCC_TESTBUS_DEBUG		(1 << 13)
+#define MSMSDCC_SDHCI_MODE_SUPPORTED	(1 << 14)
 
 #define set_hw_caps(h, val)		((h)->hw_caps |= val)
 #define is_sps_mode(h)			((h)->hw_caps & MSMSDCC_SPS_BAM_SUP)
@@ -473,6 +476,7 @@
 				((h)->hw_caps & MSMSDCC_SW_RST_CFG_BROKEN)
 #define is_data_pend_for_cmd53(h) ((h)->hw_caps & MSMSDCC_DATA_PEND_FOR_CMD53)
 #define is_testbus_debug(h) ((h)->hw_caps & MSMSDCC_TESTBUS_DEBUG)
+#define is_sdhci_supported(h) ((h)->hw_caps & MSMSDCC_SDHCI_MODE_SUPPORTED)
 
 /* Set controller capabilities based on version */
 static inline void set_default_hw_caps(struct msmsdcc_host *host)
@@ -511,7 +515,8 @@
 				 MSMSDCC_AUTO_CMD21 |
 				 MSMSDCC_DATA_PEND_FOR_CMD53 |
 				 MSMSDCC_TESTBUS_DEBUG |
-				 MSMSDCC_SW_RST_CFG_BROKEN;
+				 MSMSDCC_SW_RST_CFG_BROKEN |
+				 MSMSDCC_SDHCI_MODE_SUPPORTED;
 }
 
 int msmsdcc_set_pwrsave(struct mmc_host *mmc, int pwrsave);
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 4ff8fea..3495f4d 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -89,6 +89,9 @@
 #define CORE_TESTBUS_ENA	(1 << 3)
 #define CORE_TESTBUS_SEL2	(1 << 4)
 
+#define CORE_MCI_VERSION	0x050
+#define CORE_VERSION_310	0x10000011
+
 /*
  * Waiting until end of potential AHB access for data:
  * 16 AHB cycles (160ns for 100MHz and 320ns for 50MHz) +
@@ -264,6 +267,7 @@
 	u32 curr_io_level;
 	struct completion pwr_irq_completion;
 	struct sdhci_msm_bus_vote msm_bus_vote;
+	struct device_attribute	polling;
 	u32 clk_rate; /* Keeps track of current clock rate that is set */
 };
 
@@ -593,6 +597,7 @@
 int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode)
 {
 	unsigned long flags;
+	int tuning_seq_cnt = 3;
 	u8 phase, *data_buf, tuned_phases[16], tuned_phase_cnt = 0;
 	const u32 *tuning_block_pattern = tuning_block_64;
 	int size = sizeof(tuning_block_64); /* Tuning pattern size in bytes */
@@ -619,17 +624,18 @@
 	}
 	spin_unlock_irqrestore(&host->lock, flags);
 
-	/* first of all reset the tuning block */
-	rc = msm_init_cm_dll(host);
-	if (rc)
-		goto out;
-
 	data_buf = kmalloc(size, GFP_KERNEL);
 	if (!data_buf) {
 		rc = -ENOMEM;
 		goto out;
 	}
 
+retry:
+	/* first of all reset the tuning block */
+	rc = msm_init_cm_dll(host);
+	if (rc)
+		goto kfree;
+
 	phase = 0;
 	do {
 		struct mmc_command cmd = {0};
@@ -686,10 +692,12 @@
 		pr_debug("%s: %s: finally setting the tuning phase to %d\n",
 				mmc_hostname(mmc), __func__, phase);
 	} else {
+		if (--tuning_seq_cnt)
+			goto retry;
 		/* tuning failed */
 		pr_err("%s: %s: no tuning point found\n",
 			mmc_hostname(mmc), __func__);
-		rc = -EAGAIN;
+		rc = -EIO;
 	}
 
 kfree:
@@ -1838,6 +1846,42 @@
 	else
 		return 0;
 }
+
+static ssize_t
+show_polling(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct sdhci_host *host = dev_get_drvdata(dev);
+	int poll;
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	poll = !!(host->mmc->caps & MMC_CAP_NEEDS_POLL);
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", poll);
+}
+
+static ssize_t
+store_polling(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sdhci_host *host = dev_get_drvdata(dev);
+	int value;
+	unsigned long flags;
+
+	if (!kstrtou32(buf, 0, &value)) {
+		spin_lock_irqsave(&host->lock, flags);
+		if (value) {
+			host->mmc->caps |= MMC_CAP_NEEDS_POLL;
+			mmc_detect_change(host->mmc, 0);
+		} else {
+			host->mmc->caps &= ~MMC_CAP_NEEDS_POLL;
+		}
+		spin_unlock_irqrestore(&host->lock, flags);
+	}
+	return count;
+}
+
 static ssize_t
 show_sdhci_max_bus_bw(struct device *dev, struct device_attribute *attr,
 			char *buf)
@@ -2129,6 +2173,12 @@
 	struct sdhci_msm_host *msm_host = pltfm_host->priv;
 	u32 value;
 	int ret;
+	u32 version;
+
+	version = readl_relaxed(msm_host->core_mem + CORE_MCI_VERSION);
+	/* Core version 3.1.0 doesn't need this workaround */
+	if (version == CORE_VERSION_310)
+		return;
 
 	value = readl_relaxed(msm_host->core_mem + CORE_MCI_DATA_CTRL);
 	value &= ~(u32)CORE_MCI_DPSM_ENABLE;
@@ -2410,7 +2460,6 @@
 					MMC_CAP_SET_XPC_300|
 					MMC_CAP_SET_XPC_330;
 
-	msm_host->mmc->caps |= MMC_CAP_HW_RESET;
 	msm_host->mmc->caps2 |= msm_host->pdata->caps2;
 	msm_host->mmc->caps2 |= MMC_CAP2_CORE_RUNTIME_PM;
 	msm_host->mmc->caps2 |= MMC_CAP2_PACKED_WR;
@@ -2464,6 +2513,16 @@
 	if (ret)
 		goto remove_host;
 
+	if (!gpio_is_valid(msm_host->pdata->status_gpio)) {
+		msm_host->polling.show = show_polling;
+		msm_host->polling.store = store_polling;
+		sysfs_attr_init(&msm_host->polling.attr);
+		msm_host->polling.attr.name = "polling";
+		msm_host->polling.attr.mode = S_IRUGO | S_IWUSR;
+		ret = device_create_file(&pdev->dev, &msm_host->polling);
+		if (ret)
+			goto remove_max_bus_bw_file;
+	}
 	ret = pm_runtime_set_active(&pdev->dev);
 	if (ret)
 		pr_err("%s: %s: pm_runtime_set_active failed: err: %d\n",
@@ -2474,6 +2533,8 @@
 	/* Successful initialization */
 	goto out;
 
+remove_max_bus_bw_file:
+	device_remove_file(&pdev->dev, &msm_host->msm_bus_vote.max_bus_bw);
 remove_host:
 	dead = (readl_relaxed(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
 	sdhci_remove_host(host, dead);
@@ -2512,6 +2573,8 @@
 			0xffffffff);
 
 	pr_debug("%s: %s\n", dev_name(&pdev->dev), __func__);
+	if (!gpio_is_valid(msm_host->pdata->status_gpio))
+		device_remove_file(&pdev->dev, &msm_host->polling);
 	device_remove_file(&pdev->dev, &msm_host->msm_bus_vote.max_bus_bw);
 	sdhci_remove_host(host, dead);
 	pm_runtime_disable(&pdev->dev);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index ce1c536..9527249 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1932,7 +1932,7 @@
 	if (host->ops->execute_tuning) {
 		spin_unlock(&host->lock);
 		enable_irq(host->irq);
-		host->ops->execute_tuning(host, opcode);
+		err = host->ops->execute_tuning(host, opcode);
 		disable_irq(host->irq);
 		spin_lock(&host->lock);
 		goto out;
@@ -2312,9 +2312,11 @@
 	spin_lock_irqsave(&host->lock, flags);
 
 	if (host->mrq) {
-		pr_err("%s: Timeout waiting for hardware "
-			"interrupt.\n", mmc_hostname(host->mmc));
-		sdhci_dumpregs(host);
+		if (!host->mrq->cmd->ignore_timeout) {
+			pr_err("%s: Timeout waiting for hardware interrupt.\n",
+			       mmc_hostname(host->mmc));
+			sdhci_dumpregs(host);
+		}
 
 		if (host->data) {
 			pr_info("%s: bytes to transfer: %d transferred: %d\n",
diff --git a/drivers/net/usb/rmnet_usb_ctrl.c b/drivers/net/usb/rmnet_usb_ctrl.c
index 0772592..d1f3748 100644
--- a/drivers/net/usb/rmnet_usb_ctrl.c
+++ b/drivers/net/usb/rmnet_usb_ctrl.c
@@ -200,8 +200,10 @@
 		dev->get_encap_failure_cnt++;
 		usb_unanchor_urb(dev->rcvurb);
 		usb_autopm_put_interface(dev->intf);
-		dev_err(dev->devicep,
-		"%s: Error submitting Read URB %d\n", __func__, status);
+		if (status != -ENODEV)
+			dev_err(dev->devicep,
+			"%s: Error submitting Read URB %d\n",
+			__func__, status);
 		goto resubmit_int_urb;
 	}
 
@@ -214,7 +216,9 @@
 		status = usb_submit_urb(dev->inturb, GFP_KERNEL);
 		if (status) {
 			usb_unanchor_urb(dev->inturb);
-			dev_err(dev->devicep, "%s: Error re-submitting Int URB %d\n",
+			if (status != -ENODEV)
+				dev_err(dev->devicep,
+				"%s: Error re-submitting Int URB %d\n",
 				__func__, status);
 		}
 	}
@@ -286,8 +290,10 @@
 	status = usb_submit_urb(urb, GFP_ATOMIC);
 	if (status) {
 		usb_unanchor_urb(urb);
-		dev_err(dev->devicep, "%s: Error re-submitting Int URB %d\n",
-		__func__, status);
+		if (status != -ENODEV)
+			dev_err(dev->devicep,
+			"%s: Error re-submitting Int URB %d\n",
+			__func__, status);
 	}
 
 	return;
@@ -383,7 +389,9 @@
 		status = usb_submit_urb(dev->inturb, GFP_ATOMIC);
 		if (status) {
 			usb_unanchor_urb(dev->inturb);
-			dev_err(dev->devicep, "%s: Error re-submitting Int URB %d\n",
+			if (status != -ENODEV)
+				dev_err(dev->devicep,
+				"%s: Error re-submitting Int URB %d\n",
 				__func__, status);
 		}
 	}
@@ -397,8 +405,9 @@
 	retval = usb_submit_urb(dev->inturb, GFP_KERNEL);
 	if (retval < 0) {
 		usb_unanchor_urb(dev->inturb);
-		dev_err(dev->devicep, "%s Intr submit %d\n", __func__,
-				retval);
+		if (retval != -ENODEV)
+			dev_err(dev->devicep,
+			"%s Intr submit %d\n", __func__, retval);
 	}
 
 	return retval;
@@ -527,7 +536,9 @@
 	dev->snd_encap_cmd_cnt++;
 	result = usb_submit_urb(sndurb, GFP_KERNEL);
 	if (result < 0) {
-		dev_err(dev->devicep, "%s: Submit URB error %d\n",
+		if (result != -ENODEV)
+			dev_err(dev->devicep,
+			"%s: Submit URB error %d\n",
 			__func__, result);
 		dev->snd_encap_cmd_cnt--;
 		usb_autopm_put_interface(dev->intf);
diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c
index 06c304a..180b856 100644
--- a/drivers/pinctrl/pinconf-generic.c
+++ b/drivers/pinctrl/pinconf-generic.c
@@ -20,6 +20,7 @@
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinconf.h>
 #include <linux/pinctrl/pinconf-generic.h>
+#include <linux/of.h>
 #include "core.h"
 #include "pinconf.h"
 
@@ -36,11 +37,15 @@
 struct pin_config_item conf_items[] = {
 	PCONFDUMP(PIN_CONFIG_BIAS_DISABLE, "input bias disabled", NULL),
 	PCONFDUMP(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, "input bias high impedance", NULL),
+	PCONFDUMP(PIN_CONFIG_BIAS_BUS_HOLD, "input bias bus hold", NULL),
 	PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL),
 	PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", NULL),
+	PCONFDUMP(PIN_CONFIG_BIAS_PULL_PIN_DEFAULT,
+				"input bias pull to pin specific state", NULL),
 	PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL),
 	PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL),
 	PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL),
+	PCONFDUMP(PIN_CONFIG_DRIVE_STRENGTH, "output drive strength", "mA"),
 	PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_ENABLE, "input schmitt enabled", NULL),
 	PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL),
 	PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "time units"),
@@ -121,3 +126,103 @@
 }
 
 #endif
+
+#ifdef CONFIG_OF
+struct pinconf_generic_dt_params {
+	const char * const property;
+	enum pin_config_param param;
+	u32 default_value;
+};
+
+static struct pinconf_generic_dt_params dt_params[] = {
+	{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
+	{ "bias-high-impedance", PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0 },
+	{ "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 },
+	{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
+	{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
+	{ "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
+	{ "drive-push-pull", PIN_CONFIG_DRIVE_PUSH_PULL, 0 },
+	{ "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 },
+	{ "drive-open-source", PIN_CONFIG_DRIVE_OPEN_SOURCE, 0 },
+	{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
+	{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
+	{ "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
+	{ "input-schmitt", PIN_CONFIG_INPUT_SCHMITT, 0 },
+	{ "input-debounce", PIN_CONFIG_INPUT_DEBOUNCE, 0 },
+	{ "power-source", PIN_CONFIG_POWER_SOURCE, 0 },
+	{ "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
+	{ "low-power-enable", PIN_CONFIG_LOW_POWER_MODE, 1 },
+	{ "low-power-disable", PIN_CONFIG_LOW_POWER_MODE, 0 },
+	{ "output-low", PIN_CONFIG_OUTPUT, 0, },
+	{ "output-high", PIN_CONFIG_OUTPUT, 1, },
+};
+
+/**
+ * pinconf_generic_parse_dt_config()
+ * parse the config properties into generic pinconfig values.
+ * @np: node containing the pinconfig properties
+ * @configs: array with nconfigs entries containing the generic pinconf values
+ * @nconfigs: umber of configurations
+ */
+int pinconf_generic_parse_dt_config(struct device_node *np,
+				    unsigned long **configs,
+				    unsigned int *nconfigs)
+{
+	unsigned long *cfg;
+	unsigned int ncfg = 0;
+	int ret;
+	int i;
+	u32 val;
+
+	if (!np)
+		return -EINVAL;
+
+	/* allocate a temporary array big enough to hold one of each option */
+	cfg = kzalloc(sizeof(*cfg) * ARRAY_SIZE(dt_params), GFP_KERNEL);
+	if (!cfg)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
+		struct pinconf_generic_dt_params *par = &dt_params[i];
+		ret = of_property_read_u32(np, par->property, &val);
+
+		/* property not found */
+		if (ret == -EINVAL)
+			continue;
+
+		/* use default value, when no value is specified */
+		if (ret)
+			val = par->default_value;
+
+		pr_debug("found %s with value %u\n", par->property, val);
+		cfg[ncfg] = pinconf_to_config_packed(par->param, val);
+		ncfg++;
+	}
+
+	ret = 0;
+
+	/* no configs found at all */
+	if (ncfg == 0) {
+		*configs = NULL;
+		*nconfigs = 0;
+		goto out;
+	}
+
+	/*
+	 * Now limit the number of configs to the real number of
+	 * found properties.
+	 */
+	*configs = kzalloc(ncfg * sizeof(unsigned long), GFP_KERNEL);
+	if (!*configs) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memcpy(*configs, cfg, ncfg * sizeof(unsigned long));
+	*nconfigs = ncfg;
+
+out:
+	kfree(cfg);
+	return ret;
+}
+#endif
diff --git a/drivers/pinctrl/pinconf.h b/drivers/pinctrl/pinconf.h
index bfda73d..bf21525 100644
--- a/drivers/pinctrl/pinconf.h
+++ b/drivers/pinctrl/pinconf.h
@@ -115,3 +115,9 @@
 }
 
 #endif
+
+#if defined(CONFIG_GENERIC_PINCONF) && defined(CONFIG_OF)
+int pinconf_generic_parse_dt_config(struct device_node *np,
+				    unsigned long **configs,
+				    unsigned int *nconfigs);
+#endif
diff --git a/drivers/platform/msm/ipa/ipa_rm_resource.c b/drivers/platform/msm/ipa/ipa_rm_resource.c
index dba4430..986892b 100644
--- a/drivers/platform/msm/ipa/ipa_rm_resource.c
+++ b/drivers/platform/msm/ipa/ipa_rm_resource.c
@@ -787,15 +787,11 @@
 				&producer->resource.state_lock, flags);
 			consumer_result = ipa_rm_resource_consumer_release(
 				(struct ipa_rm_resource_cons *)consumer);
-			if (consumer_result == -EINPROGRESS) {
-				result = -EINPROGRESS;
-			} else {
-				spin_lock_irqsave(
-					&producer->resource.state_lock, flags);
-				producer->pending_release--;
-				spin_unlock_irqrestore(
-					&producer->resource.state_lock, flags);
-			}
+			spin_lock_irqsave(
+				&producer->resource.state_lock, flags);
+			producer->pending_release--;
+			spin_unlock_irqrestore(
+				&producer->resource.state_lock, flags);
 		}
 	}
 	spin_lock_irqsave(&producer->resource.state_lock, flags);
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index e05c866..2a007ca 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -296,6 +296,8 @@
 	unsigned int			cool_bat_mv;
 	unsigned int			resume_delta_mv;
 	int				term_current;
+	int				soc_resume_limit;
+	bool				resuming_charging;
 	unsigned int			maxinput_usb_ma;
 	unsigned int			maxinput_dc_ma;
 	unsigned int			hot_batt_p;
@@ -757,6 +759,23 @@
 }
 
 static void
+qpnp_chg_set_appropriate_vbatdet(struct qpnp_chg_chip *chip)
+{
+	if (chip->bat_is_cool)
+		qpnp_chg_vbatdet_set(chip, chip->cool_bat_mv
+			- chip->resume_delta_mv);
+	else if (chip->bat_is_warm)
+		qpnp_chg_vbatdet_set(chip, chip->warm_bat_mv
+			- chip->resume_delta_mv);
+	else if (chip->resuming_charging)
+		qpnp_chg_vbatdet_set(chip, chip->max_voltage_mv
+			+ chip->resume_delta_mv);
+	else
+		qpnp_chg_vbatdet_set(chip, chip->max_voltage_mv
+			- chip->resume_delta_mv);
+}
+
+static void
 qpnp_arb_stop_work(struct work_struct *work)
 {
 	struct delayed_work *dwork = to_delayed_work(work);
@@ -955,6 +974,10 @@
 	power_supply_changed(chip->usb_psy);
 	if (chip->dc_chgpth_base)
 		power_supply_changed(&chip->dc_psy);
+	if (chip->resuming_charging) {
+		chip->resuming_charging = false;
+		qpnp_chg_set_appropriate_vbatdet(chip);
+	}
 	qpnp_chg_enable_irq(&chip->chg_vbatdet_lo);
 
 	return IRQ_HANDLED;
@@ -1295,6 +1318,16 @@
 	if (chip->bms_psy) {
 		chip->bms_psy->get_property(chip->bms_psy,
 			  POWER_SUPPLY_PROP_CAPACITY, &ret);
+		if (get_prop_batt_status(chip) == POWER_SUPPLY_STATUS_FULL
+				&& !chip->resuming_charging
+				&& !chip->charging_disabled
+				&& chip->soc_resume_limit
+				&& ret.intval <= chip->soc_resume_limit) {
+			pr_debug("resuming charging at %d%% soc\n", ret.intval);
+			chip->resuming_charging = true;
+			qpnp_chg_set_appropriate_vbatdet(chip);
+			qpnp_chg_charge_en(chip, !chip->charging_disabled);
+		}
 		if (ret.intval == 0) {
 			if (!qpnp_chg_is_usb_chg_plugged_in(chip)
 				&& !qpnp_chg_is_usb_chg_plugged_in(chip))
@@ -1674,20 +1707,6 @@
 }
 
 static void
-qpnp_chg_set_appropriate_vbatdet(struct qpnp_chg_chip *chip)
-{
-	if (chip->bat_is_cool)
-		qpnp_chg_vbatdet_set(chip, chip->cool_bat_mv
-			- chip->resume_delta_mv);
-	else if (chip->bat_is_warm)
-		qpnp_chg_vbatdet_set(chip, chip->warm_bat_mv
-			- chip->resume_delta_mv);
-	else
-		qpnp_chg_vbatdet_set(chip, chip->max_voltage_mv
-			- chip->resume_delta_mv);
-}
-
-static void
 qpnp_chg_set_appropriate_battery_current(struct qpnp_chg_chip *chip)
 {
 	unsigned int chg_current = chip->max_bat_chg_current;
@@ -2129,7 +2148,16 @@
 		chip->bat_is_cool = bat_cool;
 		chip->bat_is_warm = bat_warm;
 
-		/* set appropriate voltages and currents */
+		if (bat_cool || bat_warm)
+			chip->resuming_charging = false;
+
+		/**
+		 * set appropriate voltages and currents.
+		 *
+		 * Note that when the battery is hot or cold, the charger
+		 * driver will not resume with SoC. Only vbatdet is used to
+		 * determine resume of charging.
+		 */
 		qpnp_chg_set_appropriate_vddmax(chip);
 		qpnp_chg_set_appropriate_battery_current(chip);
 		qpnp_chg_set_appropriate_vbatdet(chip);
@@ -2692,6 +2720,8 @@
 	OF_PROP_READ(chip, tchg_mins, "tchg-mins", rc, 1);
 	OF_PROP_READ(chip, hot_batt_p, "batt-hot-percentage", rc, 1);
 	OF_PROP_READ(chip, cold_batt_p, "batt-cold-percentage", rc, 1);
+	OF_PROP_READ(chip, soc_resume_limit, "resume-soc", rc, 1);
+
 	if (rc)
 		return rc;
 
diff --git a/drivers/tty/n_smux.c b/drivers/tty/n_smux.c
index d1545dc..3794aa9 100644
--- a/drivers/tty/n_smux.c
+++ b/drivers/tty/n_smux.c
@@ -1187,8 +1187,11 @@
 			enable_powerdown = 1;
 
 		ch->local_state = SMUX_LCH_LOCAL_OPENED;
-		if (ch->remote_state == SMUX_LCH_REMOTE_OPENED)
+		if (ch->remote_state == SMUX_LCH_REMOTE_OPENED) {
 			schedule_notify(lcid, SMUX_CONNECTED, NULL);
+			if (!(list_empty(&ch->tx_queue)))
+				list_channel(ch);
+		}
 		ret = 0;
 	} else if (ch->remote_mode == SMUX_LCH_MODE_REMOTE_LOOPBACK) {
 		SMUX_DBG("smux: Remote loopback OPEN ACK received\n");
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 9446ddf..2487e3f 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -34,6 +34,7 @@
 #include <linux/usb/gadget.h>
 #include <linux/qpnp-misc.h>
 #include <linux/usb/msm_hsusb.h>
+#include <linux/usb/msm_ext_chg.h>
 #include <linux/regulator/consumer.h>
 #include <linux/power_supply.h>
 #include <linux/qpnp/qpnp-adc.h>
@@ -165,7 +166,7 @@
 struct dwc3_msm {
 	struct device *dev;
 	void __iomem *base;
-	u32 resource_size;
+	struct resource *io_res;
 	int dbm_num_eps;
 	u8 ep_num_mapping[DBM_MAX_EPS];
 	const struct usb_ep_ops *original_ep_ops[DWC3_ENDPOINTS_NUM];
@@ -2400,47 +2401,68 @@
 	return 0;
 }
 
-static ssize_t
-dwc3_msm_ext_chg_write(struct file *file, const char __user *ubuf,
-				size_t size, loff_t *pos)
+static long
+dwc3_msm_ext_chg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	struct dwc3_msm *mdwc = context;
-	char kbuf[16];
+	struct msm_usb_chg_info info = {0};
+	int ret = 0, val;
 
-	memset(kbuf, 0x00, sizeof(kbuf));
-	if (copy_from_user(&kbuf, ubuf, min_t(size_t, sizeof(kbuf) - 1, size)))
-		return -EFAULT;
+	switch (cmd) {
+	case MSM_USB_EXT_CHG_INFO:
+		info.chg_block_type = USB_CHG_BLOCK_QSCRATCH;
+		info.page_offset = (context->io_res->start +
+				QSCRATCH_REG_OFFSET) & ~PAGE_MASK;
+		/*
+		 * The charger block register address space is only
+		 * 512 bytes.  But mmap() works on PAGE granularity.
+		 */
+		info.length = PAGE_SIZE;
 
-	pr_debug("%s: buf = %s\n", __func__, kbuf);
-
-	if (!strncmp(kbuf, "enable", 6)) {
-		pr_info("%s: on\n", __func__);
-		if (mdwc->charger.chg_type == DWC3_DCP_CHARGER) {
-			pm_runtime_get_sync(mdwc->dev);
+		if (copy_to_user((void __user *)arg, &info, sizeof(info))) {
+			pr_err("%s: copy to user failed\n\n", __func__);
+			ret = -EFAULT;
+		}
+		break;
+	case MSM_USB_EXT_CHG_BLOCK_LPM:
+		if (get_user(val, (int __user *)arg)) {
+			pr_err("%s: get_user failed\n\n", __func__);
+			ret = -EFAULT;
+			break;
+		}
+		pr_debug("%s: LPM block request %d\n", __func__, val);
+		if (val) { /* block LPM */
+			if (mdwc->charger.chg_type == DWC3_DCP_CHARGER) {
+				pm_runtime_get_sync(mdwc->dev);
+			} else {
+				mdwc->ext_chg_active = false;
+				complete(&mdwc->ext_chg_wait);
+				ret = -ENODEV;
+			}
 		} else {
 			mdwc->ext_chg_active = false;
 			complete(&mdwc->ext_chg_wait);
-			return -ENODEV;
+			pm_runtime_put(mdwc->dev);
 		}
-	} else if (!strncmp(kbuf, "disable", 7)) {
-		pr_info("%s: off\n", __func__);
-		mdwc->ext_chg_active = false;
-		complete(&mdwc->ext_chg_wait);
-		pm_runtime_put(mdwc->dev);
-	} else {
-		return -EINVAL;
+		break;
+	default:
+		ret = -EINVAL;
 	}
 
-	return size;
+	return ret;
 }
 
 static int dwc3_msm_ext_chg_mmap(struct file *file, struct vm_area_struct *vma)
 {
+	struct dwc3_msm *mdwc = context;
 	unsigned long vsize = vma->vm_end - vma->vm_start;
 	int ret;
 
-	pr_debug("%s: size = %lu %x\n", __func__, vsize, (int) vma->vm_pgoff);
+	if (vma->vm_pgoff != 0 || vsize > PAGE_SIZE)
+		return -EINVAL;
 
+	vma->vm_pgoff = __phys_to_pfn(mdwc->io_res->start +
+				QSCRATCH_REG_OFFSET);
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 
 	ret = io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
@@ -2465,7 +2487,7 @@
 static const struct file_operations dwc3_msm_ext_chg_fops = {
 	.owner = THIS_MODULE,
 	.open = dwc3_msm_ext_chg_open,
-	.write = dwc3_msm_ext_chg_write,
+	.unlocked_ioctl = dwc3_msm_ext_chg_ioctl,
 	.mmap = dwc3_msm_ext_chg_mmap,
 	.release = dwc3_msm_ext_chg_release,
 };
@@ -2799,7 +2821,7 @@
 		goto disable_hs_ldo;
 	}
 
-	msm->resource_size = resource_size(res);
+	msm->io_res = res; /* used to calculate chg block offset */
 
 	if (of_property_read_u32(node, "qcom,dwc-hsphy-init",
 						&msm->hsphy_init_seq))
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index 3355e19..d1b911a 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -642,6 +642,8 @@
 	if (ctxt->ch && ctxt->ch->priv_usb == ctxt)
 		ctxt->ch->priv_usb = NULL;
 	list_del(&ctxt->list_item);
+	/* Free any pending USB requests from last session */
+	free_reqs(ctxt);
 	kfree(ctxt);
 }
 
diff --git a/drivers/video/msm/mdss/dsi_io_v2.c b/drivers/video/msm/mdss/dsi_io_v2.c
index 273fb54..f0ad511 100644
--- a/drivers/video/msm/mdss/dsi_io_v2.c
+++ b/drivers/video/msm/mdss/dsi_io_v2.c
@@ -320,7 +320,7 @@
 static void msm_dsi_phy_regulator_init(unsigned char *ctrl_base,
 					struct mdss_dsi_phy_ctrl *pd)
 {
-	MIPI_OUTP(ctrl_base + DSI_DSIPHY_LDO_CNTRL, 0x04);
+	MIPI_OUTP(ctrl_base + DSI_DSIPHY_LDO_CNTRL, 0x25);
 	MIPI_OUTP(ctrl_base + DSI_DSIPHY_REGULATOR_CTRL_0, pd->regulator[0]);
 	MIPI_OUTP(ctrl_base + DSI_DSIPHY_REGULATOR_CTRL_1, pd->regulator[1]);
 	MIPI_OUTP(ctrl_base + DSI_DSIPHY_REGULATOR_CTRL_2, pd->regulator[2]);
diff --git a/drivers/video/msm/mdss/dsi_v2.c b/drivers/video/msm/mdss/dsi_v2.c
index 5833796..1a9059c 100644
--- a/drivers/video/msm/mdss/dsi_v2.c
+++ b/drivers/video/msm/mdss/dsi_v2.c
@@ -26,15 +26,6 @@
 static int dsi_off(struct mdss_panel_data *pdata)
 {
 	int rc = 0;
-	if (!panel_common_data || !pdata)
-		return -ENODEV;
-
-	if (dsi_intf.op_mode_config)
-		dsi_intf.op_mode_config(DSI_CMD_MODE, pdata);
-
-	pr_debug("panel off commands\n");
-	if (panel_common_data->off)
-		panel_common_data->off(pdata);
 
 	pr_debug("turn off dsi controller\n");
 	if (dsi_intf.off)
@@ -44,11 +35,6 @@
 		pr_err("mdss_dsi_off DSI failed %d\n", rc);
 		return rc;
 	}
-
-	pr_debug("turn off panel power\n");
-	if (panel_common_data->reset)
-		panel_common_data->reset(pdata, 0);
-
 	return rc;
 }
 
@@ -56,13 +42,7 @@
 {
 	int rc = 0;
 
-	pr_debug("dsi_on\n");
-
-	if (!panel_common_data || !pdata)
-		return -ENODEV;
-
-
-	pr_debug("dsi_on DSI controller ont\n");
+	pr_debug("dsi_on DSI controller on\n");
 	if (dsi_intf.on)
 		rc = dsi_intf.on(pdata);
 
@@ -70,17 +50,34 @@
 		pr_err("mdss_dsi_on DSI failed %d\n", rc);
 		return rc;
 	}
-	pr_debug("dsi_on power on panel\n");
-	if (panel_common_data->reset)
-		panel_common_data->reset(pdata, 1);
+	return rc;
+}
+static int dsi_panel_handler(struct mdss_panel_data *pdata, int enable)
+{
+	int rc = 0;
 
-	pr_debug("dsi_on DSI panel ont\n");
-	if (panel_common_data->on)
-		rc = panel_common_data->on(pdata);
+	pr_debug("dsi_panel_handler enable=%d\n", enable);
+	if (!panel_common_data || !pdata)
+		return -ENODEV;
 
-	if (rc) {
-		pr_err("mdss_dsi_on panel failed %d\n", rc);
-		return rc;
+	if (enable) {
+		if (panel_common_data->reset)
+			panel_common_data->reset(pdata, 1);
+
+		if (panel_common_data->on)
+			rc = panel_common_data->on(pdata);
+
+		if (rc)
+			pr_err("dsi_panel_handler panel on failed %d\n", rc);
+	} else {
+		if (dsi_intf.op_mode_config)
+			dsi_intf.op_mode_config(DSI_CMD_MODE, pdata);
+
+		if (panel_common_data->off)
+			panel_common_data->off(pdata);
+
+		if (panel_common_data->reset)
+			panel_common_data->reset(pdata, 0);
 	}
 	return rc;
 }
@@ -96,12 +93,18 @@
 	}
 
 	switch (event) {
-	case MDSS_EVENT_PANEL_ON:
+	case MDSS_EVENT_UNBLANK:
 		rc = dsi_on(pdata);
 		break;
-	case MDSS_EVENT_PANEL_OFF:
+	case MDSS_EVENT_BLANK:
 		rc = dsi_off(pdata);
 		break;
+	case MDSS_EVENT_PANEL_ON:
+		rc = dsi_panel_handler(pdata, 1);
+		break;
+	case MDSS_EVENT_PANEL_OFF:
+		rc = dsi_panel_handler(pdata, 0);
+		break;
 	default:
 		pr_debug("%s: unhandled event=%d\n", __func__, event);
 		break;
diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c
index 91e70a7..66418db 100644
--- a/drivers/video/msm/mdss/mdp3.c
+++ b/drivers/video/msm/mdss/mdp3.c
@@ -161,12 +161,19 @@
 {
 	int i = 0;
 	struct mdp3_hw_resource *mdata = (struct mdp3_hw_resource *)ptr;
-	u32 mdp_interrupt = MDP3_REG_READ(MDP3_REG_INTR_STATUS);
+	u32 mdp_interrupt = 0;
 
+	spin_lock(&mdata->irq_lock);
+	if (!mdata->irq_mask) {
+		pr_err("spurious interrupt\n");
+		spin_unlock(&mdata->irq_lock);
+		return IRQ_HANDLED;
+	}
+
+	mdp_interrupt = MDP3_REG_READ(MDP3_REG_INTR_STATUS);
 	MDP3_REG_WRITE(MDP3_REG_INTR_CLEAR, mdp_interrupt);
 	pr_debug("mdp3_irq_handler irq=%d\n", mdp_interrupt);
 
-	spin_lock(&mdata->irq_lock);
 	mdp_interrupt &= mdata->irq_mask;
 
 	while (mdp_interrupt && i < MDP3_MAX_INTR) {
@@ -183,7 +190,6 @@
 void mdp3_irq_enable(int type)
 {
 	unsigned long flag;
-	int irqEnabled = 0;
 
 	pr_debug("mdp3_irq_enable type=%d\n", type);
 	spin_lock_irqsave(&mdp3_res->irq_lock, flag);
@@ -193,11 +199,10 @@
 		spin_unlock_irqrestore(&mdp3_res->irq_lock, flag);
 		return;
 	}
-	irqEnabled = mdp3_res->irq_mask;
+
 	mdp3_res->irq_mask |= BIT(type);
 	MDP3_REG_WRITE(MDP3_REG_INTR_ENABLE, mdp3_res->irq_mask);
-	if (!irqEnabled)
-		enable_irq(mdp3_res->irq);
+
 	spin_unlock_irqrestore(&mdp3_res->irq_lock, flag);
 }
 
@@ -220,8 +225,6 @@
 	if (mdp3_res->irq_ref_count[type] == 0) {
 		mdp3_res->irq_mask &= ~BIT(type);
 		MDP3_REG_WRITE(MDP3_REG_INTR_ENABLE, mdp3_res->irq_mask);
-		if (!mdp3_res->irq_mask)
-			disable_irq_nosync(mdp3_res->irq);
 	}
 }
 
@@ -229,7 +232,7 @@
 {
 	unsigned long flag;
 
-	pr_debug("interrupt %d callback n", type);
+	pr_debug("interrupt %d callback\n", type);
 	spin_lock_irqsave(&mdp3_res->irq_lock, flag);
 	if (cb)
 		mdp3_res->callbacks[type] = *cb;
@@ -240,6 +243,30 @@
 	return 0;
 }
 
+void mdp3_irq_register(void)
+{
+	unsigned long flag;
+
+	pr_debug("mdp3_irq_register\n");
+	spin_lock_irqsave(&mdp3_res->irq_lock, flag);
+	enable_irq(mdp3_res->irq);
+	spin_unlock_irqrestore(&mdp3_res->irq_lock, flag);
+}
+
+void mdp3_irq_deregister(void)
+{
+	unsigned long flag;
+
+	pr_debug("mdp3_irq_deregister\n");
+	spin_lock_irqsave(&mdp3_res->irq_lock, flag);
+	memset(mdp3_res->irq_ref_count, 0, sizeof(u32) * MDP3_MAX_INTR);
+	mdp3_res->irq_mask = 0;
+	MDP3_REG_WRITE(MDP3_REG_INTR_ENABLE, 0);
+	MDP3_REG_WRITE(MDP3_REG_INTR_CLEAR, 0xfffffff);
+	disable_irq_nosync(mdp3_res->irq);
+	spin_unlock_irqrestore(&mdp3_res->irq_lock, flag);
+}
+
 static int mdp3_bus_scale_register(void)
 {
 	int i;
@@ -955,6 +982,92 @@
 		return xres * bpp;
 }
 
+static int mdp3_fbmem_alloc(struct msm_fb_data_type *mfd)
+{
+	int ret = -ENOMEM, dom;
+	void *virt = NULL;
+	unsigned long phys = 0;
+	size_t size;
+	u32 yres = mfd->fbi->var.yres_virtual;
+
+	size = PAGE_ALIGN(mfd->fbi->fix.line_length * yres);
+
+	if (mfd->index != 0) {
+		mfd->fbi->screen_base = virt;
+		mfd->fbi->fix.smem_start = phys;
+		mfd->fbi->fix.smem_len = 0;
+		return 0;
+	}
+
+	mdp3_res->ion_handle = ion_alloc(mdp3_res->ion_client, size,
+					SZ_1M,
+					ION_HEAP(ION_QSECOM_HEAP_ID), 0);
+
+	if (!IS_ERR_OR_NULL(mdp3_res->ion_handle)) {
+		virt = ion_map_kernel(mdp3_res->ion_client,
+					mdp3_res->ion_handle);
+		if (IS_ERR(virt)) {
+			pr_err("%s map kernel error\n", __func__);
+			goto ion_map_kernel_err;
+		}
+
+		ret = ion_phys(mdp3_res->ion_client, mdp3_res->ion_handle,
+				&phys, &size);
+		if (ret) {
+			pr_err("%s ion_phys error\n", __func__);
+			goto ion_map_phys_err;
+		}
+	} else {
+		pr_err("%s ion alloc fail\n", __func__);
+		mdp3_res->ion_handle = NULL;
+		return -ENOMEM;
+	}
+
+	dom = (mdp3_res->domains + MDP3_IOMMU_DOMAIN)->domain_idx;
+
+	ret = ion_map_iommu(mdp3_res->ion_client, mdp3_res->ion_handle,
+			dom, 0, SZ_4K, 0, &mfd->iova,
+			(unsigned long *)&size, 0, 0);
+
+	if (ret) {
+		pr_err("%s map IOMMU error\n", __func__);
+		goto ion_map_phys_err;
+	}
+
+	pr_info("allocating %u bytes at %p (%lx phys) for fb %d\n",
+			size, virt, phys, mfd->index);
+
+	mfd->fbi->screen_base = virt;
+	mfd->fbi->fix.smem_start = phys;
+	mfd->fbi->fix.smem_len = size;
+	return 0;
+
+ion_map_phys_err:
+	ion_unmap_kernel(mdp3_res->ion_client, mdp3_res->ion_handle);
+ion_map_kernel_err:
+	ion_free(mdp3_res->ion_client, mdp3_res->ion_handle);
+	mdp3_res->ion_handle = NULL;
+	return -ENOMEM;
+}
+
+void mdp3_fbmem_free(struct msm_fb_data_type *mfd)
+{
+	pr_info("mdp3_fbmem_free\n");
+	if (mdp3_res->ion_handle) {
+		int dom = (mdp3_res->domains + MDP3_IOMMU_DOMAIN)->domain_idx;
+
+		ion_unmap_kernel(mdp3_res->ion_client, mdp3_res->ion_handle);
+		ion_unmap_iommu(mdp3_res->ion_client,  mdp3_res->ion_handle,
+				dom, 0);
+		ion_free(mdp3_res->ion_client, mdp3_res->ion_handle);
+		mdp3_res->ion_handle = NULL;
+		mfd->fbi->screen_base = 0;
+		mfd->fbi->fix.smem_start = 0;
+		mfd->fbi->fix.smem_len = 0;
+		mfd->iova = 0;
+	}
+}
+
 struct mdp3_dma *mdp3_get_dma_pipe(int capability)
 {
 	int i;
@@ -996,6 +1109,7 @@
 	static struct msm_mdp_interface mdp3_interface = {
 	.init_fnc = mdp3_init,
 	.fb_mem_get_iommu_domain = mdp3_fb_mem_get_iommu_domain,
+	.fb_mem_alloc_fnc = mdp3_fbmem_alloc,
 	.fb_stride = mdp3_fb_stride,
 	};
 
diff --git a/drivers/video/msm/mdss/mdp3.h b/drivers/video/msm/mdss/mdp3.h
index 1afae01..d29e5b6 100644
--- a/drivers/video/msm/mdss/mdp3.h
+++ b/drivers/video/msm/mdss/mdp3.h
@@ -110,6 +110,7 @@
 	struct ion_client *ion_client;
 	struct mdp3_iommu_domain_map *domains;
 	struct mdp3_iommu_ctx_map *iommu_contexts;
+	struct ion_handle *ion_handle;
 
 	struct mdp3_dma dma[MDP3_DMA_MAX];
 	struct mdp3_intf intf[MDP3_DMA_OUTPUT_SEL_MAX];
@@ -141,6 +142,8 @@
 void mdp3_irq_disable(int type);
 void mdp3_irq_disable_nosync(int type);
 int mdp3_set_intr_callback(u32 type, struct mdp3_intr_cb *cb);
+void mdp3_irq_register(void);
+void mdp3_irq_deregister(void);
 int mdp3_clk_set_rate(int clk_type, unsigned long clk_rate, int client);
 int mdp3_clk_enable(int enable);
 int mdp3_bus_scale_set_quota(int client, u64 ab_quota, u64 ib_quota);
@@ -148,6 +151,7 @@
 int mdp3_get_img(struct msmfb_data *img, struct mdp3_img_data *data);
 int mdp3_iommu_enable(int client);
 int mdp3_iommu_disable(int client);
+void mdp3_fbmem_free(struct msm_fb_data_type *mfd);
 
 #define MDP3_REG_WRITE(addr, val) writel_relaxed(val, mdp3_res->mdp_base + addr)
 #define MDP3_REG_READ(addr) readl_relaxed(mdp3_res->mdp_base + addr)
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index f43d1ed..04cd78c 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -427,8 +427,10 @@
 	}
 
 	panel = mdp3_session->panel;
-	if (panel->event_handler)
-		rc = panel->event_handler(panel, MDSS_EVENT_PANEL_ON, NULL);
+	if (panel->event_handler) {
+		rc = panel->event_handler(panel, MDSS_EVENT_UNBLANK, NULL);
+		rc |= panel->event_handler(panel, MDSS_EVENT_PANEL_ON, NULL);
+	}
 	if (rc) {
 		pr_err("fail to turn on the panel\n");
 		goto on_error;
@@ -439,6 +441,8 @@
 		goto on_error;
 	}
 
+	mdp3_irq_register();
+
 	rc = mdp3_ctrl_dma_init(mfd, mdp3_session->dma);
 	if (rc) {
 		pr_err("dma init failed\n");
@@ -457,6 +461,10 @@
 		goto on_error;
 	}
 
+	if (panel->set_backlight)
+		panel->set_backlight(panel, panel->panel_info.bl_max);
+
+	pr_debug("mdp3_ctrl_on dma start\n");
 	if (mfd->fbi->screen_base) {
 		rc = mdp3_session->dma->start(mdp3_session->dma,
 						mdp3_session->intf);
@@ -488,6 +496,7 @@
 		return -ENODEV;
 	}
 
+	panel = mdp3_session->panel;
 	mutex_lock(&mdp3_session->lock);
 
 	if (!mdp3_session->status) {
@@ -495,30 +504,39 @@
 		goto off_error;
 	}
 
-	pr_debug("mdp3_ctrl_off stop mdp3 dma engine\n");
-
 	mdp3_histogram_stop(mdp3_session, MDP_BLOCK_DMA_P);
 
-	rc = mdp3_session->dma->stop(mdp3_session->dma, mdp3_session->intf);
+	pr_debug("mdp3_ctrl_off turn panel off\n");
+	if (panel->set_backlight)
+		panel->set_backlight(panel, 0);
 
-	if (rc)
-		pr_err("fail to stop the MDP3 dma\n");
-
-	pr_debug("mdp3_ctrl_off stop dsi panel and controller\n");
-	panel = mdp3_session->panel;
 	if (panel->event_handler)
 		rc = panel->event_handler(panel, MDSS_EVENT_PANEL_OFF, NULL);
 	if (rc)
 		pr_err("fail to turn off the panel\n");
 
-	pr_debug("mdp3_ctrl_off release bus and clock\n");
-	rc = mdp3_ctrl_res_req_bus(mfd, 0);
+	rc = mdp3_session->dma->stop(mdp3_session->dma, mdp3_session->intf);
 	if (rc)
-		pr_err("mdp bus resource release failed\n");
+		pr_err("fail to stop the MDP3 dma\n");
+
+	mdp3_irq_deregister();
+
+	pr_debug("mdp3_ctrl_off stop clock\n");
 	rc = mdp3_ctrl_res_req_clk(mfd, 0);
 	if (rc)
 		pr_err("mdp clock resource release failed\n");
 
+	pr_debug("mdp3_ctrl_off stop dsi controller\n");
+	if (panel->event_handler)
+		rc = panel->event_handler(panel, MDSS_EVENT_BLANK, NULL);
+	if (rc)
+		pr_err("fail to turn off the panel\n");
+
+	pr_debug("mdp3_ctrl_off release bus\n");
+	rc = mdp3_ctrl_res_req_bus(mfd, 0);
+	if (rc)
+		pr_err("mdp bus resource release failed\n");
+
 	rc = mdp3_iommu_disable(MDP3_CLIENT_DMA_P);
 	if (rc)
 		pr_err("fail to dettach MDP DMA SMMU\n");
@@ -666,6 +684,9 @@
 	if (mdp3_bufq_count(&mdp3_session->bufq_out) > 2) {
 		data = mdp3_bufq_pop(&mdp3_session->bufq_out);
 		mdp3_put_img(data);
+
+		if (mfd->fbi->screen_base)
+			mdp3_fbmem_free(mfd);
 	}
 	mutex_unlock(&mdp3_session->lock);
 
diff --git a/drivers/video/msm/mdss/mdp3_ppp.c b/drivers/video/msm/mdss/mdp3_ppp.c
index 48ffb72..afb2eb4 100644
--- a/drivers/video/msm/mdss/mdp3_ppp.c
+++ b/drivers/video/msm/mdss/mdp3_ppp.c
@@ -898,8 +898,8 @@
 	struct blit_req_list *req;
 	int i, rc;
 
-	req = mdp3_ppp_next_req(&ppp_stat->req_q);
 	mutex_lock(&ppp_stat->config_ppp_mutex);
+	req = mdp3_ppp_next_req(&ppp_stat->req_q);
 
 	mdp3_iommu_enable(MDP3_CLIENT_PPP);
 	mdp3_ppp_turnon(mfd, 1);
diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h
index 078960b..840af17 100644
--- a/drivers/video/msm/mdss/mdss.h
+++ b/drivers/video/msm/mdss/mdss.h
@@ -89,6 +89,7 @@
 
 	u32 smp_mb_cnt;
 	u32 smp_mb_size;
+	u32 smp_mb_per_pipe;
 
 	u32 rot_block_size;
 
diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c
index 2f29b3d..e682e69 100644
--- a/drivers/video/msm/mdss/mdss_dsi_host.c
+++ b/drivers/video/msm/mdss/mdss_dsi_host.c
@@ -1209,6 +1209,8 @@
 {
 	u32 dsi_ctrl, data;
 	int video_mode;
+	u32 left_dsi_ctrl = 0;
+	bool left_ctrl_restore = false;
 
 	if (ctrl->shared_pdata.broadcast_enable) {
 		if (ctrl->ndx == DSI_CTRL_0) {
@@ -1221,13 +1223,15 @@
 	if (ctrl->shared_pdata.broadcast_enable) {
 		if ((ctrl->ndx == DSI_CTRL_1)
 		  && (left_ctrl_pdata != NULL)) {
-			dsi_ctrl = MIPI_INP(left_ctrl_pdata->ctrl_base
+			left_dsi_ctrl = MIPI_INP(left_ctrl_pdata->ctrl_base
 								+ 0x0004);
-			video_mode = dsi_ctrl & 0x02; /* VIDEO_MODE_EN */
+			video_mode =
+				left_dsi_ctrl & 0x02; /* VIDEO_MODE_EN */
 			if (video_mode) {
-				data = dsi_ctrl | 0x04; /* CMD_MODE_EN */
+				data = left_dsi_ctrl | 0x04; /* CMD_MODE_EN */
 				MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x0004,
 						data);
+				left_ctrl_restore = true;
 			}
 		}
 	}
@@ -1246,6 +1250,10 @@
 
 	mdss_dsi_cmds2buf_tx(ctrl, cmds, cnt);
 
+	if (left_ctrl_restore)
+		MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x0004,
+					left_dsi_ctrl); /*restore */
+
 	if (video_mode)
 		MIPI_OUTP((ctrl->ctrl_base) + 0x0004,
 					dsi_ctrl); /* restore */
@@ -1280,6 +1288,45 @@
 	struct dsi_buf *tp, *rp;
 	int no_max_pkt_size;
 	char cmd;
+	u32 dsi_ctrl, data;
+	int video_mode;
+	u32 left_dsi_ctrl = 0;
+	bool left_ctrl_restore = false;
+
+	if (ctrl->shared_pdata.broadcast_enable) {
+		if (ctrl->ndx == DSI_CTRL_0) {
+			pr_debug("%s: Broadcast mode. 1st ctrl\n",
+				 __func__);
+			return 0;
+		}
+	}
+
+	if (ctrl->shared_pdata.broadcast_enable) {
+		if ((ctrl->ndx == DSI_CTRL_1)
+		  && (left_ctrl_pdata != NULL)) {
+			left_dsi_ctrl = MIPI_INP(left_ctrl_pdata->ctrl_base
+								+ 0x0004);
+			video_mode = left_dsi_ctrl & 0x02; /* VIDEO_MODE_EN */
+			if (video_mode) {
+				data = left_dsi_ctrl | 0x04; /* CMD_MODE_EN */
+				MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x0004,
+						data);
+				left_ctrl_restore = true;
+			}
+		}
+	}
+
+	/* turn on cmd mode
+	* for video mode, do not send cmds more than
+	* one pixel line, since it only transmit it
+	* during BLLP.
+	*/
+	dsi_ctrl = MIPI_INP((ctrl->ctrl_base) + 0x0004);
+	video_mode = dsi_ctrl & 0x02; /* VIDEO_MODE_EN */
+	if (video_mode) {
+		data = dsi_ctrl | 0x04; /* CMD_MODE_EN */
+		MIPI_OUTP((ctrl->ctrl_base) + 0x0004, data);
+	}
 
 	no_max_pkt_size = rx_flags & CMD_REQ_NO_MAX_PKT_SIZE;
 	if (no_max_pkt_size)
@@ -1378,6 +1425,13 @@
 		break;
 	}
 
+	if (left_ctrl_restore)
+		MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x0004,
+					left_dsi_ctrl); /*restore */
+	if (video_mode)
+		MIPI_OUTP((ctrl->ctrl_base) + 0x0004,
+					dsi_ctrl); /* restore */
+
 	return rp->len;
 }
 
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index 56a4ac4..0a41ef8 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -1511,10 +1511,16 @@
 
 	rc = mdss_mdp_smp_setup(mdata, data[0], data[1]);
 
-	if (rc)
+	if (rc) {
 		pr_err("unable to setup smp data\n");
+		return rc;
+	}
 
-	return rc;
+	rc = of_property_read_u32(pdev->dev.of_node,
+		"qcom,mdss-smp-mb-per-pipe", data);
+	mdata->smp_mb_per_pipe = (!rc ? data[0] : 0);
+
+	return 0;
 }
 
 static int mdss_mdp_parse_dt_misc(struct platform_device *pdev)
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index 8ecc861..950fd27 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -301,6 +301,11 @@
 	struct pp_sts_type pp_sts;
 };
 
+struct mdss_mdp_pipe_smp_map {
+	DECLARE_BITMAP(reserved, MDSS_MDP_SMP_MMB_BLOCKS);
+	DECLARE_BITMAP(allocated, MDSS_MDP_SMP_MMB_BLOCKS);
+};
+
 struct mdss_mdp_pipe {
 	u32 num;
 	u32 type;
@@ -337,8 +342,7 @@
 	struct mdp_overlay req_data;
 	u32 params_changed;
 
-	unsigned long smp[MAX_PLANES];
-	unsigned long smp_reserved[MAX_PLANES];
+	struct mdss_mdp_pipe_smp_map smp_map[MAX_PLANES];
 
 	struct mdss_mdp_data back_buf;
 	struct mdss_mdp_data front_buf;
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index e656131..f6225ab 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -1722,9 +1722,13 @@
 
 static inline int __mdss_mdp_ctl_get_mixer_off(struct mdss_mdp_mixer *mixer)
 {
-	if (mixer->type == MDSS_MDP_MIXER_TYPE_INTF)
-		return MDSS_MDP_REG_CTL_LAYER(mixer->num);
-	else
+	if (mixer->type == MDSS_MDP_MIXER_TYPE_INTF) {
+		if (mixer->num == MDSS_MDP_INTF_LAYERMIXER3)
+			return MDSS_MDP_CTL_X_LAYER_5;
+		else
+			return MDSS_MDP_REG_CTL_LAYER(mixer->num);
+	} else {
 		return MDSS_MDP_REG_CTL_LAYER(mixer->num +
-				MDSS_MDP_INTF_MAX_LAYERMIXER);
+				MDSS_MDP_INTF_LAYERMIXER3);
+	}
 }
diff --git a/drivers/video/msm/mdss/mdss_mdp_hwio.h b/drivers/video/msm/mdss/mdss_mdp_hwio.h
index 8e5534d..ccd6e56 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -235,6 +235,7 @@
 
 #define MDSS_MDP_NUM_REG_MIXERS 3
 #define MDSS_MDP_NUM_WB_MIXERS 2
+#define MDSS_MDP_CTL_X_LAYER_5 0x24
 
 enum mdss_mdp_mixer_intf_index {
 	MDSS_MDP_INTF_LAYERMIXER0,
@@ -496,7 +497,7 @@
 #define MDSS_MDP_REG_SMP_ALLOC_W0			0x00180
 #define MDSS_MDP_REG_SMP_ALLOC_R0			0x00230
 
-#define MDSS_MDP_SMP_MMB_BLOCKS			22
+#define MDSS_MDP_SMP_MMB_BLOCKS			44
 
 #define MDSS_MDP_LP_MISR_SEL			0x450
 #define MDSS_MDP_LP_MISR_CTRL_MDP		0x454
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
index ab028e4..9b81633 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
@@ -573,7 +573,7 @@
 	mdss_mdp_ctl_write(ctl, 0, MDSS_MDP_LM_BORDER_COLOR);
 	off = MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num);
 
-	if (mdss_mdp_rev == MDSS_MDP_HW_REV_102)
+	if (mdss_mdp_rev >= MDSS_MDP_HW_REV_102)
 		mdss_v2_intf_off =  0xEC00;
 
 	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_TIMING_ENGINE_EN -
diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index 137da66..d1e5e64 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -132,8 +132,8 @@
 
 	mutex_lock(&mdss_mdp_smp_lock);
 	for (i = 0; i < MAX_PLANES; i++) {
-		mdss_mdp_smp_mmb_free(&pipe->smp_reserved[i], false);
-		mdss_mdp_smp_mmb_free(&pipe->smp[i], true);
+		mdss_mdp_smp_mmb_free(pipe->smp_map[i].reserved, false);
+		mdss_mdp_smp_mmb_free(pipe->smp_map[i].allocated, true);
 	}
 	mutex_unlock(&mdss_mdp_smp_lock);
 }
@@ -144,7 +144,7 @@
 
 	mutex_lock(&mdss_mdp_smp_lock);
 	for (i = 0; i < MAX_PLANES; i++)
-		mdss_mdp_smp_mmb_free(&pipe->smp_reserved[i], false);
+		mdss_mdp_smp_mmb_free(pipe->smp_map[i].reserved, false);
 	mutex_unlock(&mdss_mdp_smp_lock);
 }
 
@@ -193,13 +193,17 @@
 
 			if (mdata->mdp_rev == MDSS_MDP_HW_REV_100)
 				num_blks = roundup_pow_of_two(num_blks);
+
+			if (mdata->smp_mb_per_pipe &&
+				(num_blks > mdata->smp_mb_per_pipe) &&
+				!(pipe->flags & MDP_FLIP_LR))
+				num_blks = mdata->smp_mb_per_pipe;
 		}
 
 		pr_debug("reserving %d mmb for pnum=%d plane=%d\n",
 				num_blks, pipe->num, i);
-		reserved = mdss_mdp_smp_mmb_reserve(&pipe->smp[i],
-			&pipe->smp_reserved[i], num_blks);
-
+		reserved = mdss_mdp_smp_mmb_reserve(pipe->smp_map[i].allocated,
+			pipe->smp_map[i].reserved, num_blks);
 		if (reserved < num_blks)
 			break;
 	}
@@ -207,7 +211,8 @@
 	if (reserved < num_blks) {
 		pr_debug("insufficient MMB blocks\n");
 		for (; i >= 0; i--)
-			mdss_mdp_smp_mmb_free(&pipe->smp_reserved[i], false);
+			mdss_mdp_smp_mmb_free(pipe->smp_map[i].reserved,
+				false);
 		rc = -ENOMEM;
 	}
 	mutex_unlock(&mdss_mdp_smp_lock);
@@ -222,8 +227,10 @@
 
 	mutex_lock(&mdss_mdp_smp_lock);
 	for (i = 0; i < MAX_PLANES; i++) {
-		mdss_mdp_smp_mmb_amend(&pipe->smp[i], &pipe->smp_reserved[i]);
-		cnt += mdss_mdp_smp_mmb_set(pipe->ftch_id + i, &pipe->smp[i]);
+		mdss_mdp_smp_mmb_amend(pipe->smp_map[i].allocated,
+			pipe->smp_map[i].reserved);
+		cnt += mdss_mdp_smp_mmb_set(pipe->ftch_id + i,
+			pipe->smp_map[i].allocated);
 	}
 	mdss_mdp_smp_set_wm_levels(pipe, cnt);
 	mutex_unlock(&mdss_mdp_smp_lock);
diff --git a/include/linux/input/mpu3050.h b/include/linux/input/mpu3050.h
index 61a2920..f87dfe3 100644
--- a/include/linux/input/mpu3050.h
+++ b/include/linux/input/mpu3050.h
@@ -25,6 +25,7 @@
 	int (*power_off)(void);
 
 	int gpio_int;
+	int gpio_en;
 	int gpio_fsync;
 };
 
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index f548721..e3ff5db 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -99,8 +99,8 @@
  */
 
 	unsigned int		cmd_timeout_ms;	/* in milliseconds */
-	/* Set this flag only for blocking bkops request */
-	bool			bkops_busy;
+	/* Set this flag only for commands which can be HPIed */
+	bool			ignore_timeout;
 
 	struct mmc_data		*data;		/* data segment associated with cmd */
 	struct mmc_request	*mrq;		/* associated request */
@@ -162,6 +162,8 @@
 extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool,
 			bool);
 extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int);
+extern int mmc_switch_ignore_timeout(struct mmc_card *, u8, u8, u8,
+				     unsigned int);
 extern int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd);
 
 #define MMC_ERASE_ARG		0x00000000
diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h
index 72474e1..9fd5ec5 100644
--- a/include/linux/pinctrl/pinconf-generic.h
+++ b/include/linux/pinctrl/pinconf-generic.h
@@ -29,12 +29,21 @@
  *	if for example some other pin is going to drive the signal connected
  *	to it for a while. Pins used for input are usually always high
  *	impedance.
+ * @PIN_CONFIG_BIAS_BUS_HOLD: the pin will be set to weakly latch so that it
+ *	weakly drives the last value on a tristate bus, also known as a "bus
+ *	holder", "bus keeper" or "repeater". This allows another device on the
+ *	bus to change the value by driving the bus high or low and switching to
+ *	tristate. The argument is ignored.
  * @PIN_CONFIG_BIAS_PULL_UP: the pin will be pulled up (usually with high
  *	impedance to VDD). If the argument is != 0 pull-up is enabled,
  *	if it is 0, pull-up is disabled.
  * @PIN_CONFIG_BIAS_PULL_DOWN: the pin will be pulled down (usually with high
  *	impedance to GROUND). If the argument is != 0 pull-down is enabled,
  *	if it is 0, pull-down is disabled.
+ * @PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: the pin will be pulled up or down based
+ *	on embedded knowledge of the controller, like current mux function.
+ *	If the argument is != 0 pull up/down is enabled, if it is 0,
+ *	the pull is disabled.
  * @PIN_CONFIG_DRIVE_PUSH_PULL: the pin will be driven actively high and
  *	low, this is the most typical case and is typically achieved with two
  *	active transistors on the output. Sending this config will enabale
@@ -78,8 +87,10 @@
 enum pin_config_param {
 	PIN_CONFIG_BIAS_DISABLE,
 	PIN_CONFIG_BIAS_HIGH_IMPEDANCE,
+	PIN_CONFIG_BIAS_BUS_HOLD,
 	PIN_CONFIG_BIAS_PULL_UP,
 	PIN_CONFIG_BIAS_PULL_DOWN,
+	PIN_CONFIG_BIAS_PULL_PIN_DEFAULT,
 	PIN_CONFIG_DRIVE_PUSH_PULL,
 	PIN_CONFIG_DRIVE_OPEN_DRAIN,
 	PIN_CONFIG_DRIVE_OPEN_SOURCE,
diff --git a/include/linux/usb/Kbuild b/include/linux/usb/Kbuild
index b607f35..087d163 100644
--- a/include/linux/usb/Kbuild
+++ b/include/linux/usb/Kbuild
@@ -5,6 +5,7 @@
 header-y += functionfs.h
 header-y += gadgetfs.h
 header-y += midi.h
+header-y += msm_ext_chg.h
 header-y += g_printer.h
 header-y += tmc.h
 header-y += video.h
diff --git a/include/linux/usb/msm_ext_chg.h b/include/linux/usb/msm_ext_chg.h
new file mode 100644
index 0000000..dcc786d
--- /dev/null
+++ b/include/linux/usb/msm_ext_chg.h
@@ -0,0 +1,31 @@
+#ifndef __LINUX_USB_MSM_EXT_CHG_H
+#define __LINUX_USB_MSM_EXT_CHG_H
+
+#include <linux/ioctl.h>
+
+#define USB_CHG_BLOCK_ULPI	1
+#define USB_CHG_BLOCK_QSCRATCH	2
+
+/**
+ * struct msm_usb_chg_info - MSM USB charger block details.
+ * @chg_block_type: The type of charger block. QSCRATCH/ULPI.
+ * @page_offset: USB charger register base may not be aligned to
+ *              PAGE_SIZE.  The kernel driver aligns the base
+ *              address and use it for memory mapping.  This
+ *              page_offset is used by user space to calaculate
+ *              the corret charger register base address.
+ * @length: The length of the charger register address space.
+ */
+struct msm_usb_chg_info {
+	uint32_t chg_block_type;
+	off_t page_offset;
+	size_t length;
+};
+
+/* Get the MSM USB charger block information */
+#define MSM_USB_EXT_CHG_INFO _IOW('M', 0, struct msm_usb_chg_info)
+
+/* Vote against USB hardware low power mode */
+#define MSM_USB_EXT_CHG_BLOCK_LPM _IOW('M', 1, int)
+
+#endif /* __LINUX_USB_MSM_EXT_CHG_H */
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
index ea7a203..41f8607 100644
--- a/include/trace/events/sched.h
+++ b/include/trace/events/sched.h
@@ -51,6 +51,44 @@
 );
 
 /*
+ * Tracepoint for task enqueue/dequeue:
+ */
+TRACE_EVENT(sched_enq_deq_task,
+
+	TP_PROTO(struct task_struct *p, int enqueue),
+
+	TP_ARGS(p, enqueue),
+
+	TP_STRUCT__entry(
+		__array(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	pid			)
+		__field(	int,	prio			)
+		__field(	int,	cpu			)
+		__field(	int,	enqueue			)
+		__field(unsigned int,	nr_running		)
+		__field(unsigned long,	cpu_load		)
+		__field(unsigned int,	rt_nr_running		)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+		__entry->pid		= p->pid;
+		__entry->prio		= p->prio;
+		__entry->cpu		= task_cpu(p);
+		__entry->enqueue	= enqueue;
+		__entry->nr_running	= task_rq(p)->nr_running;
+		__entry->cpu_load	= task_rq(p)->cpu_load[0];
+		__entry->rt_nr_running	= task_rq(p)->rt.rt_nr_running;
+	),
+
+	TP_printk("cpu=%d %s comm=%s pid=%d prio=%d nr_running=%u cpu_load=%lu rt_nr_running=%u",
+			__entry->cpu, __entry->enqueue ? "enqueue" : "dequeue",
+			__entry->comm, __entry->pid,
+			__entry->prio, __entry->nr_running,
+			__entry->cpu_load, __entry->rt_nr_running)
+);
+
+/*
  * Tracepoint for waking up a task:
  */
 DECLARE_EVENT_CLASS(sched_wakeup_template,
@@ -179,6 +217,31 @@
 		  __entry->orig_cpu, __entry->dest_cpu)
 );
 
+/*
+ * Tracepoint for a CPU going offline/online:
+ */
+TRACE_EVENT(sched_cpu_hotplug,
+
+	TP_PROTO(int affected_cpu, int error, int status),
+
+	TP_ARGS(affected_cpu, error, status),
+
+	TP_STRUCT__entry(
+		__field(	int,	affected_cpu		)
+		__field(	int,	error			)
+		__field(	int,	status			)
+	),
+
+	TP_fast_assign(
+		__entry->affected_cpu	= affected_cpu;
+		__entry->error		= error;
+		__entry->status		= status;
+	),
+
+	TP_printk("cpu %d %s error=%d", __entry->affected_cpu,
+		__entry->status ? "online" : "offline", __entry->error)
+);
+
 DECLARE_EVENT_CLASS(sched_process_template,
 
 	TP_PROTO(struct task_struct *p),
diff --git a/kernel/cpu.c b/kernel/cpu.c
index fb4a5ac..d5ab2e6 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -17,6 +17,8 @@
 #include <linux/gfp.h>
 #include <linux/suspend.h>
 
+#include <trace/events/sched.h>
+
 #ifdef CONFIG_SMP
 /* Serializes the updates to cpu_online_mask, cpu_present_mask */
 static DEFINE_MUTEX(cpu_add_remove_lock);
@@ -264,6 +266,7 @@
 
 out_release:
 	cpu_hotplug_done();
+	trace_sched_cpu_hotplug(cpu, err, 0);
 	if (!err)
 		cpu_notify_nofail(CPU_POST_DEAD | mod, hcpu);
 	return err;
@@ -321,6 +324,7 @@
 	if (ret != 0)
 		__cpu_notify(CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL);
 	cpu_hotplug_done();
+	trace_sched_cpu_hotplug(cpu, ret, 1);
 
 	return ret;
 }
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 3513fef..d9c4b64 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -727,6 +727,7 @@
 	update_rq_clock(rq);
 	sched_info_queued(p);
 	p->sched_class->enqueue_task(rq, p, flags);
+	trace_sched_enq_deq_task(p, 1);
 }
 
 static void dequeue_task(struct rq *rq, struct task_struct *p, int flags)
@@ -734,6 +735,7 @@
 	update_rq_clock(rq);
 	sched_info_dequeued(p);
 	p->sched_class->dequeue_task(rq, p, flags);
+	trace_sched_enq_deq_task(p, 0);
 }
 
 void activate_task(struct rq *rq, struct task_struct *p, int flags)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 68fd9d7..1dee449 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3031,10 +3031,10 @@
 	params.listen_interval =
 		nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
 
-	if (info->attrs[NL80211_ATTR_STA_AID])
-		params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
-	else
+	if (info->attrs[NL80211_ATTR_PEER_AID])
 		params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
+	else
+		params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
 	if (!params.aid || params.aid > IEEE80211_MAX_AID)
 		return -EINVAL;
 
@@ -3104,7 +3104,8 @@
 			params.sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
 		}
 		/* TDLS peers cannot be added */
-		if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
+		if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
+		    info->attrs[NL80211_ATTR_PEER_AID])
 			return -EINVAL;
 		/* but don't bother the driver with it */
 		params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
@@ -3116,7 +3117,8 @@
 		break;
 	case NL80211_IFTYPE_MESH_POINT:
 		/* TDLS peers cannot be added */
-		if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
+		if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
+		    info->attrs[NL80211_ATTR_PEER_AID])
 			return -EINVAL;
 		break;
 	case NL80211_IFTYPE_STATION:
diff --git a/sound/soc/codecs/msm8x10-wcd.c b/sound/soc/codecs/msm8x10-wcd.c
index 53cfb3e..de0b4da 100644
--- a/sound/soc/codecs/msm8x10-wcd.c
+++ b/sound/soc/codecs/msm8x10-wcd.c
@@ -35,9 +35,11 @@
 #include <sound/soc-dapm.h>
 #include <sound/tlv.h>
 #include <mach/qdsp6v2/apr.h>
+#include <mach/subsystem_notif.h>
 #include "msm8x10-wcd.h"
 #include "wcd9xxx-resmgr.h"
 #include "msm8x10_wcd_registers.h"
+#include "../msm/qdsp6v2/q6core.h"
 
 #define MSM8X10_WCD_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
 			SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000)
@@ -186,6 +188,11 @@
 
 struct msm8x10_wcd_i2c msm8x10_wcd_modules[MAX_MSM8X10_WCD_DEVICE];
 
+static void *adsp_state_notifier;
+
+static struct snd_soc_codec *registered_codec;
+#define ADSP_STATE_READY_TIMEOUT_MS 2000
+
 
 static int get_i2c_msm8x10_wcd_device_info(u16 reg,
 					   struct msm8x10_wcd_i2c **msm8x10_wcd)
@@ -2549,6 +2556,53 @@
 	return NULL;
 }
 
+static int msm8x10_wcd_device_up(struct snd_soc_codec *codec)
+{
+	pr_debug("%s: device up!\n", __func__);
+
+	mutex_lock(&codec->mutex);
+
+	msm8x10_wcd_bringup(codec);
+	msm8x10_wcd_codec_init_reg(codec);
+	msm8x10_wcd_update_reg_defaults(codec);
+
+	mutex_unlock(&codec->mutex);
+
+	return 0;
+}
+
+static int adsp_state_callback(struct notifier_block *nb, unsigned long value,
+			       void *priv)
+{
+	bool timedout;
+	unsigned long timeout;
+
+	if (value == SUBSYS_AFTER_POWERUP) {
+		pr_debug("%s: ADSP is about to power up. bring up codec\n",
+			 __func__);
+
+		timeout = jiffies +
+			  msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS);
+		while (!(timedout = time_after(jiffies, timeout))) {
+			if (!q6core_is_adsp_ready()) {
+				pr_debug("%s: ADSP isn't ready\n", __func__);
+			} else {
+				pr_debug("%s: ADSP is ready\n", __func__);
+				msm8x10_wcd_device_up(registered_codec);
+				break;
+			}
+		}
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block adsp_state_notifier_block = {
+	.notifier_call = adsp_state_callback,
+	.priority = -INT_MAX,
+};
+
+
 static int msm8x10_wcd_codec_probe(struct snd_soc_codec *codec)
 {
 	struct msm8x10_wcd_priv *msm8x10_wcd;
@@ -2591,6 +2645,16 @@
 	msm8x10_wcd->mbhc_polling_active = false;
 	mutex_init(&msm8x10_wcd->codec_resource_lock);
 
+	registered_codec = codec;
+	adsp_state_notifier =
+	    subsys_notif_register_notifier("adsp",
+					   &adsp_state_notifier_block);
+	if (!adsp_state_notifier) {
+		pr_err("%s: Failed to register adsp state notifier\n",
+		       __func__);
+		registered_codec = NULL;
+		return -ENOMEM;
+	}
 	return 0;
 }
 
diff --git a/sound/soc/msm/msm8226.c b/sound/soc/msm/msm8226.c
index 043a998..d3ba3d5 100644
--- a/sound/soc/msm/msm8226.c
+++ b/sound/soc/msm/msm8226.c
@@ -36,12 +36,20 @@
 #define BTSCO_RATE_8KHZ 8000
 #define BTSCO_RATE_16KHZ 16000
 
+/* It takes about 13ms for Class-D PAs to ramp-up */
+#define EXT_CLASS_D_EN_DELAY 13000
+#define EXT_CLASS_D_DIS_DELAY 3000
+#define EXT_CLASS_D_DELAY_DELTA 2000
+
 #define WCD9XXX_MBHC_DEF_BUTTONS 8
 #define WCD9XXX_MBHC_DEF_RLOADS 5
 #define TAPAN_EXT_CLK_RATE 9600000
 
 #define NUM_OF_AUXPCM_GPIOS 4
 
+#define LO_1_SPK_AMP   0x1
+#define LO_2_SPK_AMP   0x2
+
 static int msm8226_auxpcm_rate = 8000;
 static atomic_t auxpcm_rsc_ref;
 static const char *const auxpcm_rate_text[] = {"rate_8000", "rate_16000"};
@@ -116,6 +124,7 @@
 	SLIM_4_TX_1 = 150, /* In-call musid delivery TX */
 };
 
+static int msm8226_ext_spk_pamp;
 static int msm_slim_0_rx_ch = 1;
 static int msm_slim_0_tx_ch = 1;
 
@@ -125,6 +134,7 @@
 static struct mutex cdc_mclk_mutex;
 static struct clk *codec_clk;
 static int clk_users;
+static int ext_spk_amp_gpio = -1;
 static int vdd_spkr_gpio = -1;
 static int msm_proxy_rx_ch = 2;
 
@@ -189,6 +199,99 @@
 	return 0;
 }
 
+static void msm8226_ext_spk_power_amp_enable(u32 enable)
+{
+	if (enable) {
+		gpio_direction_output(ext_spk_amp_gpio, enable);
+		/* time takes enable the external power amplifier */
+		usleep_range(EXT_CLASS_D_EN_DELAY,
+			EXT_CLASS_D_EN_DELAY + EXT_CLASS_D_DELAY_DELTA);
+	} else {
+		gpio_direction_output(ext_spk_amp_gpio, enable);
+		/* time takes disable the external power amplifier */
+		usleep_range(EXT_CLASS_D_DIS_DELAY,
+			EXT_CLASS_D_DIS_DELAY + EXT_CLASS_D_DELAY_DELTA);
+	}
+
+	pr_debug("%s: %s external speaker PAs.\n", __func__,
+		enable ? "Enable" : "Disable");
+}
+
+static void msm8226_ext_spk_power_amp_on(u32 spk)
+{
+	if (gpio_is_valid(ext_spk_amp_gpio)) {
+		if (spk & (LO_1_SPK_AMP | LO_2_SPK_AMP)) {
+			pr_debug("%s:Enable left and right speakers case spk = 0x%x\n",
+				__func__, spk);
+
+			msm8226_ext_spk_pamp |= spk;
+
+			if ((msm8226_ext_spk_pamp & LO_1_SPK_AMP) &&
+				(msm8226_ext_spk_pamp & LO_2_SPK_AMP))
+				if (ext_spk_amp_gpio >= 0) {
+					pr_debug("%s  enable power", __func__);
+					msm8226_ext_spk_power_amp_enable(1);
+				}
+		} else  {
+			pr_err("%s: Invalid external speaker ampl. spk = 0x%x\n",
+				__func__, spk);
+		}
+	}
+}
+
+static void msm8226_ext_spk_power_amp_off(u32 spk)
+{
+	if (gpio_is_valid(ext_spk_amp_gpio)) {
+		if (spk & (LO_1_SPK_AMP | LO_2_SPK_AMP)) {
+			pr_debug("%s Disable left and right speakers case spk = 0x%08x",
+				__func__, spk);
+
+			msm8226_ext_spk_pamp &= ~spk;
+
+			if (!msm8226_ext_spk_pamp) {
+				if (ext_spk_amp_gpio >= 0) {
+					pr_debug("%s  disable power", __func__);
+					msm8226_ext_spk_power_amp_enable(0);
+				}
+				msm8226_ext_spk_pamp = 0;
+			}
+		 } else  {
+			pr_err("%s: ERROR : Invalid Ext Spk Ampl. spk = 0x%08x\n",
+				__func__, spk);
+		}
+	}
+}
+
+static int msm8226_ext_spkramp_event(struct snd_soc_dapm_widget *w,
+			struct snd_kcontrol *k, int event)
+{
+	pr_debug("%s()\n", __func__);
+
+	if (SND_SOC_DAPM_EVENT_ON(event)) {
+		if (!strncmp(w->name, "Lineout_1 amp", 14))
+			msm8226_ext_spk_power_amp_on(LO_1_SPK_AMP);
+		else if (!strncmp(w->name, "Lineout_2 amp", 14))
+			msm8226_ext_spk_power_amp_on(LO_2_SPK_AMP);
+		else {
+			pr_err("%s() Invalid Speaker Widget = %s\n",
+				__func__, w->name);
+			return -EINVAL;
+		}
+	} else {
+		if (!strncmp(w->name, "Lineout_1 amp", 14))
+			msm8226_ext_spk_power_amp_off(LO_1_SPK_AMP);
+		else if (!strncmp(w->name, "Lineout_2 amp", 14))
+			msm8226_ext_spk_power_amp_off(LO_2_SPK_AMP);
+		else {
+			pr_err("%s() Invalid Speaker Widget = %s\n",
+				__func__, w->name);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 static int msm8226_vdd_spkr_event(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *kcontrol, int event)
 {
@@ -230,6 +333,9 @@
 	SND_SOC_DAPM_MIC("Digital Mic5", NULL),
 	SND_SOC_DAPM_MIC("Digital Mic6", NULL),
 
+	SND_SOC_DAPM_SPK("Lineout_1 amp", msm8226_ext_spkramp_event),
+	SND_SOC_DAPM_SPK("Lineout_2 amp", msm8226_ext_spkramp_event),
+
 	SND_SOC_DAPM_SUPPLY("EXT_VDD_SPKR",  SND_SOC_NOPM, 0, 0,
 	msm8226_vdd_spkr_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 };
@@ -1437,7 +1543,7 @@
 	pdata->us_euro_gpio = of_get_named_gpio(pdev->dev.of_node,
 				"qcom,cdc-us-euro-gpios", 0);
 	if (pdata->us_euro_gpio < 0) {
-		dev_info(&pdev->dev,
+		dev_dbg(&pdev->dev,
 			"property %s in node %s not found %d\n",
 			"qcom,cdc-us-euro-gpios", pdev->dev.of_node->full_name,
 			pdata->us_euro_gpio);
@@ -1527,7 +1633,7 @@
 	vdd_spkr_gpio = of_get_named_gpio(pdev->dev.of_node,
 				"qcom,cdc-vdd-spkr-gpios", 0);
 	if (vdd_spkr_gpio < 0) {
-		dev_err(&pdev->dev,
+		dev_dbg(&pdev->dev,
 			"Looking up %s property in node %s failed %d\n",
 			"qcom, cdc-vdd-spkr-gpios",
 			pdev->dev.of_node->full_name, vdd_spkr_gpio);
@@ -1542,19 +1648,38 @@
 		}
 	}
 
+	ext_spk_amp_gpio = of_get_named_gpio(pdev->dev.of_node,
+			"qcom,cdc-lineout-spkr-gpios", 0);
+	if (ext_spk_amp_gpio < 0) {
+		dev_err(&pdev->dev,
+			"Looking up %s property in node %s failed %d\n",
+			"qcom, cdc-lineout-spkr-gpios",
+			pdev->dev.of_node->full_name, ext_spk_amp_gpio);
+	} else {
+		ret = gpio_request(ext_spk_amp_gpio,
+				"TAPAN_CODEC_LINEOUT_SPKR");
+		if (ret) {
+			/* GPIO to enable EXT AMP exists, but failed request */
+			dev_err(card->dev,
+				"%s: Failed to request tapan amp spkr gpio %d\n",
+				__func__, ext_spk_amp_gpio);
+			goto err_vdd_spkr;
+		}
+	}
+
 	mbhc_cfg.gpio_level_insert = of_property_read_bool(pdev->dev.of_node,
 					"qcom,headset-jack-type-NO");
 	msm8226_setup_hs_jack(pdev, pdata);
 
 	ret = msm8226_prepare_codec_mclk(card);
 	if (ret)
-		goto err_vdd_spkr;
+		goto err_lineout_spkr;
 
 	ret = snd_soc_register_card(card);
 	if (ret) {
 		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
 			ret);
-		goto err_vdd_spkr;
+		goto err_lineout_spkr;
 	}
 	mutex_init(&cdc_mclk_mutex);
 
@@ -1564,7 +1689,7 @@
 		dev_err(&pdev->dev, "Looking up %s property in node %s failed",
 			"qcom,prim-auxpcm-gpio-set",
 			pdev->dev.of_node->full_name);
-		goto err_vdd_spkr;
+		goto err_lineout_spkr;
 	}
 	if (!strcmp(auxpcm_pri_gpio_set, "prim-gpio-prim")) {
 		lpaif_pri_muxsel_virt_addr = ioremap(LPAIF_PRI_MODE_MUXSEL, 4);
@@ -1574,16 +1699,22 @@
 		dev_err(&pdev->dev, "Invalid value %s for AUXPCM GPIO set\n",
 			auxpcm_pri_gpio_set);
 		ret = -EINVAL;
-		goto err_vdd_spkr;
+		goto err_lineout_spkr;
 	}
 	if (lpaif_pri_muxsel_virt_addr == NULL) {
 		pr_err("%s Pri muxsel virt addr is null\n", __func__);
 		ret = -EINVAL;
-		goto err_vdd_spkr;
+		goto err_lineout_spkr;
 	}
 
 	return 0;
 
+err_lineout_spkr:
+	if (ext_spk_amp_gpio >= 0) {
+		gpio_free(ext_spk_amp_gpio);
+		ext_spk_amp_gpio = -1;
+	}
+
 err_vdd_spkr:
 	if (vdd_spkr_gpio >= 0) {
 		gpio_free(vdd_spkr_gpio);
@@ -1607,11 +1738,15 @@
 	struct msm8226_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
 
 	gpio_free(pdata->mclk_gpio);
-	gpio_free(vdd_spkr_gpio);
+	if (vdd_spkr_gpio >= 0)
+		gpio_free(vdd_spkr_gpio);
+	if (ext_spk_amp_gpio >= 0)
+		gpio_free(ext_spk_amp_gpio);
 	if (pdata->us_euro_gpio > 0)
 		gpio_free(pdata->us_euro_gpio);
 
 	vdd_spkr_gpio = -1;
+	ext_spk_amp_gpio = -1;
 	snd_soc_unregister_card(card);
 
 	return 0;