Merge "input: sensor: cm36283: Remove earlysuspend code"
diff --git a/Documentation/csdio.txt b/Documentation/csdio.txt
deleted file mode 100644
index 22d5e35..0000000
--- a/Documentation/csdio.txt
+++ /dev/null
@@ -1,189 +0,0 @@
-Introduction
-============
-The Char SDIO Device Driver is an interface which exposes an SDIO
-card/function from kernel space as a char device in user space.
-
-The driver doesn't interact with any HW directly. It relies on SDIO
-card/function interface provided as a part of Linux kernel.
-
-Hardware description
-====================
-Each SDIO device/card contains an SDIO client HW block.
-The host interacts with the device by sending byte sequences called
-command (CMD). Some commands can be followed by data blocks. The
-device sends back a byte sequence called response (R) and a data
-block if required. CMD3, CMD5 and CMD7 are used to initialize the
-device. CMD52 and CMD53 are used to access the device. Command
-format and properties are defined by SDIO Specification document
-published by SD Association:
-    http://www.sdcard.org/developers/tech/sdio/.
-
-CMD52 and CMD53 can access up to 8 address spaces called Functions.
-Function 0 contains system information predefined by SD/SDIO
-standard and Functions 1-7 are defined by the SDIO device
-manufacturer.
-
-An SDIO device/card can send an interrupt to SDIO host. This
-interrupt is intercepted and handled by SDIO host.
-
-Software description
-====================
-Linux provides a framework for handling SDIO devices. It implements
-kind of plug-and-play model in which the Linux SDIO Host Driver is
-responsible for initializing an SDIO device upon insertion. It also
-reads device/card identification information and enumerates functions
-provided by the device and then looks up in the list of
-preregistered user SDIO drivers for a suitable one.
-
-During its lifecycle the user SDIO driver interacts with the Linux
-SDIO Host Driver in order to send/receive information to/from SDIO
-device/card. The user SDIO driver doesn't work with CMD52/CMD53
-directly. Instead it uses an abstraction provided by the Linux SDIO
-Host Driver.
-
-The Linux SDIO Host Driver is also in charge of handling SDIO
-interrupts. User SDIO driver can register its own callback in SDIO
-Host Driver and get a notification about interrupt event.
-
-The Char SDIO Device Driver follows the design guidelines mentioned
-above. It provides the following functionality:
-
- - Register itself in the user SDIO drivers list;
- - Handle Probe event upon insertion of supported card/device;
- - Creates and maintains a char device driver for each SDIO Function
-   found in the card/device;
- - Translates read/write/ioctl calls to appropriate SDIO call
-   sequences;
-
-In order to handle general SDIO configuration functionality and
-Function 0 the Char SDIO Device Driver provides additional
-simplified char device driver.
-
-The Manufacturer and Device IDs of handled SDIO device should be
-provided as parameters for kernel module or as configuration
-parameters in case of statically linked driver.
-
-Design
-======
-The main goal of the Char SDIO Device Driver is to expose an SDIO
-card/device from kernel space to user space as a char device driver.
-The driver should be generic and simple as far as possible.
-
-The biggest design tradeoff is maintaining a balance between the
-system call overhead required to initiate an SDIO transaction from
-user space and overall SDIO communication performance. But luckily,
-because of nature of SDIO protocol, this overhead is negligible
-comparing to time required to execute SDIO transaction itself. So,
-each CMD52 (read or write) consists from single ioctl system call.
-And each CMD53 invokes single ioctl system call followed by read or
-write system call.
-
-The Char SDIO Device Driver registers its own class of the devices
-called 'csdio'. This class will serve as a common roof for all SDIO
-devices served by different instances of the Char SDIO Device Driver.
-Additional benefit from maintaining its own class is the driver
-ability to overwrite default permissions of the dev nodes created by
-the driver.
-
-Power Management
-================
-None
-
-SMP/multi-core
-==============
-The driver does not anticipate any issues related to multi-core
-since it is expected to run on one core only.
-
-Security
-========
-None
-
-Performance
-===========
-None
-
-Interface
-=========
-The Char SDIO Device Driver has two char device interfaces:
- - Control Interface;
- - Function Interface.
-
-Char SDIO Device Driver Control Interface consists of:
- - open()   - device node is /dev/csdio0;
- - close()
- - ioctl()  - the following options are available:
-   - CSDIO_IOC_ENABLE_HIGHSPEED_MODE;
-   - CSDIO_IOC_SET_DATA_TRANSFER_CLOCKS;
-   - CSDIO_IOC_ENABLE_ISR;
-   - CSDIO_IOC_DISABLE_ISR.
-
-Char SDIO Device Driver Function Interface consists of:
- - open()  - device node is /dev/csdiofX, where X is Function Id;
- - close()
- - read()  - send CMD53 read;
- - write() - send CMD53 write;
- - ioctl() - the following options are available:
-   - CSDIO_IOC_SET_OP_CODE - 0 fixed adrress, 1 autoincrement.
-   - CSDIO_IOC_FUNCTION_SET_BLOCK_SIZE;
-   - CSDIO_IOC_SET_BLOCK_MODE - 0 byte mode, 1 block mode;
-   - CSDIO_IOC_CMD52 - execute CMD52, receives the
-        following structure as a parameter:
-            struct csdio_cmd52_ctrl_t {
-	            uint32_t    m_write; // 0 - read, 1 -write
-	            uint32_t    m_address;
-	            uint32_t    m_data;  // data to write or read data
-	            uint32_t    m_ret;   // command execution status
-            }__attribute__ ((packed));
-   - CSDIO_IOC_CMD53 - setup CMD53 data transfer, receives the
-        following structure as a parameter:
-            struct csdio_cmd53_ctrl_t {
-	            uint32_t    m_block_mode;
-	            uint32_t    m_op_code;
-	            uint32_t    m_address;
-            }__attribute__ ((packed));
-   - CSDIO_IOC_CONNECT_ISR;
-   - CSDIO_IOC_DISCONNECT_ISR;
-   - CSDIO_IOC_GET_VDD;
-   - CSDIO_IOC_SET_VDD.
-
-Additionally, user space application can use fcntl system call with
-parameters F_SETOWN and F_SETFL in order to set an asynchronous
-callback for SDIO interrupt.
-
-Driver parameters
-=================
-If the driver is compiled as a kernel module, the following
-parameters can be used in order to provide Manufacturer and Device IDs
-upon module download:
- - csdio_vendor_id;
- - csdio_device_id.
-If the driver is intended to work with specific SDIO host the
-host_name parameter should be added followed by the name of the MMC
-host platform device.
-
-Config options
-==============
-These are the kernel configuration options:
- - CONFIG_CSDIO_VENDOR_ID;
- - CONFIG_CSDIO_DEVICE_ID.
-
-Dependencies
-============
-The Char SDIO Device Driver depends on Linux SDIO Host Driver.
-
-User space utilities
-====================
-None
-
-Other
-=====
-None
-
-Known issues
-============
-None
-
-To do
-=====
-Provide mechanism to support a number of SDIO devices simultaneously
-connected to different SDIO hosts.
diff --git a/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt b/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt
index a0b2f6d..99de826 100644
--- a/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt
+++ b/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt
@@ -11,7 +11,7 @@
 	bits to indicate what bin (and voltage range) a chip is in.
 
 Required properties:
-- compatible:			Must be "qcom,cpr-regulator"
+- compatible:			Must be "qti,cpr-regulator"
 - reg:				Register addresses for RBCPR, RBCPR clock
 				select, PVS and CPR eFuse address
 - reg-names:			Register names. Must be "rbcpr", "rbcpr_clk",
@@ -22,91 +22,106 @@
 				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,pvs-init-voltage:  	A list of integers whose length is equal to 2
-				to the power of qcom,pvs-fuse[num-of-bits]. The
+- qti,pvs-init-voltage:  	A list of integers whose length is equal to 2
+				to the power of qti,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 initial voltage
 				of the PVS bin in turbo mode in microvolts.
-- qcom,pvs-corner-ceiling-slow:	Ceiling voltages of all corners for APC_PVS_SLOW
-- qcom,pvs-corner-ceiling-nom:	Ceiling voltages of all corners for APC_PVS_NOM
-- qcom,pvs-corner-ceiling-fast:	Ceiling voltages of all corners for APC_PVS_FAST
+- qti,pvs-corner-ceiling-slow:	Ceiling voltages of all corners for APC_PVS_SLOW
+- qti,pvs-corner-ceiling-nom:	Ceiling voltages of all corners for APC_PVS_NOM
+- qti,pvs-corner-ceiling-fast:	Ceiling voltages of all corners for APC_PVS_FAST
 				The ceiling voltages for each of above three
 				properties may look like this:
 				  0 (SVS voltage):		1050000 uV
 				  1 (NORMAL voltage):		1150000 uV
 				  2 (TURBO voltage):		1275000 uV
 - vdd-apc-supply:		Regulator to supply VDD APC power
-- qcom,vdd-apc-step-up-limit:	Limit of vdd-apc-supply steps for scaling up.
-- qcom,vdd-apc-step-down-limit:	Limit of vdd-apc-supply steps for scaling down.
-- qcom,cpr-ref-clk:		The reference clock in kHz.
-- qcom,cpr-timer-delay:		The delay in microseconds for the timer interval.
-- qcom,cpr-timer-cons-up:	Consecutive number of timer interval (qcom,cpr-timer-delay)
+- qti,vdd-apc-step-up-limit:	Limit of vdd-apc-supply steps for scaling up.
+- qti,vdd-apc-step-down-limit:	Limit of vdd-apc-supply steps for scaling down.
+- qti,cpr-ref-clk:		The reference clock in kHz.
+- qti,cpr-timer-delay:		The delay in microseconds for the timer interval.
+- qti,cpr-timer-cons-up:	Consecutive number of timer interval (qti,cpr-timer-delay)
 				occurred before issuing UP interrupt.
-- qcom,cpr-timer-cons-down:	Consecutive number of timer interval (qcom,cpr-timer-delay)
+- qti,cpr-timer-cons-down:	Consecutive number of timer interval (qti,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 (Ring Oscillator(RO) count) per vdd-apc-supply step
+- qti,cpr-irq-line:		Internal interrupt route signal of RBCPR, one of 0, 1 or 2.
+- qti,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
+- qti,cpr-up-threshold:	The threshold for CPR to issue interrupt when
 				error_steps is greater than it when stepping up.
-- qcom,cpr-down-threshold:	The threshold for CPR to issue interrupt when
+- qti,cpr-down-threshold:	The threshold for CPR to issue interrupt when
 				error_steps is greater than it when stepping down.
-- qcom,cpr-idle-clocks:		Idle clock cycles RO can be in.
-- 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.
+- qti,cpr-idle-clocks:		Idle clock cycles RO can be in.
+- qti,cpr-gcnt-time:		The time for gate count in microseconds.
+- qti,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
+- qti,pvs-fuse-redun-sel:	Array of 5 elements to indicate where to read the bits, 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:
+				used instead of the original bits and method to read fuse row, reading
+				register through SCM or directly. The 5 elements with index [0..4] 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
+				  [4] => fuse reading method, 0 for direct reading or 1 for SCM reading
 				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:
+				Otherwise, the original PVS bits should be selected. If the 5th
+				element is 0, read the fuse row from register directly. Otherwise,
+				read it through SCM.
+- qti,pvs-fuse:			Array of 4 elements to indicate the bits for PVS fuse and read method.
+				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.
+				  [3] => fuse reading method, 0 for direct reading or 1 for SCM reading
+- qti,pvs-fuse-redun:		Array of 4 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
+				  [3] => fuse reading method, 0 for direct reading or 1 for SCM reading
+- qti,cpr-fuse-redun-sel:	Array of 5 elements to indicate where to read the bits, 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:
+				used instead of the original bits and method to read fuse row, using SCM
+				to read or read register directly. The 5 elements with index [0..4] 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
+				  [4] => fuse reading method, 0 for direct reading or 1 for SCM reading
 				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.
+				Otherwise, the original CPR bits should be selected. If the 5th element
+				is 0, read the fuse row from register directly. Otherwise, read it through
+				SCM.
+- qti,cpr-fuse-row:		Array of row number of CPR fuse and method to read that row. It should have
+				index and value like this:
+				 [0] => the fuse row number
+				 [1] => fuse reading method, 0 for direct reading or 1 for SCM reading
+- qti,cpr-fuse-bp-cpr-disable:	Bit position of the bit to indicate if CPR should be disable
+- qti,cpr-fuse-bp-scheme:	Bit position of the bit to indicate if it's a global/local scheme
+- qti,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.
+- qti,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.
+- qti,cpr-fuse-redun-row:	Array of row number of redundant CPR fuse and method to read that
+				row. It should have index and value like this:
+				 [0] => the redundant fuse row number
+				 [1] => the value to indicate reading the fuse row directly or using SCM
+- qti,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.
+- qti,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
@@ -116,30 +131,88 @@
 Optional properties:
 - vdd-mx-supply:		Regulator to supply memory power as dependency
 				of VDD APC.
-- qcom,vdd-mx-vmax:		The maximum voltage in uV for vdd-mx-supply. This
+- qti,vdd-mx-vmax:		The maximum voltage in uV for vdd-mx-supply. This
 				is required when vdd-mx-supply is present.
-- qcom,vdd-mx-vmin-method:	The method to determine the minimum voltage for
+- qti,vdd-mx-vmin-method:	The method to determine the minimum voltage for
 				vdd-mx-supply, which can be one of following
 				choices compared with VDD APC:
 				  0 => equal to the voltage(vmin) of VDD APC
 				  1 => equal to PVS corner ceiling voltage
 				  2 => equal to slow speed corner ceiling
-				  3 => equal to qcom,vdd-mx-vmax
+				  3 => equal to qti,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
+- qti,cpr-fuse-redun-bp-cpr-disable:	Redundant bit position of the bit to indicate if CPR should be disable
+- qti,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.
+- qti,cpr-enable:		Present: CPR enabled by default.
 				Not Present: CPR disable by default.
-- qcom,use-tz-api:		Present: CPR reads efuse parameters through trustzone API.
-				Not Present: CPR reads efuse parameters directly.
-
+- qti,cpr-fuse-cond-min-volt-sel:	Array of 5 elements to indicate where to read the bits,  what value to
+				compare with in order to decide if the conditional minimum apc voltage needs
+				to be applied and the fuse reading method.
+				The 5 elements with index[0..4] are:
+				[0] => the fuse row number;
+				[1] => LSB bit position of the bits;
+				[2] => number of the bits;
+				[3] => the expected data to read;
+				[4] => fuse reading method, 0 for direct reading or 1 for SCM reading;
+				When the value of the fuse bits specified by first 3 elements is not equal to
+				the value in 4th element, then set the apc voltage for all parts running
+				at each voltage corner to be not lower than the voltage defined
+				using "qti,cpr-cond-min-voltage".
+- qti,cpr-cond-min-voltage:	Minimum voltage in microvolts for SVS, NOM and TURBO mode if the fuse bits
+				defined in qti,cpr-fuse-cond-min-volt-sel have not been programmed with the
+				expected data. This is required if cpr-fuse-cond-min-volt-sel is present.
+- qti,cpr-fuse-uplift-sel: 	Array of 5 elements to indicate where to read the bits, what value to
+				compare with in order to enable or disable the pvs voltage uplift workaround,
+				and the fuse reading method.
+				The 5 elements with index[0..4] are:
+				[0]: => the fuse row number of the selector;
+				[1]: => LSB bit position of the bits;
+				[2]: => number of the bits;
+				[3]: => the value to indicate if the apc pvs voltage uplift workaround will
+					be enabled;
+				[4]: => fuse reading method, 0 for direct reading or 1 for SCM reading.
+				When the value of the fuse bits specified by first 3 elements equals to the
+				value in 4th element, the pvs voltage uplift workaround will be enabled.
+- qti,speed-bin-fuse-sel:	Array of 4 elements to indicate where to read the speed bin of the processor,
+				and the fuse reading method.
+				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 the bits;
+				[3]: => fuse reading method, 0 for direct reading or 1 for SCM reading.
+				This is required if cpr-fuse-uplift-disable-sel is present.
+- qti,cpr-uplift-voltage:	Uplift in microvolts used for increasing pvs init voltage. If this property is present,
+				This is required if cpr-fuse-uplift-disable-sel is present.
+- qti,cpr-uplift-max-volt:	Maximum voltage in microvolts used for pvs voltage uplift workaround to limit
+				the maximum pvs voltage.
+				This is required if cpr-fuse-uplift-disable-sel is present.
+- qti,cpr-uplift-quotient:	Three numbers used for pvs voltage uplift workaround to be added to the target
+				quotient for each corner.
+				The 3 quotient increment with index[0..2] are:
+				[0]: => for SVS corner target quotient;
+				[1]: => for NORM corner target quotient;
+				[2]: => for TURBO corner target quotient;
+				This is required if cpr-fuse-uplift-disable-sel is present.
+- qti,cpr-uplift-speed-bin:	The speed bin value corresponding to one type of processor which needs to apply the
+				pvs voltage uplift workaround.
+				This is required if cpr-fuse-uplift-disable-sel is present.
+- qti,cpr-quot-adjust-table:	Array of 4-tuples in which each 4-tuple indicates the speed bin
+				of the CPU, the frequency of the CPU, the quotient adjustment and the voltage corner to use.
+				The 4 elements in one 4-tuple are:
+				[0]: => the speed bin of the CPU;
+				[1]: => the frequency in kHz of the CPU;
+				[2]: => the quotient adjustment of the corresponding frequency;
+				[3]: => the voltage corner to use.
+				If the speed bin in a tuple is eqaul to the speed bin of the CPU, then the quotient
+				adjustment would be subtracted from the quotient value of the voltage corner
+				when the CPU is running at that frequency.
 
 Example:
 	apc_vreg_corner: regulator@f9018000 {
 		status = "okay";
-		compatible = "qcom,cpr-regulator";
+		compatible = "qti,cpr-regulator";
 		reg = <0xf9018000 0x1000>, <0xfc4b8000 0x1000>;
 		reg-names = "rbcpr", "efuse_addr";
 		interrupts = <0 15 0>;
@@ -147,11 +220,11 @@
 		regulator-min-microvolt = <1>;
 		regulator-max-microvolt = <3>;
 
-		qcom,pvs-fuse = <22 6 5>;
-		qcom,pvs-fuse-redun-sel = <22 24 3 2>;
-		qcom,pvs-fuse-redun = <22 27 5>;
+		qti,pvs-fuse = <22 6 5 1>;
+		qti,pvs-fuse-redun-sel = <22 24 3 2 1>;
+		qti,pvs-fuse-redun = <22 27 5 1>;
 
-		qcom,pvs-init-voltage = <1330000 1330000 1330000 1320000
+		qti,pvs-init-voltage = <1330000 1330000 1330000 1320000
 						1310000 1300000 1290000 1280000
 						1270000 1260000 1250000 1240000
 						1230000 1220000 1210000 1200000
@@ -159,35 +232,47 @@
 						1150000 1140000 1140000 1140000
 						1140000 1140000 1140000 1140000
 						1140000 1140000 1140000 1140000>;
-		qcom,pvs-corner-ceiling-slow = <1050000 1160000 1275000>;
-		qcom,pvs-corner-ceiling-nom  =  <975000 1075000 1200000>;
-		qcom,pvs-corner-ceiling-fast =  <900000 1000000 1140000>;
+		qti,pvs-corner-ceiling-slow = <1050000 1160000 1275000>;
+		qti,pvs-corner-ceiling-nom  =  <975000 1075000 1200000>;
+		qti,pvs-corner-ceiling-fast =  <900000 1000000 1140000>;
 		vdd-apc-supply = <&pm8226_s2>;
 		vdd-mx-supply = <&pm8226_l3_ao>;
-		qcom,vdd-mx-vmax = <1350000>;
-		qcom,vdd-mx-vmin-method = <1>;
-		qcom,vdd-apc-step-up-limit = <1>;
-		qcom,vdd-apc-step-down-limit = <1>;
-		qcom,cpr-ref-clk = <19200>;
-		qcom,cpr-timer-delay = <5000>;
-		qcom,cpr-timer-cons-up = <1>;
-		qcom,cpr-timer-cons-down = <2>;
-		qcom,cpr-irq-line = <0>;
-		qcom,cpr-step-quotient = <15>;
-		qcom,cpr-up-threshold = <1>;
-		qcom,cpr-down-threshold = <2>;
-		qcom,cpr-idle-clocks = <5>;
-		qcom,cpr-gcnt-time = <1>;
-		qcom,cpr-apc-volt-step = <5000>;
+		qti,vdd-mx-vmax = <1350000>;
+		qti,vdd-mx-vmin-method = <1>;
+		qti,vdd-apc-step-up-limit = <1>;
+		qti,vdd-apc-step-down-limit = <1>;
+		qti,cpr-ref-clk = <19200>;
+		qti,cpr-timer-delay = <5000>;
+		qti,cpr-timer-cons-up = <1>;
+		qti,cpr-timer-cons-down = <2>;
+		qti,cpr-irq-line = <0>;
+		qti,cpr-step-quotient = <15>;
+		qti,cpr-up-threshold = <1>;
+		qti,cpr-down-threshold = <2>;
+		qti,cpr-idle-clocks = <5>;
+		qti,cpr-gcnt-time = <1>;
+		qti,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>;
+		qti,cpr-fuse-row = <138 1>;
+		qti,cpr-fuse-bp-cpr-disable = <36>;
+		qti,cpr-fuse-bp-scheme = <37>;
+		qti,cpr-fuse-target-quot = <24 12 0>;
+		qti,cpr-fuse-ro-sel = <54 38 41>;
+		qti,cpr-fuse-redun-sel = <138 57 1 1 1>;
+		qti,cpr-fuse-redun-row = <139 1>;
+		qti,cpr-fuse-redun-target-quot = <24 12 0>;
+		qti,cpr-fuse-redun-ro-sel = <46 36 39>;
+		qti,cpr-fuse-cond-min-volt-sel = <54 42 6 7 1>;
+		qti,cpr-cond-min-voltage = <1140000>;
+		qti,cpr-fuse-uplift-sel = <22 53 1 0 0>;
+		qti,cpr-uplift-voltage = <50000>;
+		qti,cpr-uplift-quotient = <0 0 120>;
+		qti,cpr-uplift-max-volt = <1350000>;
+		qti,cpr-uplift-speed-bin = <1>;
+		qti,speed-bin-fuse-sel = <22 0 3 0>;
+		qti,cpr-quot-adjust-table = <1 998400 450 3>,
+				<1 1094400 375 3>, <1 1190400 300 3>,
+				<1 1305600 225 3>, <1 1344000 187 3>,
+				<1 1401600 150 3>, <1 1497600 75 3>;
 	};
 
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt b/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
index 3947f75..15b94ca 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
@@ -43,6 +43,29 @@
 - qcpm,cpu-sensors:     List of type names in thermal zone device struct which maps
 			to cpu0, cpu1, cpu2, cpu3 in sequence depending on how many
 			cpus there are.
+- qcom,freq-mitigation-temp: Threshold temperature to mitigate
+			the CPU max frequency in degC. This will be
+			used when polling based frequency control is disabled.
+			The difference between freq-mitigation-temp
+			and limit-temp is that limit-temp is used during
+			early boot prior to thermal_sys being available for registering
+			temperature thresholds. Also, this emergency frequency
+			mitigation is a single step frequency mitigation to a predefined value
+			as opposed to the step by step frequency mitigation during boot-up.
+- qcom,freq-mitigation-temp-hysteresis: Degrees C below which thermal will not mitigate the
+			cpu max frequency.
+- qcom,freq-mitigation-value: The frequency value (in kHz) to which the thermal
+			should mitigate the CPU, when the freq-mitigation-temp
+			threshold is reached.
+- qcom,freq-mitigation-control-mask: The frequency mitigation bitmask that will be
+			used to determine if KTM should do emergency frequency
+			mitigation for a core or not. A mask of 0x00 indicates the
+			mitigation is disabled for all the cores and a mask of 0x05
+			indicates this mitigation is enabled for cpu-0 and cpu-2.
+			Note: For KTM's frequency mitigation to work, the data for all the
+			above four properties (qcom,freq-mitigation-temp; qcom,
+			freq-mitigation-temp-hysteresis; qcom,freq-mitigation-value and
+			qcom,freq-mitigation-control-mask) should be populated.
 - qcom,vdd-restriction-temp: When temperature is below this threshold, will
 			enable vdd restriction which will set higher voltage on
 			key voltage rails, in degC.
@@ -67,6 +90,20 @@
 			phandle_of_regulator is defined by reuglator device tree.
 
 Optional child nodes
+- qti,pmic-opt-curr-temp: Threshold temperature for requesting optimum current (request
+			dual phase) for rails with PMIC, in degC. If this property exists,
+			then the properties, qti,pmic-opt-curr-temp-hysteresis and
+			qti,pmic-opt-curr-regs should also be defined to enable this
+			feature.
+- qti,pmic-opt-curr-temp-hysteresis: Degree below the threshold to disable the optimum
+			current request for a rail, in degC. If this property exists,
+			then the properties, qti,pmic-opt-curr-temp and
+			qti,pmic-opt-curr-regs should also be defined to enable
+			this feature.
+- qti,pmic-opt-curr-regs: Name of the rails for which the optimum current should be
+			requested. If this property exists, then the properties,
+			qti,pmic-opt-curr-temp and qti,pmic-opt-curr-temp-hysteresis
+			should also be defined to enable this feature.
 - qcom,<vdd restriction child node name>: Define the name of the child node.
 			If this property exisits, qcom,vdd-rstr-reg, qcom,levels
 			need to exist. qcom,min-level is optional if qcom,freq-req
@@ -97,11 +134,18 @@
 		qcom,hotplug-temp-hysteresis = <20>;
 		qcom,cpu-sensors = "tsens_tz_sensor5", "tsens_tz_sensor6",
 				"tsens_tz_sensor7", "tsens_tz_sensor8";
+		qcom,freq-mitigation-temp = <110>;
+		qcom,freq-mitigation-temp-hysteresis = <20>;
+		qcom,freq-mitigation-value = <960000>;
+		qcom,freq-mitigation-control-mask = <0x01>;
 		qcom,pmic-sw-mode-temp = <90>;
 		qcom,pmic-sw-mode-temp-hysteresis = <80>;
 		qcom,pmic-sw-mode-regs = "vdd-dig";
 		qcom,vdd-restriction-temp = <5>;
 		qcom,vdd-restriction-temp-hysteresis = <10>;
+		qti,pmic-opt-curr-temp = <85>;
+		qti,pmic-opt-curr-temp-hysteresis = <10>;
+		qti,pmic-opt-curr-regs = "vdd-dig";
 		vdd-dig-supply=<&pm8841_s2_floor_corner>
 
 		qcom,vdd-dig-rstr{
diff --git a/Documentation/devicetree/bindings/power/qpnp-charger.txt b/Documentation/devicetree/bindings/power/qpnp-charger.txt
index 584a76d..7d8fe0a 100644
--- a/Documentation/devicetree/bindings/power/qpnp-charger.txt
+++ b/Documentation/devicetree/bindings/power/qpnp-charger.txt
@@ -93,10 +93,16 @@
 					set, the charger ovp status is monitored in software.
 - qcom,ext-ovp-present			Indicates if an external OVP exists which reduces the
 					overall input resistance of the charge path.
+- qcom,ibat-calibration-enabled		Indicates if ibat calibration is enabled. This is
+					required for devices which have a ibat trim error
+					causing ibatmax to go out of spec.
 - qcom,power-stage-reduced		Indicates if power stage workaround is enabled. This work
 					around reduces the power stage segments while charging
 					under high load during low battery voltages. It's for
 					improving IADC accuracy while board has a bad layout.
+- qcom,use-external-rsense		A boolean that controls whether BMS will use
+					an external sensor resistor instead of the default
+					RDS of the batfet.
 
 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 56bdc59..a77b5ff 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -102,6 +102,12 @@
 
  - compatible : "qcom,msm-lsm-client"
 
+* msm-pcm-loopback
+
+Required properties:
+
+ - compatible : "qti,msm-pcm-loopback"
+
 * msm-dai-q6
 
 [First Level Nodes]
diff --git a/Makefile b/Makefile
index be32c2f..0c11d69 100644
--- a/Makefile
+++ b/Makefile
@@ -864,6 +864,7 @@
 # Generate .S file with all kernel symbols
 quiet_cmd_kallsyms = KSYM    $@
       cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) \
+                     --page-offset=$(CONFIG_PAGE_OFFSET) \
                      $(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@
 
 .tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE
diff --git a/arch/arm/boot/dts/apq8074-dragonboard.dtsi b/arch/arm/boot/dts/apq8074-dragonboard.dtsi
index 824b0ab..c7e24d9 100644
--- a/arch/arm/boot/dts/apq8074-dragonboard.dtsi
+++ b/arch/arm/boot/dts/apq8074-dragonboard.dtsi
@@ -13,6 +13,7 @@
 /include/ "dsi-panel-sharp-qhd-video.dtsi"
 /include/ "msm8974-camera-sensor-dragonboard.dtsi"
 /include/ "msm8974-leds.dtsi"
+/include/ "msm-rdbg.dtsi"
 
 &vph_pwr_vreg {
 	status = "ok";
diff --git a/arch/arm/boot/dts/batterydata-qrd-4v2-2200mah.dtsi b/arch/arm/boot/dts/batterydata-qrd-4v2-2200mah.dtsi
new file mode 100644
index 0000000..53aa781
--- /dev/null
+++ b/arch/arm/boot/dts/batterydata-qrd-4v2-2200mah.dtsi
@@ -0,0 +1,105 @@
+/* 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.
+ */
+
+qcom,qrd-4v2-2200mah-data {
+	qcom,default-rbatt-mohm = <163>;
+	qcom,max-voltage-uv = <4200>;
+	qcom,fcc-mah = <2200>;
+	qcom,rbatt-capacitive-mohm = <0>;
+	qcom,v-cutoff-uv = <3400000>;
+	qcom,chg-term-ua = <100000>;
+	qcom,batt-id-kohm = <10>;
+	qcom,flat-ocv-threshold-uv = <3800000>;
+
+	qcom,fcc-temp-lut {
+		qcom,lut-col-legend = <(-20) 0 25 40 60>;
+		qcom,lut-data = <2167 2179 2234 2178 2164>;
+	};
+
+	qcom,pc-temp-ocv-lut {
+		qcom,lut-col-legend = <(-20) 0 25 40 60>;
+		qcom,lut-row-legend = <100 95 90 85 80>,
+				<75 70 65 60 55>,
+				<50 45 40 35 30>,
+				<25 20 15 10 9>,
+				<8 7 6 5 4>,
+				<3 2 1 0>;
+		qcom,lut-data = <4188 4184 4199 4176 4170>,
+				<4109 4124 4145 4124 4118>,
+				<4051 4082 4097 4077 4072>,
+				<3963 4024 4055 4034 4029>,
+				<3920 3971 4002 3993 3989>,
+				<3880 3932 3963 3957 3952>,
+				<3846 3892 3920 3913 3910>,
+				<3822 3859 3881 3873 3871>,
+				<3805 3834 3851 3845 3844>,
+				<3790 3813 3828 3823 3822>,
+				<3777 3796 3808 3805 3803>,
+				<3764 3784 3792 3790 3788>,
+				<3750 3775 3778 3777 3774>,
+				<3736 3766 3766 3761 3751>,
+				<3721 3752 3755 3745 3732>,
+				<3704 3733 3737 3729 3716>,
+				<3684 3707 3713 3707 3694>,
+				<3655 3686 3688 3682 3672>,
+				<3598 3661 3677 3671 3659>,
+				<3585 3655 3673 3669 3656>,
+				<3571 3644 3664 3663 3650>,
+				<3551 3626 3643 3648 3631>,
+				<3523 3598 3609 3618 3600>,
+				<3489 3561 3565 3578 3561>,
+				<3445 3514 3510 3529 3512>,
+				<3389 3453 3440 3468 3450>,
+				<3313 3372 3345 3386 3366>,
+				<3207 3252 3209 3262 3239>,
+				<3000 3000 3000 3000 3000>;
+	};
+
+	qcom,rbatt-sf-lut {
+		qcom,lut-col-legend = <(-20) 0 25 40 60>;
+		qcom,lut-row-legend = <100 95 90 85 80>,
+				<75 70 65 60 55>,
+				<50 45 40 35 30>,
+				<25 20 15 10 9>,
+				<8 7 6 5 4>,
+				<3 2 1 0>;
+		qcom,lut-data = <1371 224 100 79 74>,
+				<1358 242 100 80 74>,
+				<1358 242 103 80 74>,
+				<1195 257 107 82 75>,
+				<1171 256 112 84 77>,
+				<1149 250 119 89 79>,
+				<1144 232 114 90 79>,
+				<1150 225 101 83 76>,
+				<1175 227 98 81 76>,
+				<1210 232 98 82 76>,
+				<1260 236 98 82 77>,
+				<1329 242 100 84 77>,
+				<1421 251 100 86 79>,
+				<1536 263 101 81 76>,
+				<1671 280 100 80 74>,
+				<1830 304 100 81 75>,
+				<2036 338 101 82 76>,
+				<2326 443 103 82 76>,
+				<2788 708 112 88 79>,
+				<2890 747 115 90 80>,
+				<2755 676 117 89 79>,
+				<2750 716 118 87 78>,
+				<2916 765 119 87 79>,
+				<3336 833 123 89 80>,
+				<4214 920 133 92 81>,
+				<5615 1031 151 96 83>,
+				<7923 1188 192 104 89>,
+				<13252 1886 585 137 122>,
+				<43764 20050 47711 3680 16847>;
+	};
+};
diff --git a/arch/arm/boot/dts/dsi-panel-hx8389b-qhd-video.dtsi b/arch/arm/boot/dts/dsi-panel-hx8389b-qhd-video.dtsi
index 8c79bb9..25e5072 100755
--- a/arch/arm/boot/dts/dsi-panel-hx8389b-qhd-video.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-hx8389b-qhd-video.dtsi
@@ -17,7 +17,7 @@
  *---------------------------------------------------------------------------*/
 &mdss_mdp {
 	dsi_hx8389b_qhd_vid: qcom,mdss_dsi_hx8389b_qhd_video {
-		qcom,mdss-dsi-panel-name = "HX8389b qhd video mode dsi panel";
+		qcom,mdss-dsi-panel-name = "hx8389b qhd video mode dsi panel";
 		qcom,mdss-dsi-panel-controller = <&mdss_dsi0>;
 		qcom,mdss-dsi-panel-type = "dsi_video_mode";
 		qcom,mdss-dsi-panel-destination = "display_1";
@@ -26,89 +26,35 @@
 		qcom,mdss-dsi-stream = <0>;
 		qcom,mdss-dsi-panel-width = <540>;
 		qcom,mdss-dsi-panel-height = <960>;
-		qcom,mdss-dsi-h-front-porch = <48>;
-		qcom,mdss-dsi-h-back-porch = <96>;
-		qcom,mdss-dsi-h-pulse-width = <96>;
+		qcom,mdss-dsi-h-front-porch = <60>;
+		qcom,mdss-dsi-h-back-porch = <39>;
+		qcom,mdss-dsi-h-pulse-width = <39>;
 		qcom,mdss-dsi-h-sync-skew = <0>;
+		qcom,mdss-dsi-v-back-porch = <13>;
 		qcom,mdss-dsi-v-front-porch = <9>;
 		qcom,mdss-dsi-v-pulse-width = <3>;
-		qcom,mdss-dsi-v-back-porch = <13>;
 		qcom,mdss-dsi-h-left-border = <0>;
 		qcom,mdss-dsi-h-right-border = <0>;
 		qcom,mdss-dsi-v-top-border = <0>;
 		qcom,mdss-dsi-v-bottom-border = <0>;
 		qcom,mdss-dsi-bpp = <24>;
+		qcom,mdss-dsi-color-order = <0>;
 		qcom,mdss-dsi-underflow-color = <0xff>;
 		qcom,mdss-dsi-border-color = <0>;
-		qcom,mdss-dsi-on-command = [
-				39 01 00 00 00 00 04
-					B9 FF 83 89
-				39 01 00 00 00 00 08
-					BA 41 93 00
-					16 A4 10 18
-				23 01 00 00 00 00 02
-					C6 08
-				39 01 00 00 00 00 03
-					BC 02 00
-				23 01 00 00 00 00 02
-					CC 02
-				39 01 00 00 00 00 14
-					B1 00 00 07
-					E8 50 10 11
-					98 f8 21 29
-					27 27 43 01
-					58 F0 00 E6
-				39 01 00 00 00 00 08
-					B2 00 00 78
-					0C 07 3F 80
-				39 01 00 00 00 00 18
-					b4 82 08 00
-					32 10 04 32
-					10 00 32 10
-					00 37 0a 40
-					08 37 0a 40
-					14 46 50 0a
-				39 01 00 00 00 00 39
-					d5 00 00 00
-					00 01 00 00
-					00 60 00 99
-					88 AA BB 88
-					23 88 01 88
-					67 88 45 01
-					23 88 88 88
-					88 88 88 99
-					BB AA 88 54
-					88 76 88 10
-					88 32 32 10
-					88 88 88 88
-					88 00 04 00
-					00 00 00 00
-					00
-				39 01 00 00 00 00 03
-					CB 07 07
-				39 01 00 00 00 00 05
-					BB 00 00 FF
-					80
-				39 01 00 00 00 00 04
-					DE 05 58 10
-				39 01 00 00 00 00 05
-					B6 00 8A 00
-					8A
-				39 01 00 00 00 00 23
-					E0 01 08 0C
-					1F 25 36 12
-					35 05 09 0D
-					10 11 0F 0F
-					1C 1D 01 08
-					0C 1F 25 36
-					12 35 05 09
-					0D 10 11 0F
-					0F 1C 1D
-				05 01 00 00 96 00 02
-					11 00
-				05 01 00 00 96 00 02
-					29 00
-		];
+		qcom,mdss-dsi-on-command = [39 01 00 00 0A 00 04 B9 FF 83 89
+				15 01 00 00 01 00 02 CC 02
+				39 01 00 00 01 00 03 C0 43 17
+				39 01 00 00 01 00 08 BA 41 93 00 16 A4 10 18
+				39 01 00 00 01 00 14 B1 00 00 06 EB 59 10 11 EE EE 3A 42 3F 3F 43 01 5A F6 00 E6
+				39 01 00 00 01 00 08 B2 00 00 78 0C 07 3F 80
+				39 01 00 00 01 00 04 b7 00 00 50
+				39 01 00 00 01 00 18 B4 80 08 00 32 10 04 32 10 00 32 10 00 37 0a 40 08 37 00 46 02 58 58 02
+				39 01 00 00 01 00 39 D5 00 00 00 00 01 00 00 00 60 00 99 88 AA BB 88 23 88 01 88 67 88 45 01 23 88 88 88 88 88 88 99 BB AA 88 54 88 76 88 10 88 32 32 10 88 88 88 88 88 3C 04 00 00 00 00 00 00
+				39 01 00 00 01 00 23 E0 05 11 16 35 3F 3F 21 43 07 0C 0F 11 12 10 10 1D 18 05 11 16 35 3F 3F 21 43 07 0C 0F 11 12 10 10 1D 18
+				39 01 00 00 05 00 80 C1 01 00 07 13 21 29 2F 34 3B 42 48 50 58 61 69 71 79 81 88 90 98 A0 A9 B1 B9 C1 C8 CE D6 DF E6 EF F7 FF 0E 5A 73 69 36 8E 69 5F C0 00 07 13 21 29 2F 34 3B 42 48 50 58 61 69 71 79 81 88 90 98 A0 A9 B1 B9 C1 C8 CE D6 DF E6 EF F7 FF 0E 5A 73 69 36 8E 69 5F C0 00 07 13 21 29 2F 34 3B 42 48 50 58 61 69 71 79 81 88 90 98 A0 A9 B1 B9 C1 C8 CE D6 DF E6 EF F7 FF 0E 5A 73 69 36 8E 69 5F C0
+				39 01 00 00 01 00 05 B6 00 88 00 88
+				05 01 00 00 78 00 02 11 00
+				05 01 00 00 32 00 02 29 00];
 		qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00
 					05 01 00 00 78 00 02 10 00];
 		qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
@@ -120,7 +66,7 @@
 		qcom,mdss-dsi-bllp-power-mode;
 		qcom,mdss-dsi-lane-0-state;
 		qcom,mdss-dsi-lane-1-state;
-		qcom,mdss-dsi-panel-timings = [97 23 17 00 4B 53 1C 27 27 03 04 00];
+		qcom,mdss-dsi-panel-timings = [87 1E 14 00 44 4B 19 21 22 03 04 00];
 		qcom,mdss-dsi-t-clk-post = <0x04>;
 		qcom,mdss-dsi-t-clk-pre = <0x1b>;
 		qcom,mdss-dsi-bl-min-level = <26>;
@@ -129,6 +75,5 @@
 		qcom,mdss-dsi-mdp-trigger = "none";
 		qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
 		qcom,mdss-dsi-reset-sequence = <1 20>, <0 2>, <1 20>;
-
 	};
 };
diff --git a/arch/arm/boot/dts/dsi-panel-orise-720p-video.dtsi b/arch/arm/boot/dts/dsi-panel-orise-720p-video.dtsi
index 30eda91..5393756 100644
--- a/arch/arm/boot/dts/dsi-panel-orise-720p-video.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-orise-720p-video.dtsi
@@ -34,7 +34,7 @@
 		qcom,mdss-pan-dsi-stream = <0>;
 		qcom,mdss-pan-dsi-mdp-tr = <0x0>;
 		qcom,mdss-pan-dsi-dma-tr = <0x04>;
-		qcom,mdss-pan-dsi-frame-rate = <60>;
+		qcom,mdss-pan-dsi-framerate = <60>;
 		qcom,panel-phy-regulatorSettings = [03 01 01 00  /* Regualotor settings */
 						    20 00 01];
 		qcom,panel-phy-timingSettings = [69 29 1f 00 55 55
diff --git a/arch/arm/boot/dts/msm-pm8110.dtsi b/arch/arm/boot/dts/msm-pm8110.dtsi
index 2ccb1fb..20e8a96 100644
--- a/arch/arm/boot/dts/msm-pm8110.dtsi
+++ b/arch/arm/boot/dts/msm-pm8110.dtsi
@@ -328,7 +328,7 @@
 			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,high-ocv-correction-limit-uv = <250>;
 			qcom,hold-soc-est = <3>;
 			qcom,bms-vadc = <&pm8110_vadc>;
 			qcom,bms-iadc = <&pm8110_iadc>;
diff --git a/arch/arm/boot/dts/msm-pm8226.dtsi b/arch/arm/boot/dts/msm-pm8226.dtsi
index b9bcd0c..6d506cc 100644
--- a/arch/arm/boot/dts/msm-pm8226.dtsi
+++ b/arch/arm/boot/dts/msm-pm8226.dtsi
@@ -206,7 +206,7 @@
 			qcom,batt-type = <0>;
 			qcom,tm-temp-margin = <5000>;
 			qcom,low-ocv-correction-limit-uv = <100>;
-			qcom,high-ocv-correction-limit-uv = <50>;
+			qcom,high-ocv-correction-limit-uv = <250>;
 			qcom,hold-soc-est = <3>;
 			qcom,low-voltage-threshold = <3420000>;
 			qcom,bms-vadc = <&pm8226_vadc>;
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index b540063..520decd 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -135,7 +135,7 @@
 		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,high-ocv-correction-limit-uv = <250>;
 		qcom,hold-soc-est = <3>;
 		qcom,bms-vadc = <&pm8941_vadc>;
 		qcom,bms-iadc = <&pm8941_iadc>;
@@ -209,7 +209,9 @@
 		qcom,resume-soc = <99>;
 		qcom,tchg-mins = <150>;
 		qcom,chg-vadc = <&pm8941_vadc>;
+		qcom,chg-iadc = <&pm8941_iadc>;
 		qcom,chg-adc_tm = <&pm8941_adc_tm>;
+		qcom,ibat-calibration-enabled;
 
 		qcom,chgr@1000 {
 			status = "disabled";
diff --git a/arch/arm/boot/dts/msm8226-720p-cdp.dtsi b/arch/arm/boot/dts/msm8226-720p-cdp.dtsi
index 3ebe225..9a1eb36 100644
--- a/arch/arm/boot/dts/msm8226-720p-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8226-720p-cdp.dtsi
@@ -28,6 +28,7 @@
 			synaptics,reset-gpio = <&msmgpio 16 0x00>;
 			synaptics,irq-gpio = <&msmgpio 17 0x2008>;
 			synaptics,button-map = <139 102 158>;
+			synaptics,fw-image-name = "PR1468813.img";
 			synaptics,i2c-pull-up;
 			synaptics,power-down;
 			synaptics,disable-gpios;
diff --git a/arch/arm/boot/dts/msm8226-720p-mtp.dtsi b/arch/arm/boot/dts/msm8226-720p-mtp.dtsi
index a4bd8fd..7f4f8fc 100644
--- a/arch/arm/boot/dts/msm8226-720p-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8226-720p-mtp.dtsi
@@ -28,6 +28,7 @@
 			synaptics,reset-gpio = <&msmgpio 16 0x00>;
 			synaptics,irq-gpio = <&msmgpio 17 0x2008>;
 			synaptics,button-map = <139 102 158>;
+			synaptics,fw-image-name = "PR1468813.img";
 			synaptics,i2c-pull-up;
 			synaptics,power-down;
 			synaptics,disable-gpios;
diff --git a/arch/arm/boot/dts/msm8226-camera.dtsi b/arch/arm/boot/dts/msm8226-camera.dtsi
index 4987dae..3e8444f 100644
--- a/arch/arm/boot/dts/msm8226-camera.dtsi
+++ b/arch/arm/boot/dts/msm8226-camera.dtsi
@@ -136,29 +136,29 @@
 };
 
 &master0 {
-	qcom,hw-thigh = <78>;
-	qcom,hw-tlow = <114>;
-	qcom,hw-tsu-sto = <28>;
-	qcom,hw-tsu-sta = <28>;
-	qcom,hw-thd-dat = <10>;
-	qcom,hw-thd-sta = <77>;
-	qcom,hw-tbuf = <118>;
+	qcom,hw-thigh = <20>;
+	qcom,hw-tlow = <28>;
+	qcom,hw-tsu-sto = <21>;
+	qcom,hw-tsu-sta = <21>;
+	qcom,hw-thd-dat = <13>;
+	qcom,hw-thd-sta = <18>;
+	qcom,hw-tbuf = <25>;
 	qcom,hw-scl-stretch-en = <0>;
 	qcom,hw-trdhld = <6>;
-	qcom,hw-tsp = <1>;
+	qcom,hw-tsp = <3>;
 	status = "ok";
 };
 
 &master1 {
-	qcom,hw-thigh = <78>;
-	qcom,hw-tlow = <114>;
-	qcom,hw-tsu-sto = <28>;
-	qcom,hw-tsu-sta = <28>;
-	qcom,hw-thd-dat = <10>;
-	qcom,hw-thd-sta = <77>;
-	qcom,hw-tbuf = <118>;
+	qcom,hw-thigh = <20>;
+	qcom,hw-tlow = <28>;
+	qcom,hw-tsu-sto = <21>;
+	qcom,hw-tsu-sta = <21>;
+	qcom,hw-thd-dat = <13>;
+	qcom,hw-thd-sta = <18>;
+	qcom,hw-tbuf = <25>;
 	qcom,hw-scl-stretch-en = <0>;
 	qcom,hw-trdhld = <6>;
-	qcom,hw-tsp = <1>;
+	qcom,hw-tsp = <3>;
 	status = "ok";
 };
diff --git a/arch/arm/boot/dts/msm8226-qrd-skuf.dtsi b/arch/arm/boot/dts/msm8226-qrd-skuf.dtsi
index 76bd262..2e32ac4 100755
--- a/arch/arm/boot/dts/msm8226-qrd-skuf.dtsi
+++ b/arch/arm/boot/dts/msm8226-qrd-skuf.dtsi
@@ -85,25 +85,25 @@
 			goodix,button-map= <158 102 139>;
 			goodix,product-id = "915";
 			goodix,cfg-data0 = [
-				41 D0 02 00 05 05 35 01 01 0F
-				2D 06 50 32 03 05 00 00 00 00
-				00 00 05 18 1A 1E 14 8C 0E 0E
-				3F 3D 2A 09 00 00 00 99 04 1D
-				00 00 00 00 00 00 00 00 00 00
-				00 32 6E 94 D5 01 05 00 00 04
-				CE 36 00 B5 3F 00 9E 4A 00 8B
-				57 00 7C 65 00 7C 10 38 68 00
-				56 50 35 66 66 27 00 00 00 00
+				41 D0 02 00 05 05 35 11 01 0F
+				2D 06 50 32 03 02 00 00 00 00
+				00 00 05 18 1A 1E 14 8C 2E 0E
+				59 5B B2 04 00 00 00 99 03 11
+				00 1C 00 00 00 00 00 00 00 00
+				00 53 A6 94 C5 01 05 00 00 08
+				7F 59 00 71 66 00 64 75 00 58
+				87 00 4E 9B 00 4E 10 38 68 00
+				56 45 30 66 66 27 00 00 00 00
 				00 00 00 00 00 00 00 00 00 00
 				00 00 00 00 00 00 00 00 00 00
 				00 00 02 04 06 08 0A 0C 0E 10
-				12 14 16 18 1A 1C 00 00 00 00
-				00 00 00 00 00 00 00 00 00 00
-				00 00 00 02 04 06 08 0A 0C 0F
+				12 14 16 18 1A 1C FF FF FF FF
+				FF FF FF FF FF FF FF FF FF FF
+				FF FF 00 02 04 06 08 0A 0C 0F
 				10 12 13 14 16 18 1C 1D 1E 1F
-				20 21 22 24 26 28 29 2A 00 00
-				00 FF FF FF FF FF FF FF FF FF
-				FF FF FF FF A3 01];
+				20 21 22 24 26 28 29 2A FF FF
+				FF FF FF FF FF FF FF FF FF FF
+				FF FF FF FF 03 01];
 			goodix,cfg-data1 = [
 				41 D0 02 00 05 05 35 01 01 C3
 				2D 06 55 32 03 03 00 00 00 00
diff --git a/arch/arm/boot/dts/msm8226-qrd.dtsi b/arch/arm/boot/dts/msm8226-qrd.dtsi
index eac0bb6..7ff97f6 100644
--- a/arch/arm/boot/dts/msm8226-qrd.dtsi
+++ b/arch/arm/boot/dts/msm8226-qrd.dtsi
@@ -28,6 +28,7 @@
 			synaptics,reset-gpio = <&msmgpio 16 0x00>;
 			synaptics,irq-gpio = <&msmgpio 17 0x2008>;
 			synaptics,button-map = <139 102 158>;
+			synaptics,fw-image-name = "PR1468813.img";
 			synaptics,i2c-pull-up;
 			synaptics,power-down;
 			synaptics,disable-gpios;
diff --git a/arch/arm/boot/dts/msm8226-regulator.dtsi b/arch/arm/boot/dts/msm8226-regulator.dtsi
index 7eb3f57..63da606 100644
--- a/arch/arm/boot/dts/msm8226-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8226-regulator.dtsi
@@ -30,7 +30,7 @@
 &soc {
 	apc_vreg_corner: regulator@f9018000 {
 		status = "okay";
-		compatible = "qcom,cpr-regulator";
+		compatible = "qti,cpr-regulator";
 		reg = <0xf9018000 0x1000>, <0xf9011064 4>, <0xfc4b8000 0x1000>;
 		reg-names = "rbcpr", "rbcpr_clk", "efuse_addr";
 		interrupts = <0 15 0>;
@@ -38,51 +38,66 @@
 		regulator-min-microvolt = <1>;
 		regulator-max-microvolt = <3>;
 
-		qcom,pvs-fuse-redun-sel = <22 24 3 2>;
-		qcom,pvs-fuse = <22 6 5>;
-		qcom,pvs-fuse-redun = <22 27 5>;
+		qti,pvs-fuse-redun-sel = <22 24 3 2 0>;
+		qti,pvs-fuse = <22 6 5 0>;
+		qti,pvs-fuse-redun = <22 27 5 0>;
 
-		qcom,pvs-init-voltage = <1275000 1275000 1275000 1275000 1275000
+		qti,pvs-init-voltage = <1275000 1275000 1275000 1275000 1275000
 					1275000 1260000 1245000 1230000 1215000
 					1200000 1185000 1170000 1155000 1140000
 					1140000 1140000 1140000 1140000 1140000
 					1150000 1140000 1140000 1140000 1140000
 					1140000 1140000 1140000 1275000 1275000
 					1275000 1275000>;
-		qcom,pvs-corner-ceiling-slow = <1050000 1150000 1275000>;
-		qcom,pvs-corner-ceiling-nom  = <1050000 1075000 1200000>;
-		qcom,pvs-corner-ceiling-fast = <1050000 1050000 1140000>;
+		qti,pvs-corner-ceiling-slow = <1050000 1150000 1275000>;
+		qti,pvs-corner-ceiling-nom  = <1050000 1075000 1200000>;
+		qti,pvs-corner-ceiling-fast = <1050000 1050000 1100000>;
 		vdd-apc-supply = <&pm8226_s2>;
 
 		vdd-mx-supply = <&pm8226_l3_ao>;
-		qcom,vdd-mx-vmax = <1350000>;
-		qcom,vdd-mx-vmin-method = <1>;
+		qti,vdd-mx-vmax = <1350000>;
+		qti,vdd-mx-vmin-method = <1>;
 
-		qcom,cpr-ref-clk = <19200>;
-		qcom,cpr-timer-delay = <5000>;
-		qcom,cpr-timer-cons-up = <0>;
-		qcom,cpr-timer-cons-down = <2>;
-		qcom,cpr-irq-line = <0>;
-		qcom,cpr-step-quotient = <15>;
-		qcom,cpr-up-threshold = <0>;
-		qcom,cpr-down-threshold = <10>;
-		qcom,cpr-idle-clocks = <0>;
-		qcom,cpr-gcnt-time = <1>;
-		qcom,vdd-apc-step-up-limit = <1>;
-		qcom,vdd-apc-step-down-limit = <1>;
-		qcom,cpr-apc-volt-step = <5000>;
+		qti,cpr-ref-clk = <19200>;
+		qti,cpr-timer-delay = <5000>;
+		qti,cpr-timer-cons-up = <0>;
+		qti,cpr-timer-cons-down = <2>;
+		qti,cpr-irq-line = <0>;
+		qti,cpr-step-quotient = <15>;
+		qti,cpr-up-threshold = <0>;
+		qti,cpr-down-threshold = <10>;
+		qti,cpr-idle-clocks = <0>;
+		qti,cpr-gcnt-time = <1>;
+		qti,vdd-apc-step-up-limit = <1>;
+		qti,vdd-apc-step-down-limit = <1>;
+		qti,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>;
+		qti,cpr-fuse-redun-sel = <138 57 1 1 0>;
+		qti,cpr-fuse-row = <138 0>;
+		qti,cpr-fuse-bp-cpr-disable = <36>;
+		qti,cpr-fuse-bp-scheme = <37>;
+		qti,cpr-fuse-target-quot = <24 12 0>;
+		qti,cpr-fuse-ro-sel = <54 38 41>;
+		qti,cpr-fuse-redun-row = <139 0>;
+		qti,cpr-fuse-redun-target-quot = <24 12 0>;
+		qti,cpr-fuse-redun-ro-sel = <46 36 39>;
 
-		qcom,cpr-enable;
+		qti,cpr-enable;
+		qti,cpr-fuse-cond-min-volt-sel = <54 42 6 7 1>;
+		qti,cpr-cond-min-voltage = <1140000>;
+		qti,cpr-fuse-uplift-sel = <22 53 1 0 0>;
+		qti,cpr-uplift-voltage = <50000>;
+		qti,cpr-uplift-quotient = <0 0 120>;
+		qti,cpr-uplift-max-volt = <1350000>;
+		qti,cpr-uplift-speed-bin = <1>;
+		qti,speed-bin-fuse-sel = <22 0 3 0>;
+		qti,cpr-quot-adjust-table = <1 300000 0 1>,
+				<1 384000 0 1>, <1 600000 0 2>,
+				<1 787200 0 2>, <1 998400 450 3>,
+				<1 1094400 375 3>, <1 1190400 300 3>,
+				<1 1305600 225 3>, <1 1344000 187 3>,
+				<1 1401600 150 3>, <1 1497600 75 3>,
+				<1 1593600 0 3>;
 	};
 };
 
diff --git a/arch/arm/boot/dts/msm8226-v1-pm.dtsi b/arch/arm/boot/dts/msm8226-v1-pm.dtsi
index 38ca03b..a1a8480 100644
--- a/arch/arm/boot/dts/msm8226-v1-pm.dtsi
+++ b/arch/arm/boot/dts/msm8226-v1-pm.dtsi
@@ -160,7 +160,7 @@
 				qcom,ss-power = <315>;
 				qcom,energy-overhead = <1027150>;
 				qcom,time-overhead = <2400>;
-				qcom,min-cpu-mode= "spc";
+				qcom,min-cpu-mode= "standalone_pc";
 				qcom,sync-cpus;
 			};
 
diff --git a/arch/arm/boot/dts/msm8226-v2-pm.dtsi b/arch/arm/boot/dts/msm8226-v2-pm.dtsi
index a0da9cc..2e9f6db 100644
--- a/arch/arm/boot/dts/msm8226-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8226-v2-pm.dtsi
@@ -162,7 +162,7 @@
 				qcom,ss-power = <315>;
 				qcom,energy-overhead = <1027150>;
 				qcom,time-overhead = <2400>;
-				qcom,min-cpu-mode= "spc";
+				qcom,min-cpu-mode= "standalone_pc";
 				qcom,sync-cpus;
 			};
 
diff --git a/arch/arm/boot/dts/msm8226-v2.dtsi b/arch/arm/boot/dts/msm8226-v2.dtsi
index d74554f..4149169 100644
--- a/arch/arm/boot/dts/msm8226-v2.dtsi
+++ b/arch/arm/boot/dts/msm8226-v2.dtsi
@@ -52,20 +52,20 @@
 };
 
 &apc_vreg_corner {
-	qcom,pvs-init-voltage = <1330000 1330000 1330000 1320000 1310000
+	qti,pvs-init-voltage = <1330000 1330000 1330000 1320000 1310000
 					1300000 1290000 1280000 1270000 1260000
 					1250000 1240000 1230000 1220000 1210000
 					1200000 1190000 1180000 1170000 1160000
 					1150000 1140000 1140000 1140000 1140000
 					1140000 1140000 1140000 1140000 1140000
 					1140000 1140000>;
-	qcom,pvs-corner-ceiling-slow = <1050000 1150000 1280000>;
-	qcom,pvs-corner-ceiling-nom  = <1050000 1080000 1200000>;
-	qcom,pvs-corner-ceiling-fast = <1050000 1050000 1140000>;
-	qcom,cpr-step-quotient = <30>;
-	qcom,cpr-up-threshold = <0>;
-	qcom,cpr-down-threshold = <5>;
-	qcom,cpr-apc-volt-step = <10000>;
+	qti,pvs-corner-ceiling-slow = <1050000 1150000 1280000>;
+	qti,pvs-corner-ceiling-nom  = <1050000 1080000 1200000>;
+	qti,pvs-corner-ceiling-fast = <1050000 1050000 1100000>;
+	qti,cpr-step-quotient = <30>;
+	qti,cpr-up-threshold = <0>;
+	qti,cpr-down-threshold = <5>;
+	qti,cpr-apc-volt-step = <10000>;
 };
 
 &msm_gpu {
@@ -102,12 +102,12 @@
 			<         0 0>,
 			< 384000000 1>,
 			< 787200000 2>,
-			<149700000 3>;
+			<1401600000 3>;
 		qcom,speed7-bin-v2 =
 			<         0 0>,
 			< 384000000 1>,
 			< 787200000 2>,
-			<1497600000 3>;
+			<1401600000 3>;
 		qcom,speed1-bin-v2 =
 			<         0 0>,
 			< 384000000 1>,
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index 0b8b07e..fc00411 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -217,13 +217,13 @@
 		reg = <0xf991f000 0x1000>;
 		interrupts = <0 109 0>;
 		status = "disabled";
-	};
 
-	serial@f995e000 {
-		compatible = "qcom,msm-lsuart-v14";
-		reg = <0xf995e000 0x1000>;
-		interrupts = <0 114 0>;
-		status = "disabled";
+		qcom,msm-bus,name = "blsp1_uart2";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<86 512 0 0>,
+				<86 512 500 800>;
 	};
 
 	qcom,msm-imem@fe805000 {
@@ -282,7 +282,6 @@
 		qcom,hsusb-otg-phy-type = <2>;
 		qcom,hsusb-otg-mode = <1>;
 		qcom,hsusb-otg-otg-control = <2>;
-		qcom,hsusb-otg-disable-reset;
 		qcom,dp-manual-pullup;
 		qcom,ahb-async-bridge-bypass;
 
@@ -1025,8 +1024,8 @@
 		qcom,cpufreq-table =
 			<  300000 1600 /* 200 MHz */ >,
 			<  384000 1600 /* 200 MHz */ >,
-			<  600000 3200 /* 320 MHz */ >,
-			<  787200 4264 /* 533 MHz */ >,
+			<  600000 1600 /* 200 MHz */ >,
+			<  787200 3200 /* 400 MHz */ >,
 			<  998400 4264 /* 533 MHz */ >,
 			< 1094400 4264 /* 533 MHz */ >,
 			< 1190400 4264 /* 533 MHz */ >,
diff --git a/arch/arm/boot/dts/msm8610-cdp.dtsi b/arch/arm/boot/dts/msm8610-cdp.dtsi
index d63c6e5..04eca14 100644
--- a/arch/arm/boot/dts/msm8610-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8610-cdp.dtsi
@@ -143,7 +143,11 @@
 			"MIC BIAS External", "Handset Mic",
 			"MIC BIAS Internal2", "Headset Mic",
 			"AMIC1", "MIC BIAS External",
-			"AMIC2", "MIC BIAS Internal2";
+			"AMIC2", "MIC BIAS Internal2",
+			"MIC BIAS External", "Digital Mic1",
+			"MIC BIAS External", "Digital Mic2",
+			"DMIC1", "MIC BIAS External",
+			"DMIC2", "MIC BIAS External";
 		qcom,headset-jack-type-NC;
     };
 };
diff --git a/arch/arm/boot/dts/msm8610-qrd.dtsi b/arch/arm/boot/dts/msm8610-qrd.dtsi
index 85bd746..92d1a77 100644
--- a/arch/arm/boot/dts/msm8610-qrd.dtsi
+++ b/arch/arm/boot/dts/msm8610-qrd.dtsi
@@ -102,6 +102,10 @@
 		linux,default-trigger = "flashlight-trigger";
 	};
 
+	qcom,wdt@f9017000 {
+		qcom,bark-time = <13000>;
+	};
+
 	gpio_keys {
                 compatible = "gpio-keys";
                 input-name = "gpio-keys";
diff --git a/arch/arm/boot/dts/msm8610-regulator.dtsi b/arch/arm/boot/dts/msm8610-regulator.dtsi
index 7eb6a22..543f59e 100644
--- a/arch/arm/boot/dts/msm8610-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8610-regulator.dtsi
@@ -30,7 +30,7 @@
 &soc {
 	apc_vreg_corner: regulator@f9018000 {
 		status = "okay";
-		compatible = "qcom,cpr-regulator";
+		compatible = "qti,cpr-regulator";
 		reg = <0xf9018000 0x1000>, <0xf9011064 4>, <0xfc4b8000 0x1000>;
 		reg-names = "rbcpr", "rbcpr_clk", "efuse_addr";
 		interrupts = <0 15 0>;
@@ -38,54 +38,53 @@
 		regulator-min-microvolt = <1>;
 		regulator-max-microvolt = <3>;
 
-		qcom,pvs-fuse-redun-sel = <53 25 3 2>;
-		qcom,pvs-fuse = <23 6 5>;
-		qcom,pvs-fuse-redun = <61 47 5>;
+		qti,pvs-fuse-redun-sel = <53 25 3 2 1>;
+		qti,pvs-fuse = <23 6 5 1>;
+		qti,pvs-fuse-redun = <61 47 5 1>;
 
-		qcom,pvs-init-voltage = <1275000 1275000 1275000 1275000 1275000
+		qti,pvs-init-voltage = <1275000 1275000 1275000 1275000 1275000
 					1275000 1275000 1275000 1275000 1275000
 					1275000 1275000 1275000 1275000 1275000
 					1275000 1275000 1275000 1275000 1275000
 					1275000 1275000 1275000 1275000 1275000
 					1275000 1275000 1275000 1275000 1275000
 					1275000 1275000>;
-		qcom,pvs-corner-ceiling-slow = <1150000 1150000 1275000>;
-		qcom,pvs-corner-ceiling-nom  = <1075000 1075000 1200000>;
-		qcom,pvs-corner-ceiling-fast = <1050000 1050000 1140000>;
+		qti,pvs-corner-ceiling-slow = <1150000 1150000 1275000>;
+		qti,pvs-corner-ceiling-nom  = <1075000 1075000 1275000>;
+		qti,pvs-corner-ceiling-fast = <1050000 1050000 1275000>;
 		vdd-apc-supply = <&pm8110_s2>;
 
 		vdd-mx-supply = <&pm8110_l3_ao>;
-		qcom,vdd-mx-vmax = <1350000>;
-		qcom,vdd-mx-vmin-method = <1>;
+		qti,vdd-mx-vmax = <1350000>;
+		qti,vdd-mx-vmin-method = <1>;
 
-		qcom,cpr-ref-clk = <19200>;
-		qcom,cpr-timer-delay = <5000>;
-		qcom,cpr-timer-cons-up = <0>;
-		qcom,cpr-timer-cons-down = <2>;
-		qcom,cpr-irq-line = <0>;
-		qcom,cpr-step-quotient = <15>;
-		qcom,cpr-up-threshold = <0>;
-		qcom,cpr-down-threshold = <10>;
-		qcom,cpr-idle-clocks = <5>;
-		qcom,cpr-gcnt-time = <1>;
-		qcom,vdd-apc-step-up-limit = <1>;
-		qcom,vdd-apc-step-down-limit = <1>;
-		qcom,cpr-apc-volt-step = <5000>;
+		qti,cpr-ref-clk = <19200>;
+		qti,cpr-timer-delay = <5000>;
+		qti,cpr-timer-cons-up = <0>;
+		qti,cpr-timer-cons-down = <2>;
+		qti,cpr-irq-line = <0>;
+		qti,cpr-step-quotient = <15>;
+		qti,cpr-up-threshold = <0>;
+		qti,cpr-down-threshold = <10>;
+		qti,cpr-idle-clocks = <5>;
+		qti,cpr-gcnt-time = <1>;
+		qti,vdd-apc-step-up-limit = <1>;
+		qti,vdd-apc-step-down-limit = <1>;
+		qti,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>;
+		qti,cpr-fuse-redun-sel = <53 25 3 2 1>;
+		qti,cpr-fuse-row = <61 1>;
+		qti,cpr-fuse-bp-cpr-disable = <39>;
+		qti,cpr-fuse-bp-scheme = <40>;
+		qti,cpr-fuse-target-quot = <27 15 3>;
+		qti,cpr-fuse-ro-sel = <47 41 44>;
+		qti,cpr-fuse-redun-row = <52 1>;
+		qti,cpr-fuse-redun-bp-cpr-disable = <24>;
+		qti,cpr-fuse-redun-bp-scheme = <25>;
+		qti,cpr-fuse-redun-target-quot = <32 12 0>;
+		qti,cpr-fuse-redun-ro-sel = <44 26 29>;
 
-		qcom,cpr-enable;
-		qcom,use-tz-api;
+		qti,cpr-enable;
 	};
 };
 
diff --git a/arch/arm/boot/dts/msm8610-rumi.dts b/arch/arm/boot/dts/msm8610-rumi.dts
index 7f06485..c22b4f28 100644
--- a/arch/arm/boot/dts/msm8610-rumi.dts
+++ b/arch/arm/boot/dts/msm8610-rumi.dts
@@ -17,7 +17,7 @@
 / {
 	model = "Qualcomm MSM 8610 Rumi";
 	compatible = "qcom,msm8610-rumi", "qcom,msm8610", "qcom,rumi";
-	qcom,msm-id = <147 15 0>;
+	qcom,board-id = <15 0>;
 };
 
 &soc {
diff --git a/arch/arm/boot/dts/msm8610-sim.dts b/arch/arm/boot/dts/msm8610-sim.dts
index 33176b9..531ee4b 100644
--- a/arch/arm/boot/dts/msm8610-sim.dts
+++ b/arch/arm/boot/dts/msm8610-sim.dts
@@ -17,7 +17,7 @@
 / {
 	model = "Qualcomm MSM 8610 Simulator";
 	compatible = "qcom,msm8610-sim", "qcom,msm8610", "qcom,sim";
-	qcom,msm-id = <147 16 0>;
+	qcom,board-id = <16 0>;
 };
 
 &soc {
diff --git a/arch/arm/boot/dts/msm8610-v1-cdp.dts b/arch/arm/boot/dts/msm8610-v1-cdp.dts
index beb3976..5a70379 100644
--- a/arch/arm/boot/dts/msm8610-v1-cdp.dts
+++ b/arch/arm/boot/dts/msm8610-v1-cdp.dts
@@ -19,8 +19,7 @@
 / {
 	model = "Qualcomm MSM 8610 CDP";
 	compatible = "qcom,msm8610-cdp", "qcom,msm8610", "qcom,cdp";
-	qcom,msm-id = <147 1 0>, <165 1 0>, <161 1 0>, <162 1 0>,
-		      <163 1 0>, <164 1 0>, <166 1 0>;
+	qcom,board-id = <1 0>;
 };
 
 
diff --git a/arch/arm/boot/dts/msm8610-v1-mtp.dts b/arch/arm/boot/dts/msm8610-v1-mtp.dts
index 82992a3..c8c8d09 100644
--- a/arch/arm/boot/dts/msm8610-v1-mtp.dts
+++ b/arch/arm/boot/dts/msm8610-v1-mtp.dts
@@ -19,8 +19,7 @@
 / {
 	model = "Qualcomm MSM 8610 MTP";
 	compatible = "qcom,msm8610-mtp", "qcom,msm8610", "qcom,mtp";
-	qcom,msm-id = <147 8 0>, <165 8 0>, <161 8 0>, <162 8 0>,
-		      <163 8 0>, <164 8 0>, <166 8 0>;
+	qcom,board-id = <8 0>;
 };
 
 
diff --git a/arch/arm/boot/dts/msm8610-v1-pm.dtsi b/arch/arm/boot/dts/msm8610-v1-pm.dtsi
index e5aa53c..ea37413 100644
--- a/arch/arm/boot/dts/msm8610-v1-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-v1-pm.dtsi
@@ -160,7 +160,7 @@
 				qcom,ss-power = <315>;
 				qcom,energy-overhead = <1027150>;
 				qcom,time-overhead = <2400>;
-				qcom,min-cpu-mode= "spc";
+				qcom,min-cpu-mode= "standalone_pc";
 				qcom,sync-cpus;
 			};
 
diff --git a/arch/arm/boot/dts/msm8610-v2-cdp.dts b/arch/arm/boot/dts/msm8610-v2-cdp.dts
index a6d1d9c..447161f 100644
--- a/arch/arm/boot/dts/msm8610-v2-cdp.dts
+++ b/arch/arm/boot/dts/msm8610-v2-cdp.dts
@@ -19,8 +19,7 @@
 / {
 	model = "Qualcomm MSM 8610v2 CDP";
 	compatible = "qcom,msm8610-cdp", "qcom,msm8610", "qcom,cdp";
-	qcom,msm-id = <147 1 0x10001>, <165 1 0x10001>, <161 1 0x10001>, <162 1 0x10001>,
-		      <163 1 0x10001>, <164 1 0x10001>, <166 1 0x10001>;
+	qcom,board-id = <1 0>;
 };
 
 
diff --git a/arch/arm/boot/dts/msm8610-v2-mtp.dts b/arch/arm/boot/dts/msm8610-v2-mtp.dts
index 405a775..77f5276 100644
--- a/arch/arm/boot/dts/msm8610-v2-mtp.dts
+++ b/arch/arm/boot/dts/msm8610-v2-mtp.dts
@@ -19,8 +19,7 @@
 / {
 	model = "Qualcomm MSM 8610v2 MTP";
 	compatible = "qcom,msm8610-mtp", "qcom,msm8610", "qcom,mtp";
-	qcom,msm-id = <147 8 0x10001>, <165 8 0x10001>, <161 8 0x10001>, <162 8 0x10001>,
-		      <163 8 0x10001>, <164 8 0x10001>, <166 8 0x10001>;
+	qcom,board-id = <8 0>;
 };
 
 
diff --git a/arch/arm/boot/dts/msm8610-v2-pm.dtsi b/arch/arm/boot/dts/msm8610-v2-pm.dtsi
index c819c49..19fb185 100644
--- a/arch/arm/boot/dts/msm8610-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-v2-pm.dtsi
@@ -162,7 +162,7 @@
 				qcom,ss-power = <315>;
 				qcom,energy-overhead = <1027150>;
 				qcom,time-overhead = <2400>;
-				qcom,min-cpu-mode= "spc";
+				qcom,min-cpu-mode= "standalone_pc";
 				qcom,sync-cpus;
 			};
 
@@ -198,24 +198,40 @@
 			<62 222>, /* ee0_krait_hlos_spmi_periph_irq */
 			<2 216>, /* tsens_upper_lower_int */
 			<41 63>,  /* dino_gen_purpose_irq35 */
+			<0xff 18>,  /* APC_qgicQTmrSecPhysIrptReq */
+			<0xff 19>,  /* APC_qgicQTmrNonSecPhysIrptReq */
+			<0xff 35>,  /* WDT_barkInt */
+			<0xff 40>,  /* qtmr_phy_irq[0] */
+			<0xff 47>,  /* rbif_irq[0] */
 			<0xff 56>,  /* q6_wdog_expired_irq */
 			<0xff 57>,  /* mss_to_apps_irq(0) */
 			<0xff 58>,  /* mss_to_apps_irq(1) */
 			<0xff 59>,  /* mss_to_apps_irq(2) */
 			<0xff 60>,  /* mss_to_apps_irq(3) */
 			<0xff 61>,  /* mss_a2_bam_irq */
+			<0xff 65>,  /* o_gc_sys_irq[0] */
+			<0xff 74>,  /* venus0_mmu_cirpt[1] */
+			<0xff 75>,  /* venus0_mmu_cirpt[0] */
+			<0xff 78>,  /* mdss_mmu_cirpt[0] */
+			<0xff 79>,  /* mdss_mmu_cirpt[1] */
+			<0xff 97>,  /* camss_vfe_mmu_cirpt[1] */
+			<0xff 102>, /* camss_jpeg_mmu_cirpt[1] */
+			<0xff 109>, /* ocmem_dm_nonsec_irq */
+			<0xff 131>, /* blsp1_qup_5_irq */
+			<0xff 141>, /* blsp1_uart_3_irq */
+			<0xff 155>, /* sdc1_irq(0) */
+			<0xff 157>, /* sdc2_irq(0) */
+			<0xff 161>, /* lpass_irq_out_spare[4] */
+			<0xff 162>, /* lpass_irq_out_spare[5]*/
+			<0xff 170>, /* sdc1_pwr_cmd_irq */
 			<0xff 173>, /* o_wcss_apss_smd_hi */
 			<0xff 174>, /* o_wcss_apss_smd_med */
 			<0xff 175>, /* o_wcss_apss_smd_low */
 			<0xff 176>, /* o_wcss_apss_smsm_irq */
 			<0xff 177>, /* o_wcss_apss_wlan_data_xfer_done */
 			<0xff 178>, /* o_wcss_apss_wlan_rx_data_avail */
-			<0xff 179>, /* o_wcss_apss_asic_intr
+			<0xff 179>, /* o_wcss_apss_asic_intr */
 			<0xff 181>, /* o_wcss_apss_wdog_bite_and_reset_rdy */
-			<0xff 161>, /* lpass_irq_out_spare[4] /
-			<0xff 162>, /* lpass_irq_out_spare[5]*/
-			<0xff 234>, /* lpass_irq_out_spare[6]*/
-			<0xff 235>, /* lpass_irq_out_spare[7]*/
 			<0xff 188>, /* lpass_irq_out_apcs(0) */
 			<0xff 189>, /* lpass_irq_out_apcs(1) */
 			<0xff 190>, /* lpass_irq_out_apcs(2) */
@@ -230,12 +246,16 @@
 			<0xff 205>, /* rpm_ipc(25) */
 			<0xff 206>, /* rpm_ipc(26) */
 			<0xff 207>, /* rpm_ipc(27) */
+			<0xff 234>, /* lpass_irq_out_spare[6]*/
+			<0xff 235>, /* lpass_irq_out_spare[7]*/
+			<0xff 240>, /* summary_irq_kpss */
+			<0xff 253>, /* sdc2_pwr_cmd_irq */
 			<0xff 258>, /* rpm_ipc(28) */
 			<0xff 259>, /* rpm_ipc(29) */
-			<0xff 275>, /* rpm_ipc(30) */
-			<0xff 276>, /* rpm_ipc(31) */
 			<0xff 269>, /* rpm_wdog_expired_irq */
-			<0xff 240>; /* summary_irq_kpss */
+			<0xff 270>, /* blsp1_bam_irq[0] */
+			<0xff 275>, /* rpm_ipc(30) */
+			<0xff 276>; /* rpm_ipc(31) */
 
 		qcom,gpio-parent = <&msmgpio>;
 		qcom,gpio-map = <3  1>,
diff --git a/arch/arm/boot/dts/msm8610-v2-qrd-skuab-dvt2.dts b/arch/arm/boot/dts/msm8610-v2-qrd-skuab-dvt2.dts
index 95a5da5..2547148 100644
--- a/arch/arm/boot/dts/msm8610-v2-qrd-skuab-dvt2.dts
+++ b/arch/arm/boot/dts/msm8610-v2-qrd-skuab-dvt2.dts
@@ -56,10 +56,26 @@
 &dsi_hx8389b_qhd_vid {
 	qcom,cont-splash-enabled;
 };
+
 &soc {
 	i2c@f9925000 {
 		fsl@1c {
 			fsl,sensors-position = <7>;
 		};
 	};
-};
\ No newline at end of file
+};
+
+&qrd_batterydata {
+	qcom,rpull-up-kohm = <100>;
+	qcom,vref-batt-therm = <1800000>;
+
+	/include/ "batterydata-qrd-4v2-2200mah.dtsi"
+};
+
+&pm8110_bms {
+	qcom,battery-data = <&qrd_batterydata>;
+};
+
+&pm8110_chg {
+	qcom,battery-data = <&qrd_batterydata>;
+};
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index a40d3aa..94a9db0 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -893,8 +893,8 @@
                 qcom,msm-bus,num-cases = <2>;
                 qcom,msm-bus,num-paths = <1>;
                 qcom,msm-bus,vectors-KBps =
-                                <1 618 0 0>,
-                                <1 618 0 800>;
+                                <54 618 0 0>,
+                                <54 618 0 800>;
         };
 
 	qcom,msm-rtb {
diff --git a/arch/arm/boot/dts/msm8926.dtsi b/arch/arm/boot/dts/msm8926.dtsi
index bbddec3..0b876a1 100644
--- a/arch/arm/boot/dts/msm8926.dtsi
+++ b/arch/arm/boot/dts/msm8926.dtsi
@@ -116,20 +116,20 @@
 };
 
 &apc_vreg_corner {
-	qcom,pvs-init-voltage = <1350000 1340000 1330000 1320000 1310000
+	qti,pvs-init-voltage = <1350000 1340000 1330000 1320000 1310000
 					1300000 1290000 1280000 1270000 1260000
 					1250000 1240000 1230000 1220000 1210000
 					1200000 1190000 1180000 1170000 1160000
 					1150000 1140000 1140000 1140000 1140000
 					1140000 1140000 1140000 1140000 1140000
 					1140000 1140000>;
-	qcom,pvs-corner-ceiling-slow = <1050000 1150000 1280000>;
-	qcom,pvs-corner-ceiling-nom  = <1050000 1080000 1200000>;
-	qcom,pvs-corner-ceiling-fast = <1050000 1050000 1140000>;
-	qcom,cpr-step-quotient = <30>;
-	qcom,cpr-up-threshold = <0>;
-	qcom,cpr-down-threshold = <5>;
-	qcom,cpr-apc-volt-step = <10000>;
+	qti,pvs-corner-ceiling-slow = <1050000 1150000 1280000>;
+	qti,pvs-corner-ceiling-nom  = <1050000 1080000 1200000>;
+	qti,pvs-corner-ceiling-fast = <1050000 1050000 1100000>;
+	qti,cpr-step-quotient = <30>;
+	qti,cpr-up-threshold = <0>;
+	qti,cpr-down-threshold = <5>;
+	qti,cpr-apc-volt-step = <10000>;
 };
 
 &tsens {
diff --git a/arch/arm/boot/dts/msm8974-v2.dtsi b/arch/arm/boot/dts/msm8974-v2.dtsi
index 6784068..9176117 100644
--- a/arch/arm/boot/dts/msm8974-v2.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2.dtsi
@@ -87,6 +87,7 @@
 	qcom,mdss-has-bwc;
 	qcom,mdss-has-decimation;
 	qcom,mdss-ad-off = <0x0013100 0x00013300>;
+	vdd-cx-supply = <&pm8841_s2_corner>;
 };
 
 &mdss_hdmi_tx {
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index fdf5243..b4a3e55 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -1684,6 +1684,10 @@
 		compatible = "qcom,msm-lsm-client";
 	};
 
+	qti,msm-pcm-loopback {
+		compatible = "qti,msm-pcm-loopback";
+	};
+
 	qcom,msm-dai-q6 {
 		compatible = "qcom,msm-dai-q6";
 		qcom,msm-dai-q6-sb-0-rx {
@@ -1986,14 +1990,15 @@
 		qcom,disk-encrypt-pipe-pair = <2>;
 		qcom,hlos-ce-hw-instance = <1>;
 		qcom,qsee-ce-hw-instance = <0>;
+		qcom,support-bus-scaling = <1>;
 		qcom,msm-bus,name = "qseecom-noc";
 		qcom,msm-bus,num-cases = <4>;
 		qcom,msm-bus,num-paths = <1>;
 		qcom,msm-bus,vectors-KBps =
 				<55 512 0 0>,
-				<55 512 3936000 393600>,
-				<55 512 3936000 393600>,
-				<55 512 3936000 393600>;
+				<55 512 0 0>,
+				<55 512 120000 1200000>,
+				<55 512 393600 3936000>;
 	};
 
 	qcom,wdt@f9017000 {
@@ -2178,6 +2183,10 @@
 		qcom,hotplug-temp-hysteresis = <20>;
 		qcom,cpu-sensors = "tsens_tz_sensor5", "tsens_tz_sensor6",
 				"tsens_tz_sensor7", "tsens_tz_sensor8";
+		qcom,freq-mitigation-temp = <110>;
+		qcom,freq-mitigation-temp-hysteresis = <20>;
+		qcom,freq-mitigation-value = <960000>;
+		qcom,freq-mitigation-control-mask = <0x01>;
 		qcom,vdd-restriction-temp = <5>;
 		qcom,vdd-restriction-temp-hysteresis = <10>;
 		qcom,pmic-sw-mode-temp = <85>;
diff --git a/arch/arm/boot/dts/msm8974pro-pm.dtsi b/arch/arm/boot/dts/msm8974pro-pm.dtsi
index 366faef..938a2cc 100644
--- a/arch/arm/boot/dts/msm8974pro-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pm.dtsi
@@ -214,6 +214,7 @@
 			<50 172>, /* usb1_hs_async_wakeup_irq */
 			<53 104>, /* mdss_irq */
 			<62 222>, /* ee0_krait_hlos_spmi_periph_irq */
+			<0xff 33>, /*l2_perf_mon*/
 			<0xff 34>,  /* APCC_qgicL2ErrorIrptReq */
 			<0xff 35>,  /* WDT_barkInt */
 			<0xff 40>,  /* qtimer_phy_irq */
diff --git a/arch/arm/boot/dts/msm8974pro-pma8084.dtsi b/arch/arm/boot/dts/msm8974pro-pma8084.dtsi
index 2693642..71fbeae 100644
--- a/arch/arm/boot/dts/msm8974pro-pma8084.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pma8084.dtsi
@@ -152,6 +152,9 @@
 	qcom,msm-thermal {
 		vdd-dig-supply = <&pma8084_s2_floor_corner>;
 		vdd-gfx-supply = <&pma8084_s7_floor_corner>;
+		qti,pmic-opt-curr-temp = <85>;
+		qti,pmic-opt-curr-temp-hysteresis = <10>;
+		qti,pmic-opt-curr-regs = "vdd-dig";
 		/delete-property/ qcom,pmic-sw-mode-temp;
 		/delete-property/ qcom,pmic-sw-mode-temp-hysteresis;
 		/delete-property/ qcom,pmic-sw-mode-regs;
@@ -180,6 +183,10 @@
 	qcom,use-phase-switching;
 };
 
+&mdss_mdp {
+	vdd-cx-supply = <&pma8084_s2_corner>;
+};
+
 &tspp {
 	vdd_cx-supply = <&pma8084_s2_corner>;
 };
diff --git a/arch/arm/configs/apq8084_defconfig b/arch/arm/configs/apq8084_defconfig
index cda1e59..968a5ee 100644
--- a/arch/arm/configs/apq8084_defconfig
+++ b/arch/arm/configs/apq8084_defconfig
@@ -378,6 +378,7 @@
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_LOCKUP_DETECTOR=y
 # CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_SYSRQ_SCHED_DEBUG is not set
 CONFIG_SCHEDSTATS=y
 CONFIG_TIMER_STATS=y
 CONFIG_DEBUG_KMEMLEAK=y
diff --git a/arch/arm/configs/fsm9xxx-perf_defconfig b/arch/arm/configs/fsm9xxx-perf_defconfig
index 37c9554..30b2346 100644
--- a/arch/arm/configs/fsm9xxx-perf_defconfig
+++ b/arch/arm/configs/fsm9xxx-perf_defconfig
@@ -185,3 +185,5 @@
 CONFIG_CRYPTO_DEV_QCE=y
 CONFIG_CRYPTO_DEV_OTA_CRYPTO=y
 CONFIG_CRC_CCITT=y
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index 431ac58..9af4009 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -399,3 +399,5 @@
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
 CONFIG_CRYPTO_TWOFISH=y
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msm8226-perf_defconfig b/arch/arm/configs/msm8226-perf_defconfig
index c47a474..1e32cfa 100644
--- a/arch/arm/configs/msm8226-perf_defconfig
+++ b/arch/arm/configs/msm8226-perf_defconfig
@@ -429,6 +429,7 @@
 CONFIG_NLS_ISO8859_1=y
 CONFIG_PRINTK_TIME=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SYSRQ_SCHED_DEBUG is not set
 CONFIG_SCHEDSTATS=y
 CONFIG_TIMER_STATS=y
 CONFIG_DEBUG_INFO=y
@@ -456,5 +457,6 @@
 CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y
 CONFIG_TOUCHSCREEN_GT9XX=y
 CONFIG_GT9XX_TOUCHPANEL_DRIVER=y
-CONFIG_DEFAULT_ROW=y
 CONFIG_MSM_RDBG=m
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msm8226_defconfig b/arch/arm/configs/msm8226_defconfig
index a163103..cedb6dc 100644
--- a/arch/arm/configs/msm8226_defconfig
+++ b/arch/arm/configs/msm8226_defconfig
@@ -468,6 +468,7 @@
 CONFIG_NLS_ISO8859_1=y
 CONFIG_PRINTK_TIME=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SYSRQ_SCHED_DEBUG is not set
 CONFIG_SCHEDSTATS=y
 CONFIG_TIMER_STATS=y
 CONFIG_DEBUG_KMEMLEAK=y
@@ -510,5 +511,4 @@
 CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y
 CONFIG_TOUCHSCREEN_GT9XX=y
 CONFIG_GT9XX_TOUCHPANEL_DRIVER=y
-CONFIG_DEFAULT_ROW=y
 CONFIG_MSM_RDBG=m
diff --git a/arch/arm/configs/msm8610-perf_defconfig b/arch/arm/configs/msm8610-perf_defconfig
index a6443ba..e46bfef 100644
--- a/arch/arm/configs/msm8610-perf_defconfig
+++ b/arch/arm/configs/msm8610-perf_defconfig
@@ -64,11 +64,6 @@
 CONFIG_MSM_MEMORY_DUMP=y
 CONFIG_MSM_DLOAD_MODE=y
 CONFIG_MSM_ADSP_LOADER=y
-CONFIG_MSM_OCMEM=y
-CONFIG_MSM_OCMEM_LOCAL_POWER_CTRL=y
-CONFIG_MSM_OCMEM_DEBUG=y
-CONFIG_MSM_OCMEM_NONSECURE=y
-CONFIG_MSM_OCMEM_POWER_DISABLE=y
 CONFIG_SENSORS_ADSP=y
 CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL=y
 CONFIG_MSM_BOOT_STATS=y
@@ -80,6 +75,7 @@
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_COMPACTION=y
+CONFIG_KSM=y
 CONFIG_CC_STACKPROTECTOR=y
 CONFIG_KSM=y
 CONFIG_ENABLE_VMALLOC_SAVING=y
@@ -319,6 +315,7 @@
 CONFIG_FB_MSM=y
 # CONFIG_FB_MSM_BACKLIGHT is not set
 CONFIG_FB_MSM_MDSS=y
+CONFIG_FB_MSM_MDSS_MDP3=y
 CONFIG_FB_MSM_MDSS_WRITEBACK=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 # CONFIG_LCD_CLASS_DEVICE is not set
@@ -392,6 +389,7 @@
 CONFIG_NLS_ISO8859_1=y
 CONFIG_PRINTK_TIME=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SYSRQ_SCHED_DEBUG is not set
 CONFIG_SCHEDSTATS=y
 CONFIG_TIMER_STATS=y
 CONFIG_DEBUG_INFO=y
@@ -428,3 +426,5 @@
 CONFIG_SENSORS_CAPELLA_CM36283=y
 CONFIG_NFC_QNCI=y
 CONFIG_MSM_RDBG=m
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index 80fe046..899ed30 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -61,11 +61,6 @@
 CONFIG_MSM_MEMORY_DUMP=y
 CONFIG_MSM_DLOAD_MODE=y
 CONFIG_MSM_ADSP_LOADER=y
-CONFIG_MSM_OCMEM=y
-CONFIG_MSM_OCMEM_LOCAL_POWER_CTRL=y
-CONFIG_MSM_OCMEM_DEBUG=y
-CONFIG_MSM_OCMEM_NONSECURE=y
-CONFIG_MSM_OCMEM_POWER_DISABLE=y
 CONFIG_SENSORS_ADSP=y
 CONFIG_MSM_RTB=y
 CONFIG_MSM_RTB_SEPARATE_CPUS=y
@@ -81,6 +76,7 @@
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_COMPACTION=y
+CONFIG_KSM=y
 CONFIG_CC_STACKPROTECTOR=y
 CONFIG_KSM=y
 CONFIG_ENABLE_VMALLOC_SAVING=y
@@ -342,6 +338,7 @@
 CONFIG_FB_MSM=y
 # CONFIG_FB_MSM_BACKLIGHT is not set
 CONFIG_FB_MSM_MDSS=y
+CONFIG_FB_MSM_MDSS_MDP3=y
 CONFIG_FB_MSM_MDSS_WRITEBACK=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 # CONFIG_LCD_CLASS_DEVICE is not set
@@ -430,6 +427,7 @@
 CONFIG_NLS_ISO8859_1=y
 CONFIG_PRINTK_TIME=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SYSRQ_SCHED_DEBUG is not set
 CONFIG_SCHEDSTATS=y
 CONFIG_TIMER_STATS=y
 CONFIG_DEBUG_KMEMLEAK=y
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index da4de08..b4f21ad 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -461,3 +461,5 @@
 CONFIG_CRYPTO_DEV_QCRYPTO=m
 CONFIG_CRYPTO_DEV_QCE=m
 CONFIG_CRYPTO_DEV_QCEDEV=m
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 4610597..fd8245f 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -554,3 +554,5 @@
 CONFIG_CRYPTO_DEV_QCE=m
 CONFIG_CRYPTO_DEV_QCEDEV=m
 CONFIG_CRC_CCITT=y
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 82f4ee2..10f2919 100755
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -98,6 +98,7 @@
 CONFIG_CC_STACKPROTECTOR=y
 CONFIG_CP_ACCESS=y
 CONFIG_USE_OF=y
+CONFIG_SECURE_TOUCH=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
@@ -476,6 +477,7 @@
 CONFIG_NLS_ISO8859_1=y
 CONFIG_PRINTK_TIME=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SYSRQ_SCHED_DEBUG is not set
 CONFIG_SCHEDSTATS=y
 CONFIG_TIMER_STATS=y
 # CONFIG_DEBUG_PREEMPT is not set
@@ -503,3 +505,5 @@
 CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y
 CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
 CONFIG_MSM_RDBG=m
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 9051f8f..0b9ba76 100755
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -104,6 +104,7 @@
 CONFIG_CC_STACKPROTECTOR=y
 CONFIG_CP_ACCESS=y
 CONFIG_USE_OF=y
+CONFIG_SECURE_TOUCH=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
@@ -502,6 +503,7 @@
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_LOCKUP_DETECTOR=y
 # CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_SYSRQ_SCHED_DEBUG is not set
 CONFIG_SCHEDSTATS=y
 CONFIG_TIMER_STATS=y
 CONFIG_DEBUG_KMEMLEAK=y
diff --git a/arch/arm/configs/msm9625-perf_defconfig b/arch/arm/configs/msm9625-perf_defconfig
index 9a5aaf0..4c0a82d 100644
--- a/arch/arm/configs/msm9625-perf_defconfig
+++ b/arch/arm/configs/msm9625-perf_defconfig
@@ -319,3 +319,5 @@
 CONFIG_CRC_CCITT=y
 CONFIG_LIBCRC32C=y
 CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msmkrypton_defconfig b/arch/arm/configs/msmkrypton_defconfig
index b04acb5..380a730 100644
--- a/arch/arm/configs/msmkrypton_defconfig
+++ b/arch/arm/configs/msmkrypton_defconfig
@@ -133,6 +133,7 @@
 CONFIG_NLS_ISO8859_1=y
 CONFIG_PRINTK_TIME=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SYSRQ_SCHED_DEBUG is not set
 CONFIG_SCHEDSTATS=y
 CONFIG_TIMER_STATS=y
 # CONFIG_DEBUG_PREEMPT is not set
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 4fc1590..4e60414 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -25,10 +25,7 @@
 obj-y += acpuclock.o
 obj-$(CONFIG_MSM_CORTEX_A7) += clock-a7.o
 obj-$(CONFIG_HW_PERF_EVENTS) += perf_trace_counters.o
-obj-$(CONFIG_ARCH_MSM_KRAIT) += acpuclock-krait.o clock-krait.o
-ifdef CONFIG_ARCH_MSM_KRAIT
-obj-$(CONFIG_DEBUG_FS) += acpuclock-krait-debug.o
-endif
+obj-$(CONFIG_ARCH_MSM_KRAIT) += clock-krait.o
 obj-$(CONFIG_ARCH_MSM7X27) += acpuclock-7627.o acpuclock-8625q.o clock-pll.o
 obj-$(CONFIG_ARCH_MSM_SCORPIONMP) += perf_event_msm_l2.o
 ifndef CONFIG_OF
@@ -258,12 +255,10 @@
 obj-$(CONFIG_MACH_MSM7X25_FFA) += board-msm7x27.o devices-msm7x25.o
 obj-$(CONFIG_ARCH_MSM8960) += clock-local.o clock-dss-8960.o clock-8960.o clock-rpm.o clock-pll.o
 obj-$(CONFIG_ARCH_MSM8960) += footswitch-8x60.o
-obj-$(CONFIG_ARCH_MSM8960) += acpuclock-8960.o acpuclock-8960ab.o
 obj-$(CONFIG_ARCH_MSM8960) += memory_topology.o
 obj-$(CONFIG_ARCH_MSM8960) += saw-regulator.o
 obj-$(CONFIG_ARCH_MSM8960) += devices-8960.o
 obj-$(CONFIG_ARCH_APQ8064) += devices-8960.o devices-8064.o
-obj-$(CONFIG_ARCH_APQ8064) += acpuclock-8064.o
 board-8960-all-objs += board-8960.o board-8960-camera.o board-8960-display.o board-8960-pmic.o board-8960-storage.o board-8960-gpiomux.o
 board-8930-all-objs += board-8930.o board-8930-camera.o board-8930-display.o board-8930-pmic.o board-8930-storage.o board-8930-gpiomux.o devices-8930.o board-8930-gpu.o
 board-8064-all-objs += board-8064.o board-8064-pmic.o board-8064-storage.o board-8064-gpiomux.o board-8064-camera.o board-8064-display.o board-8064-gpu.o
@@ -286,7 +281,7 @@
 obj-$(CONFIG_ARCH_APQ8084) += board-8084.o board-8084-gpiomux.o
 obj-$(CONFIG_ARCH_APQ8084) += clock-8084.o
 obj-$(CONFIG_ARCH_MSM8974) += board-8974.o board-8974-gpiomux.o
-obj-$(CONFIG_ARCH_MSM8974) += acpuclock-8974.o clock-krait-8974.o
+obj-$(CONFIG_ARCH_MSM8974) += clock-krait-8974.o
 obj-$(CONFIG_ARCH_MSM8974) += clock-local2.o clock-pll.o clock-8974.o clock-rpm.o clock-voter.o clock-mdss-8974.o
 obj-$(CONFIG_ARCH_MSM8974) += gdsc.o
 obj-$(CONFIG_ARCH_MSM9625) += gdsc.o
@@ -299,7 +294,6 @@
 obj-$(CONFIG_ARCH_MSMSAMARIUM) += board-samarium.o board-samarium-gpiomux.o
 obj-$(CONFIG_ARCH_MSM9625) += board-9625.o board-9625-gpiomux.o
 obj-$(CONFIG_ARCH_MSM9625) += clock-local2.o clock-pll.o clock-9625.o clock-rpm.o clock-voter.o acpuclock-9625.o acpuclock-cortex.o
-obj-$(CONFIG_ARCH_MSM8930) += acpuclock-8930.o acpuclock-8627.o acpuclock-8930aa.o acpuclock-8930ab.o
 obj-$(CONFIG_ARCH_MPQ8092) += board-8092.o board-8092-gpiomux.o
 obj-$(CONFIG_ARCH_MPQ8092) += clock-8092.o
 obj-$(CONFIG_ARCH_MSM8226) += board-8226.o board-8226-gpiomux.o
diff --git a/arch/arm/mach-msm/acpuclock-8064.c b/arch/arm/mach-msm/acpuclock-8064.c
deleted file mode 100644
index 8262946..0000000
--- a/arch/arm/mach-msm/acpuclock-8064.c
+++ /dev/null
@@ -1,679 +0,0 @@
-/*
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <mach/rpm-regulator.h>
-#include <mach/msm_bus_board.h>
-#include <mach/msm_bus.h>
-
-#include "mach/socinfo.h"
-#include "acpuclock.h"
-#include "acpuclock-krait.h"
-
-static struct hfpll_data hfpll_data __initdata = {
-	.mode_offset = 0x00,
-	.l_offset = 0x08,
-	.m_offset = 0x0C,
-	.n_offset = 0x10,
-	.config_offset = 0x04,
-	.config_val = 0x7845C665,
-	.has_droop_ctl = true,
-	.droop_offset = 0x14,
-	.droop_val = 0x0108C000,
-	.low_vdd_l_max = 22,
-	.nom_vdd_l_max = 42,
-	.vdd[HFPLL_VDD_NONE] =       0,
-	.vdd[HFPLL_VDD_LOW]  =  945000,
-	.vdd[HFPLL_VDD_NOM]  = 1050000,
-	.vdd[HFPLL_VDD_HIGH] = 1150000,
-};
-
-static struct scalable scalable[] __initdata = {
-	[CPU0] = {
-		.hfpll_phys_base = 0x00903200,
-		.aux_clk_sel_phys = 0x02088014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x4501,
-		.vreg[VREG_CORE] = { "krait0", 1300000 },
-		.vreg[VREG_MEM]  = { "krait0_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait0_dig", 1150000 },
-		.vreg[VREG_HFPLL_A] = { "krait0_hfpll", 1800000 },
-	},
-	[CPU1] = {
-		.hfpll_phys_base = 0x00903240,
-		.aux_clk_sel_phys = 0x02098014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x5501,
-		.vreg[VREG_CORE] = { "krait1", 1300000 },
-		.vreg[VREG_MEM]  = { "krait1_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait1_dig", 1150000 },
-		.vreg[VREG_HFPLL_A] = { "krait1_hfpll", 1800000 },
-	},
-	[CPU2] = {
-		.hfpll_phys_base = 0x00903280,
-		.aux_clk_sel_phys = 0x020A8014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x6501,
-		.vreg[VREG_CORE] = { "krait2", 1300000 },
-		.vreg[VREG_MEM]  = { "krait2_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait2_dig", 1150000 },
-		.vreg[VREG_HFPLL_A] = { "krait2_hfpll", 1800000 },
-	},
-	[CPU3] = {
-		.hfpll_phys_base = 0x009032C0,
-		.aux_clk_sel_phys = 0x020B8014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x7501,
-		.vreg[VREG_CORE] = { "krait3", 1300000 },
-		.vreg[VREG_MEM]  = { "krait3_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait3_dig", 1150000 },
-		.vreg[VREG_HFPLL_A] = { "krait3_hfpll", 1800000 },
-	},
-	[L2] = {
-		.hfpll_phys_base = 0x00903300,
-		.aux_clk_sel_phys = 0x02011028,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x0500,
-		.vreg[VREG_HFPLL_A] = { "l2_hfpll", 1800000 },
-	},
-};
-
-/*
- * The correct maximum rate for 8064ab in 600 MHZ.
- * We rely on the RPM rounding requests up here.
-*/
-static struct msm_bus_paths bw_level_tbl[] __initdata = {
-	[0] =  BW_MBPS(640), /* At least  80 MHz on bus. */
-	[1] = BW_MBPS(1064), /* At least 133 MHz on bus. */
-	[2] = BW_MBPS(1600), /* At least 200 MHz on bus. */
-	[3] = BW_MBPS(2128), /* At least 266 MHz on bus. */
-	[4] = BW_MBPS(3200), /* At least 400 MHz on bus. */
-	[5] = BW_MBPS(4264), /* At least 533 MHz on bus. */
-};
-
-static struct msm_bus_scale_pdata bus_scale_data __initdata = {
-	.usecase = bw_level_tbl,
-	.num_usecases = ARRAY_SIZE(bw_level_tbl),
-	.active_only = 1,
-	.name = "acpuclk-8064",
-};
-
-static struct l2_level l2_freq_tbl[] __initdata = {
-	[0]  = { {  384000, PLL_8, 0, 0x00 },  950000, 1050000, 1 },
-	[1]  = { {  432000, HFPLL, 2, 0x20 }, 1050000, 1050000, 2 },
-	[2]  = { {  486000, HFPLL, 2, 0x24 }, 1050000, 1050000, 2 },
-	[3]  = { {  540000, HFPLL, 2, 0x28 }, 1050000, 1050000, 2 },
-	[4]  = { {  594000, HFPLL, 1, 0x16 }, 1050000, 1050000, 2 },
-	[5]  = { {  648000, HFPLL, 1, 0x18 }, 1050000, 1050000, 4 },
-	[6]  = { {  702000, HFPLL, 1, 0x1A }, 1150000, 1150000, 4 },
-	[7]  = { {  756000, HFPLL, 1, 0x1C }, 1150000, 1150000, 4 },
-	[8]  = { {  810000, HFPLL, 1, 0x1E }, 1150000, 1150000, 4 },
-	[9]  = { {  864000, HFPLL, 1, 0x20 }, 1150000, 1150000, 4 },
-	[10] = { {  918000, HFPLL, 1, 0x22 }, 1150000, 1150000, 5 },
-	[11] = { {  972000, HFPLL, 1, 0x24 }, 1150000, 1150000, 5 },
-	[12] = { { 1026000, HFPLL, 1, 0x26 }, 1150000, 1150000, 5 },
-	[13] = { { 1080000, HFPLL, 1, 0x28 }, 1150000, 1150000, 5 },
-	[14] = { { 1134000, HFPLL, 1, 0x2A }, 1150000, 1150000, 5 },
-	{ }
-};
-
-static struct acpu_level tbl_slow[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   975000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   975000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),  1000000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),  1000000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),  1025000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),  1025000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(5),  1075000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),  1075000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(5),  1100000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1100000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(5),  1125000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1125000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(14), 1175000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1175000 },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(14), 1200000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1200000 },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(14), 1225000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1225000 },
-	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(14), 1237500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1237500 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1250000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_nom[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   925000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   925000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),   950000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),   975000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   975000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(5),  1025000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),  1025000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(5),  1050000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1050000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(5),  1075000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1075000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(14), 1125000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1125000 },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(14), 1150000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1150000 },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(14), 1175000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1175000 },
-	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(14), 1187500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1187500 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1200000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_fast[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   850000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),   925000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   925000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(5),   975000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   975000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(5),  1000000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1000000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(5),  1025000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1025000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(14), 1075000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1075000 },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(14), 1100000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1100000 },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(14), 1125000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1125000 },
-	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(14), 1137500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1137500 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1150000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_faster[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   850000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),   925000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   925000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(5),   962500 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   962500 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(5),   975000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   975000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(5),  1000000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1000000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(14), 1050000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1050000 },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(14), 1075000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1075000 },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(14), 1100000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1100000 },
-	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(14), 1112500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1112500 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1125000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS0_1512MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   950000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   962500 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),  1000000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1025000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1037500 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1075000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1087500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1125000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1150000 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1162500 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS1_1512MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   950000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   962500 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   975000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1000000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1012500 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1037500 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1050000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1087500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1112500 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1125000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS2_1512MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   925000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   925000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   925000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   925000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   937500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   950000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   975000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1000000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1012500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1037500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1075000 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1087500 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS3_1512MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   900000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   900000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   925000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   950000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  975000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  987500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1000000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1037500 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1050000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS4_1512MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  950000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  962500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14),  975000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1000000 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1012500 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS5_1512MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  937500 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  950000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14),  962500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14),  987500 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1000000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS6_1512MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  937500 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  950000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14),  962500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14),  975000 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14),  987500 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS0_1700MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   950000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   962500 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),  1000000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1025000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1037500 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1075000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1087500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1125000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1150000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1175000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1225000 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(14), 1250000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS1_1700MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   950000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   962500 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   975000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1000000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1012500 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1037500 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1050000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1087500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1112500 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1150000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1187500 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(14), 1200000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS2_1700MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   925000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   925000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   925000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   925000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   937500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   950000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   975000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1000000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1012500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1037500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1075000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1100000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1137500 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(14), 1162500 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS3_1700MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   900000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   900000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   925000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   950000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  975000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  987500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1000000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1037500 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1062500 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1100000 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(14), 1125000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS4_1700MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  950000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  962500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14),  975000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1000000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1037500 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1075000 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(14), 1100000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS5_1700MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  937500 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  950000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14),  962500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14),  987500 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1012500 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1050000 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(14), 1075000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS6_1700MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  937500 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  950000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14),  962500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14),  975000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1000000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1025000 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(14), 1050000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS0_2000MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   950000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   950000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   962500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   975000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1000000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1025000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1037500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1062500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1100000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1125000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1175000 },
-	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(14), 1225000 },
-	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(14), 1287500 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS1_2000MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   925000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   925000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   925000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   925000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   937500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   950000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   975000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1000000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1012500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1037500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1075000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1100000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1137500 },
-	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(14), 1187500 },
-	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(14), 1250000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS2_2000MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   900000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   912500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   925000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   950000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  975000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  987500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1012500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1050000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1075000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1112500 },
-	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(14), 1162500 },
-	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(14), 1212500 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS3_2000MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   900000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   900000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   912500 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   937500 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  962500 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  975000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1000000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1025000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1050000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1087500 },
-	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(14), 1137500 },
-	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(14), 1175000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS4_2000MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  950000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  962500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14),  975000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1000000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1037500 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1075000 },
-	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(14), 1112500 },
-	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(14), 1150000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS5_2000MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  937500 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  950000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14),  962500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14),  987500 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1012500 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1050000 },
-	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(14), 1087500 },
-	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(14), 1125000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS6_2000MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  937500 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  950000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14),  962500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14),  975000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1000000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1025000 },
-	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(14), 1062500 },
-	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(14), 1100000 },
-	{ 0, { 0 } }
-};
-
-static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
-	[0][PVS_SLOW]    = {tbl_slow, sizeof(tbl_slow),     0 },
-	[0][PVS_NOMINAL] = {tbl_nom,  sizeof(tbl_nom),  25000 },
-	[0][PVS_FAST]    = {tbl_fast, sizeof(tbl_fast), 25000 },
-	[0][PVS_FASTER]  = {tbl_faster, sizeof(tbl_faster), 25000 },
-
-	[1][0] = { tbl_PVS0_1700MHz, sizeof(tbl_PVS0_1700MHz),     0 },
-	[1][1] = { tbl_PVS1_1700MHz, sizeof(tbl_PVS1_1700MHz),     25000 },
-	[1][2] = { tbl_PVS2_1700MHz, sizeof(tbl_PVS2_1700MHz),     25000 },
-	[1][3] = { tbl_PVS3_1700MHz, sizeof(tbl_PVS3_1700MHz),     25000 },
-	[1][4] = { tbl_PVS4_1700MHz, sizeof(tbl_PVS4_1700MHz),     25000 },
-	[1][5] = { tbl_PVS5_1700MHz, sizeof(tbl_PVS5_1700MHz),     25000 },
-	[1][6] = { tbl_PVS6_1700MHz, sizeof(tbl_PVS6_1700MHz),     25000 },
-
-	[2][0] = { tbl_PVS0_2000MHz, sizeof(tbl_PVS0_2000MHz),     0 },
-	[2][1] = { tbl_PVS1_2000MHz, sizeof(tbl_PVS1_2000MHz),     25000 },
-	[2][2] = { tbl_PVS2_2000MHz, sizeof(tbl_PVS2_2000MHz),     25000 },
-	[2][3] = { tbl_PVS3_2000MHz, sizeof(tbl_PVS3_2000MHz),     25000 },
-	[2][4] = { tbl_PVS4_2000MHz, sizeof(tbl_PVS4_2000MHz),     25000 },
-	[2][5] = { tbl_PVS5_2000MHz, sizeof(tbl_PVS5_2000MHz),     25000 },
-	[2][6] = { tbl_PVS6_2000MHz, sizeof(tbl_PVS6_2000MHz),     25000 },
-
-	[14][0] = { tbl_PVS0_1512MHz, sizeof(tbl_PVS0_1512MHz),     0 },
-	[14][1] = { tbl_PVS1_1512MHz, sizeof(tbl_PVS1_1512MHz),     25000 },
-	[14][2] = { tbl_PVS2_1512MHz, sizeof(tbl_PVS2_1512MHz),     25000 },
-	[14][3] = { tbl_PVS3_1512MHz, sizeof(tbl_PVS3_1512MHz),     25000 },
-	[14][4] = { tbl_PVS4_1512MHz, sizeof(tbl_PVS4_1512MHz),     25000 },
-	[14][5] = { tbl_PVS5_1512MHz, sizeof(tbl_PVS5_1512MHz),     25000 },
-	[14][6] = { tbl_PVS6_1512MHz, sizeof(tbl_PVS6_1512MHz),     25000 },
-};
-
-static struct acpuclk_krait_params acpuclk_8064_params __initdata = {
-	.scalable = scalable,
-	.scalable_size = sizeof(scalable),
-	.hfpll_data = &hfpll_data,
-	.pvs_tables = pvs_tables,
-	.l2_freq_tbl = l2_freq_tbl,
-	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
-	.bus_scale = &bus_scale_data,
-	.pte_efuse_phys = 0x007000C0,
-	.get_bin_info = get_krait_bin_format_a,
-	.stby_khz = 384000,
-};
-
-static int __init acpuclk_8064_probe(struct platform_device *pdev)
-{
-	if (cpu_is_apq8064ab() ||
-		SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2) {
-		acpuclk_8064_params.hfpll_data->low_vdd_l_max = 37;
-		acpuclk_8064_params.hfpll_data->nom_vdd_l_max = 74;
-	}
-
-	return acpuclk_krait_init(&pdev->dev, &acpuclk_8064_params);
-}
-
-static struct platform_driver acpuclk_8064_driver = {
-	.driver = {
-		.name = "acpuclk-8064",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init acpuclk_8064_init(void)
-{
-	return platform_driver_probe(&acpuclk_8064_driver,
-				     acpuclk_8064_probe);
-}
-device_initcall(acpuclk_8064_init);
diff --git a/arch/arm/mach-msm/acpuclock-8627.c b/arch/arm/mach-msm/acpuclock-8627.c
deleted file mode 100644
index 405b26b..0000000
--- a/arch/arm/mach-msm/acpuclock-8627.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <mach/rpm-regulator.h>
-#include <mach/msm_bus_board.h>
-#include <mach/msm_bus.h>
-
-#include "acpuclock.h"
-#include "acpuclock-krait.h"
-
-/* Corner type vreg VDD values */
-#define LVL_NONE	RPM_VREG_CORNER_NONE
-#define LVL_LOW		RPM_VREG_CORNER_LOW
-#define LVL_NOM		RPM_VREG_CORNER_NOMINAL
-#define LVL_HIGH	RPM_VREG_CORNER_HIGH
-
-static struct hfpll_data hfpll_data __initdata = {
-	.mode_offset = 0x00,
-	.l_offset = 0x08,
-	.m_offset = 0x0C,
-	.n_offset = 0x10,
-	.config_offset = 0x04,
-	.config_val = 0x7845C665,
-	.has_droop_ctl = true,
-	.droop_offset = 0x14,
-	.droop_val = 0x0108C000,
-	.low_vdd_l_max = 22,
-	.nom_vdd_l_max = 42,
-	.vdd[HFPLL_VDD_NONE] = LVL_NONE,
-	.vdd[HFPLL_VDD_LOW]  = LVL_LOW,
-	.vdd[HFPLL_VDD_NOM]  = LVL_NOM,
-	.vdd[HFPLL_VDD_HIGH] = LVL_HIGH,
-};
-
-static struct scalable scalable[] __initdata = {
-	[CPU0] = {
-		.hfpll_phys_base = 0x00903200,
-		.aux_clk_sel_phys = 0x02088014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x4501,
-		.vreg[VREG_CORE] = { "krait0", 1300000 },
-		.vreg[VREG_MEM]  = { "krait0_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait0_dig", 1150000 },
-		.vreg[VREG_HFPLL_A] = { "krait0_hfpll", 1800000 },
-	},
-	[CPU1] = {
-		.hfpll_phys_base = 0x00903300,
-		.aux_clk_sel_phys = 0x02098014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x5501,
-		.vreg[VREG_CORE] = { "krait1", 1300000 },
-		.vreg[VREG_MEM]  = { "krait1_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait1_dig", 1150000 },
-		.vreg[VREG_HFPLL_A] = { "krait1_hfpll", 1800000 },
-	},
-	[L2] = {
-		.hfpll_phys_base = 0x00903400,
-		.aux_clk_sel_phys = 0x02011028,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x0500,
-		.vreg[VREG_HFPLL_A] = { "l2_hfpll", 1800000 },
-	},
-};
-
-static struct msm_bus_paths bw_level_tbl[] __initdata = {
-	[0] =  BW_MBPS(640), /* At least  80 MHz on bus. */
-	[1] = BW_MBPS(1064), /* At least 133 MHz on bus. */
-	[2] = BW_MBPS(1600), /* At least 200 MHz on bus. */
-	[3] = BW_MBPS(2128), /* At least 266 MHz on bus. */
-	[4] = BW_MBPS(3200), /* At least 400 MHz on bus. */
-};
-
-static struct msm_bus_scale_pdata bus_scale_data __initdata = {
-	.usecase = bw_level_tbl,
-	.num_usecases = ARRAY_SIZE(bw_level_tbl),
-	.active_only = 1,
-	.name = "acpuclk-8627",
-};
-
-/* TODO: Update vdd_dig, vdd_mem and bw when data is available. */
-static struct l2_level l2_freq_tbl[] __initdata = {
-	[0]  = { {  384000, PLL_8, 0, 0x00 },  LVL_NOM, 1050000, 1 },
-	[1]  = { {  432000, HFPLL, 2, 0x20 },  LVL_NOM, 1050000, 1 },
-	[2]  = { {  486000, HFPLL, 2, 0x24 },  LVL_NOM, 1050000, 1 },
-	[3]  = { {  540000, HFPLL, 2, 0x28 },  LVL_NOM, 1050000, 2 },
-	[4]  = { {  594000, HFPLL, 1, 0x16 },  LVL_NOM, 1050000, 2 },
-	[5]  = { {  648000, HFPLL, 1, 0x18 },  LVL_NOM, 1050000, 2 },
-	[6]  = { {  702000, HFPLL, 1, 0x1A },  LVL_NOM, 1050000, 3 },
-	[7]  = { {  756000, HFPLL, 1, 0x1C }, LVL_HIGH, 1150000, 3 },
-	[8]  = { {  810000, HFPLL, 1, 0x1E }, LVL_HIGH, 1150000, 3 },
-	[9]  = { {  864000, HFPLL, 1, 0x20 }, LVL_HIGH, 1150000, 4 },
-	[10] = { {  918000, HFPLL, 1, 0x22 }, LVL_HIGH, 1150000, 4 },
-	[11] = { {  972000, HFPLL, 1, 0x24 }, LVL_HIGH, 1150000, 4 },
-	{ }
-};
-
-/* TODO: Update core voltages when data is available. */
-static struct acpu_level acpu_freq_tbl[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
-	{ 1, {   432000, HFPLL, 2, 0x20 }, L2(4),   925000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(4),   925000 },
-	{ 1, {   540000, HFPLL, 2, 0x28 }, L2(4),   937500 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(4),   962500 },
-	{ 1, {   648000, HFPLL, 1, 0x18 }, L2(8),   987500 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(8),  1000000 },
-	{ 1, {   756000, HFPLL, 1, 0x1C }, L2(8),  1025000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(8),  1062500 },
-	{ 1, {   864000, HFPLL, 1, 0x20 }, L2(11), 1062500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(11), 1087500 },
-	{ 1, {   972000, HFPLL, 1, 0x24 }, L2(11), 1100000 },
-	{ 0, { 0 } }
-};
-
-static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
-	[0][PVS_SLOW]    = { acpu_freq_tbl, sizeof(acpu_freq_tbl),     0 },
-	[0][PVS_NOMINAL] = { acpu_freq_tbl, sizeof(acpu_freq_tbl), 25000 },
-	[0][PVS_FAST]    = { acpu_freq_tbl, sizeof(acpu_freq_tbl), 25000 },
-};
-
-static struct acpuclk_krait_params acpuclk_8627_params __initdata = {
-	.scalable = scalable,
-	.scalable_size = sizeof(scalable),
-	.hfpll_data = &hfpll_data,
-	.pvs_tables = pvs_tables,
-	.l2_freq_tbl = l2_freq_tbl,
-	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
-	.bus_scale = &bus_scale_data,
-	.pte_efuse_phys = 0x007000C0,
-	.get_bin_info = get_krait_bin_format_a,
-	.stby_khz = 384000,
-};
-
-static int __init acpuclk_8627_probe(struct platform_device *pdev)
-{
-	return acpuclk_krait_init(&pdev->dev, &acpuclk_8627_params);
-}
-
-static struct platform_driver acpuclk_8627_driver = {
-	.driver = {
-		.name = "acpuclk-8627",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init acpuclk_8627_init(void)
-{
-	return platform_driver_probe(&acpuclk_8627_driver,
-				     acpuclk_8627_probe);
-}
-device_initcall(acpuclk_8627_init);
diff --git a/arch/arm/mach-msm/acpuclock-8930.c b/arch/arm/mach-msm/acpuclock-8930.c
deleted file mode 100644
index e29d6fe..0000000
--- a/arch/arm/mach-msm/acpuclock-8930.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <mach/rpm-regulator.h>
-#include <mach/msm_bus_board.h>
-#include <mach/msm_bus.h>
-
-#include "acpuclock.h"
-#include "acpuclock-krait.h"
-
-/* Corner type vreg VDD values */
-#define LVL_NONE	RPM_VREG_CORNER_NONE
-#define LVL_LOW		RPM_VREG_CORNER_LOW
-#define LVL_NOM		RPM_VREG_CORNER_NOMINAL
-#define LVL_HIGH	RPM_VREG_CORNER_HIGH
-
-static struct hfpll_data hfpll_data __initdata = {
-	.mode_offset = 0x00,
-	.l_offset = 0x08,
-	.m_offset = 0x0C,
-	.n_offset = 0x10,
-	.config_offset = 0x04,
-	.config_val = 0x7845C665,
-	.has_droop_ctl = true,
-	.droop_offset = 0x14,
-	.droop_val = 0x0108C000,
-	.low_vdd_l_max = 22,
-	.nom_vdd_l_max = 42,
-	.vdd[HFPLL_VDD_NONE] = LVL_NONE,
-	.vdd[HFPLL_VDD_LOW]  = LVL_LOW,
-	.vdd[HFPLL_VDD_NOM]  = LVL_NOM,
-	.vdd[HFPLL_VDD_HIGH] = LVL_HIGH,
-};
-
-static struct scalable scalable_pm8917[] __initdata = {
-	[CPU0] = {
-		.hfpll_phys_base = 0x00903200,
-		.aux_clk_sel_phys = 0x02088014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x4501,
-		.vreg[VREG_CORE] = { "krait0", 1300000 },
-		.vreg[VREG_MEM]  = { "krait0_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait0_dig", LVL_HIGH},
-		.vreg[VREG_HFPLL_A] = { "krait0_s8", 2050000 },
-		.vreg[VREG_HFPLL_B] = { "krait0_l23", 1800000 },
-	},
-	[CPU1] = {
-		.hfpll_phys_base = 0x00903300,
-		.aux_clk_sel_phys = 0x02098014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x5501,
-		.vreg[VREG_CORE] = { "krait1", 1300000 },
-		.vreg[VREG_MEM]  = { "krait1_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait1_dig", LVL_HIGH},
-		.vreg[VREG_HFPLL_A] = { "krait1_s8", 2050000 },
-		.vreg[VREG_HFPLL_B] = { "krait1_l23", 1800000 },
-	},
-	[L2] = {
-		.hfpll_phys_base = 0x00903400,
-		.aux_clk_sel_phys = 0x02011028,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x0500,
-		.vreg[VREG_HFPLL_A] = { "l2_s8", 2050000 },
-		.vreg[VREG_HFPLL_B] = { "l2_l23", 1800000 },
-	},
-};
-
-static struct scalable scalable[] __initdata = {
-	[CPU0] = {
-		.hfpll_phys_base = 0x00903200,
-		.aux_clk_sel_phys = 0x02088014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x4501,
-		.vreg[VREG_CORE] = { "krait0", 1300000 },
-		.vreg[VREG_MEM]  = { "krait0_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait0_dig", LVL_HIGH},
-		.vreg[VREG_HFPLL_A] = { "krait0_hfpll", 1800000 },
-	},
-	[CPU1] = {
-		.hfpll_phys_base = 0x00903300,
-		.aux_clk_sel_phys = 0x02098014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x5501,
-		.vreg[VREG_CORE] = { "krait1", 1300000 },
-		.vreg[VREG_MEM]  = { "krait1_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait1_dig", LVL_HIGH},
-		.vreg[VREG_HFPLL_A] = { "krait1_hfpll", 1800000 },
-	},
-	[L2] = {
-		.hfpll_phys_base = 0x00903400,
-		.aux_clk_sel_phys = 0x02011028,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x0500,
-		.vreg[VREG_HFPLL_A] = { "l2_hfpll", 1800000 },
-	},
-};
-
-static struct msm_bus_paths bw_level_tbl[] __initdata = {
-	[0] =  BW_MBPS(640), /* At least  80 MHz on bus. */
-	[1] = BW_MBPS(1064), /* At least 133 MHz on bus. */
-	[2] = BW_MBPS(1600), /* At least 200 MHz on bus. */
-	[3] = BW_MBPS(2128), /* At least 266 MHz on bus. */
-	[4] = BW_MBPS(3200), /* At least 400 MHz on bus. */
-	[5] = BW_MBPS(3600), /* At least 450 MHz on bus. */
-	[6] = BW_MBPS(3936), /* At least 492 MHz on bus. */
-	[7] = BW_MBPS(4264), /* At least 533 MHz on bus. */
-};
-
-static struct msm_bus_scale_pdata bus_scale_data __initdata = {
-	.usecase = bw_level_tbl,
-	.num_usecases = ARRAY_SIZE(bw_level_tbl),
-	.active_only = 1,
-	.name = "acpuclk-8930",
-};
-
-static struct l2_level l2_freq_tbl[] __initdata = {
-	[0]  = { {  384000, PLL_8, 0, 0x00 },  LVL_LOW, 1050000, 1 },
-	[1]  = { {  432000, HFPLL, 2, 0x20 },  LVL_NOM, 1050000, 2 },
-	[2]  = { {  486000, HFPLL, 2, 0x24 },  LVL_NOM, 1050000, 2 },
-	[3]  = { {  540000, HFPLL, 2, 0x28 },  LVL_NOM, 1050000, 2 },
-	[4]  = { {  594000, HFPLL, 1, 0x16 },  LVL_NOM, 1050000, 2 },
-	[5]  = { {  648000, HFPLL, 1, 0x18 },  LVL_NOM, 1050000, 4 },
-	[6]  = { {  702000, HFPLL, 1, 0x1A },  LVL_NOM, 1050000, 4 },
-	[7]  = { {  756000, HFPLL, 1, 0x1C }, LVL_HIGH, 1150000, 4 },
-	[8]  = { {  810000, HFPLL, 1, 0x1E }, LVL_HIGH, 1150000, 4 },
-	[9]  = { {  864000, HFPLL, 1, 0x20 }, LVL_HIGH, 1150000, 4 },
-	[10] = { {  918000, HFPLL, 1, 0x22 }, LVL_HIGH, 1150000, 7 },
-	[11] = { {  972000, HFPLL, 1, 0x24 }, LVL_HIGH, 1150000, 7 },
-	[12] = { { 1026000, HFPLL, 1, 0x26 }, LVL_HIGH, 1150000, 7 },
-	[13] = { { 1080000, HFPLL, 1, 0x28 }, LVL_HIGH, 1150000, 7 },
-	[14] = { { 1134000, HFPLL, 1, 0x2A }, LVL_HIGH, 1150000, 7 },
-	[15] = { { 1188000, HFPLL, 1, 0x2C }, LVL_HIGH, 1150000, 7 },
-	{ }
-};
-
-static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   975000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   975000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),  1000000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),  1000000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),  1025000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),  1025000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1075000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1100000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1125000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
-	{ 1, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   925000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   950000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   950000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),   975000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   975000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),  1000000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),  1000000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(10), 1050000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1050000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(10), 1075000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1075000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(10), 1100000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1100000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1150000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1150000 },
-	{ 1, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1175000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   900000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   900000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),   925000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   925000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),   950000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   950000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(10), 1000000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1000000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(10), 1025000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1025000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(10), 1050000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1050000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1100000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1100000 },
-	{ 1, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1125000 },
-	{ 0, { 0 } }
-};
-
-static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
-[0][PVS_SLOW]    = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow),     0 },
-[0][PVS_NOMINAL] = { acpu_freq_tbl_nom,  sizeof(acpu_freq_tbl_nom),  25000 },
-[0][PVS_FAST]    = { acpu_freq_tbl_fast, sizeof(acpu_freq_tbl_fast), 25000 },
-};
-
-static struct acpuclk_krait_params acpuclk_8930_params __initdata = {
-	.scalable = scalable,
-	.scalable_size = sizeof(scalable),
-	.hfpll_data = &hfpll_data,
-	.pvs_tables = pvs_tables,
-	.l2_freq_tbl = l2_freq_tbl,
-	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
-	.bus_scale = &bus_scale_data,
-	.pte_efuse_phys = 0x007000C0,
-	.get_bin_info = get_krait_bin_format_a,
-	.stby_khz = 384000,
-};
-
-static int __init acpuclk_8930_probe(struct platform_device *pdev)
-{
-	struct acpuclk_platform_data *pdata = pdev->dev.platform_data;
-	if (pdata && pdata->uses_pm8917)
-		acpuclk_8930_params.scalable = scalable_pm8917;
-
-	return acpuclk_krait_init(&pdev->dev, &acpuclk_8930_params);
-}
-
-static struct platform_driver acpuclk_8930_driver = {
-	.driver = {
-		.name = "acpuclk-8930",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init acpuclk_8930_init(void)
-{
-	return platform_driver_probe(&acpuclk_8930_driver,
-				     acpuclk_8930_probe);
-}
-device_initcall(acpuclk_8930_init);
diff --git a/arch/arm/mach-msm/acpuclock-8930aa.c b/arch/arm/mach-msm/acpuclock-8930aa.c
deleted file mode 100644
index c824323..0000000
--- a/arch/arm/mach-msm/acpuclock-8930aa.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <mach/rpm-regulator.h>
-#include <mach/msm_bus_board.h>
-#include <mach/msm_bus.h>
-
-#include "acpuclock.h"
-#include "acpuclock-krait.h"
-
-/* Corner type vreg VDD values */
-#define LVL_NONE	RPM_VREG_CORNER_NONE
-#define LVL_LOW		RPM_VREG_CORNER_LOW
-#define LVL_NOM		RPM_VREG_CORNER_NOMINAL
-#define LVL_HIGH	RPM_VREG_CORNER_HIGH
-
-static struct hfpll_data hfpll_data __initdata = {
-	.mode_offset = 0x00,
-	.l_offset = 0x08,
-	.m_offset = 0x0C,
-	.n_offset = 0x10,
-	.config_offset = 0x04,
-	.config_val = 0x7845C665,
-	.has_droop_ctl = true,
-	.droop_offset = 0x14,
-	.droop_val = 0x0108C000,
-	.low_vdd_l_max = 22,
-	.nom_vdd_l_max = 42,
-	.vdd[HFPLL_VDD_NONE] = LVL_NONE,
-	.vdd[HFPLL_VDD_LOW]  = LVL_LOW,
-	.vdd[HFPLL_VDD_NOM]  = LVL_NOM,
-	.vdd[HFPLL_VDD_HIGH] = LVL_HIGH,
-};
-
-static struct scalable scalable[] __initdata = {
-	[CPU0] = {
-		.hfpll_phys_base = 0x00903200,
-		.aux_clk_sel_phys = 0x02088014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x4501,
-		.vreg[VREG_CORE] = { "krait0", 1300000 },
-		.vreg[VREG_MEM]  = { "krait0_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait0_dig", LVL_HIGH},
-		.vreg[VREG_HFPLL_A] = { "krait0_hfpll", 1800000 },
-	},
-	[CPU1] = {
-		.hfpll_phys_base = 0x00903300,
-		.aux_clk_sel_phys = 0x02098014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x5501,
-		.vreg[VREG_CORE] = { "krait1", 1300000 },
-		.vreg[VREG_MEM]  = { "krait1_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait1_dig", LVL_HIGH},
-		.vreg[VREG_HFPLL_A] = { "krait1_hfpll", 1800000 },
-	},
-	[L2] = {
-		.hfpll_phys_base = 0x00903400,
-		.aux_clk_sel_phys = 0x02011028,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x0500,
-		.vreg[VREG_HFPLL_A] = { "l2_hfpll", 1800000 },
-	},
-};
-
-static struct msm_bus_paths bw_level_tbl[] __initdata = {
-	[0] =  BW_MBPS(640), /* At least  80 MHz on bus. */
-	[1] = BW_MBPS(1064), /* At least 133 MHz on bus. */
-	[2] = BW_MBPS(1600), /* At least 200 MHz on bus. */
-	[3] = BW_MBPS(2128), /* At least 266 MHz on bus. */
-	[4] = BW_MBPS(3200), /* At least 400 MHz on bus. */
-	[5] = BW_MBPS(3600), /* At least 450 MHz on bus. */
-	[6] = BW_MBPS(3936), /* At least 492 MHz on bus. */
-	[7] = BW_MBPS(4264), /* At least 533 MHz on bus. */
-};
-
-static struct msm_bus_scale_pdata bus_scale_data __initdata = {
-	.usecase = bw_level_tbl,
-	.num_usecases = ARRAY_SIZE(bw_level_tbl),
-	.active_only = 1,
-	.name = "acpuclk-8930aa",
-};
-
-static struct l2_level l2_freq_tbl[] __initdata = {
-	[0]  = { {  384000, PLL_8, 0, 0x00 },  LVL_LOW, 1050000, 1 },
-	[1]  = { {  432000, HFPLL, 2, 0x20 },  LVL_NOM, 1050000, 2 },
-	[2]  = { {  486000, HFPLL, 2, 0x24 },  LVL_NOM, 1050000, 2 },
-	[3]  = { {  540000, HFPLL, 2, 0x28 },  LVL_NOM, 1050000, 2 },
-	[4]  = { {  594000, HFPLL, 1, 0x16 },  LVL_NOM, 1050000, 2 },
-	[5]  = { {  648000, HFPLL, 1, 0x18 },  LVL_NOM, 1050000, 4 },
-	[6]  = { {  702000, HFPLL, 1, 0x1A },  LVL_NOM, 1050000, 4 },
-	[7]  = { {  756000, HFPLL, 1, 0x1C }, LVL_HIGH, 1150000, 4 },
-	[8]  = { {  810000, HFPLL, 1, 0x1E }, LVL_HIGH, 1150000, 4 },
-	[9]  = { {  864000, HFPLL, 1, 0x20 }, LVL_HIGH, 1150000, 4 },
-	[10] = { {  918000, HFPLL, 1, 0x22 }, LVL_HIGH, 1150000, 7 },
-	[11] = { {  972000, HFPLL, 1, 0x24 }, LVL_HIGH, 1150000, 7 },
-	[12] = { { 1026000, HFPLL, 1, 0x26 }, LVL_HIGH, 1150000, 7 },
-	[13] = { { 1080000, HFPLL, 1, 0x28 }, LVL_HIGH, 1150000, 7 },
-	[14] = { { 1134000, HFPLL, 1, 0x2A }, LVL_HIGH, 1150000, 7 },
-	[15] = { { 1188000, HFPLL, 1, 0x2C }, LVL_HIGH, 1150000, 7 },
-	{ }
-};
-
-static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   975000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   975000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),  1000000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),  1000000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),  1025000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),  1025000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1075000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1100000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1125000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1200000 },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1225000 },
-	{ 1, {  1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   925000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   950000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   950000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),   975000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   975000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),  1000000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),  1000000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(10), 1050000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1050000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(10), 1075000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1075000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(10), 1100000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1100000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1150000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1150000 },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1175000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1175000 },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(15), 1200000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1200000 },
-	{ 1, {  1404000, HFPLL, 1, 0x34 }, L2(15), 1212500 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   900000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   900000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),   925000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   925000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),   950000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   950000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(10), 1000000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1000000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(10), 1025000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1025000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(10), 1050000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1050000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1100000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1100000 },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1125000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1125000 },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(15), 1150000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1150000 },
-	{ 1, {  1404000, HFPLL, 1, 0x34 }, L2(15), 1162500 },
-	{ 0, { 0 } }
-};
-
-static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
-[0][PVS_SLOW]    = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow),     0 },
-[0][PVS_NOMINAL] = { acpu_freq_tbl_nom,  sizeof(acpu_freq_tbl_nom),  25000 },
-[0][PVS_FAST]    = { acpu_freq_tbl_fast, sizeof(acpu_freq_tbl_fast), 25000 },
-};
-
-static struct acpuclk_krait_params acpuclk_8930aa_params __initdata = {
-	.scalable = scalable,
-	.scalable_size = sizeof(scalable),
-	.hfpll_data = &hfpll_data,
-	.pvs_tables = pvs_tables,
-	.l2_freq_tbl = l2_freq_tbl,
-	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
-	.bus_scale = &bus_scale_data,
-	.pte_efuse_phys = 0x007000C0,
-	.get_bin_info = get_krait_bin_format_a,
-	.stby_khz = 384000,
-};
-
-static int __init acpuclk_8930aa_probe(struct platform_device *pdev)
-{
-	return acpuclk_krait_init(&pdev->dev, &acpuclk_8930aa_params);
-}
-
-static struct platform_driver acpuclk_8930aa_driver = {
-	.driver = {
-		.name = "acpuclk-8930aa",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init acpuclk_8930aa_init(void)
-{
-	return platform_driver_probe(&acpuclk_8930aa_driver,
-				     acpuclk_8930aa_probe);
-}
-device_initcall(acpuclk_8930aa_init);
diff --git a/arch/arm/mach-msm/acpuclock-8930ab.c b/arch/arm/mach-msm/acpuclock-8930ab.c
deleted file mode 100644
index 7ec267b..0000000
--- a/arch/arm/mach-msm/acpuclock-8930ab.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <mach/rpm-regulator.h>
-#include <mach/msm_bus_board.h>
-#include <mach/msm_bus.h>
-
-#include "acpuclock.h"
-#include "acpuclock-krait.h"
-
-/* Corner type vreg VDD values */
-#define LVL_NONE	RPM_VREG_CORNER_NONE
-#define LVL_LOW		RPM_VREG_CORNER_LOW
-#define LVL_NOM		RPM_VREG_CORNER_NOMINAL
-#define LVL_HIGH	RPM_VREG_CORNER_HIGH
-
-static struct hfpll_data hfpll_data __initdata = {
-	.mode_offset = 0x00,
-	.l_offset = 0x08,
-	.m_offset = 0x0C,
-	.n_offset = 0x10,
-	.config_offset = 0x04,
-	.config_val = 0x7845C665,
-	.has_droop_ctl = true,
-	.droop_offset = 0x14,
-	.droop_val = 0x0108C000,
-	.low_vdd_l_max = 37,
-	.nom_vdd_l_max = 74,
-	.vdd[HFPLL_VDD_NONE] = LVL_NONE,
-	.vdd[HFPLL_VDD_LOW]  = LVL_LOW,
-	.vdd[HFPLL_VDD_NOM]  = LVL_NOM,
-	.vdd[HFPLL_VDD_HIGH] = LVL_HIGH,
-};
-
-static struct scalable scalable_pm8917[] __initdata = {
-	[CPU0] = {
-		.hfpll_phys_base = 0x00903200,
-		.aux_clk_sel_phys = 0x02088014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x4501,
-		.vreg[VREG_CORE] = { "krait0", 1300000 },
-		.vreg[VREG_MEM]  = { "krait0_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait0_dig", LVL_HIGH},
-		.vreg[VREG_HFPLL_A] = { "krait0_s8", 2050000 },
-		.vreg[VREG_HFPLL_B] = { "krait0_l23", 1800000 },
-	},
-	[CPU1] = {
-		.hfpll_phys_base = 0x00903300,
-		.aux_clk_sel_phys = 0x02098014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x5501,
-		.vreg[VREG_CORE] = { "krait1", 1300000 },
-		.vreg[VREG_MEM]  = { "krait1_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait1_dig", LVL_HIGH},
-		.vreg[VREG_HFPLL_A] = { "krait1_s8", 2050000 },
-		.vreg[VREG_HFPLL_B] = { "krait1_l23", 1800000 },
-	},
-	[L2] = {
-		.hfpll_phys_base = 0x00903400,
-		.aux_clk_sel_phys = 0x02011028,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x0500,
-		.vreg[VREG_HFPLL_A] = { "l2_s8", 2050000 },
-		.vreg[VREG_HFPLL_B] = { "l2_l23", 1800000 },
-	},
-};
-
-static struct scalable scalable[] __initdata = {
-	[CPU0] = {
-		.hfpll_phys_base = 0x00903200,
-		.aux_clk_sel_phys = 0x02088014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x4501,
-		.vreg[VREG_CORE] = { "krait0", 1300000 },
-		.vreg[VREG_MEM]  = { "krait0_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait0_dig", LVL_HIGH},
-		.vreg[VREG_HFPLL_A] = { "krait0_hfpll", 1800000 },
-	},
-	[CPU1] = {
-		.hfpll_phys_base = 0x00903300,
-		.aux_clk_sel_phys = 0x02098014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x5501,
-		.vreg[VREG_CORE] = { "krait1", 1300000 },
-		.vreg[VREG_MEM]  = { "krait1_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait1_dig", LVL_HIGH},
-		.vreg[VREG_HFPLL_A] = { "krait1_hfpll", 1800000 },
-	},
-	[L2] = {
-		.hfpll_phys_base = 0x00903400,
-		.aux_clk_sel_phys = 0x02011028,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x0500,
-		.vreg[VREG_HFPLL_A] = { "l2_hfpll", 1800000 },
-	},
-};
-
-static struct msm_bus_paths bw_level_tbl[] __initdata = {
-	[0] =  BW_MBPS(640), /* At least  80 MHz on bus. */
-	[1] = BW_MBPS(1064), /* At least 133 MHz on bus. */
-	[2] = BW_MBPS(1600), /* At least 200 MHz on bus. */
-	[3] = BW_MBPS(2128), /* At least 266 MHz on bus. */
-	[4] = BW_MBPS(3200), /* At least 400 MHz on bus. */
-	[5] = BW_MBPS(4800), /* At least 600 MHz on bus. */
-};
-
-static struct msm_bus_scale_pdata bus_scale_data __initdata = {
-	.usecase = bw_level_tbl,
-	.num_usecases = ARRAY_SIZE(bw_level_tbl),
-	.active_only = 1,
-	.name = "acpuclk-8930ab",
-};
-
-static struct l2_level l2_freq_tbl[] __initdata = {
-	[0]  = { {  384000, PLL_8, 0, 0x00 },  LVL_LOW, 1050000, 1 },
-	[1]  = { {  432000, HFPLL, 2, 0x20 },  LVL_NOM, 1050000, 2 },
-	[2]  = { {  486000, HFPLL, 2, 0x24 },  LVL_NOM, 1050000, 2 },
-	[3]  = { {  540000, HFPLL, 2, 0x28 },  LVL_NOM, 1050000, 2 },
-	[4]  = { {  594000, HFPLL, 1, 0x16 },  LVL_NOM, 1050000, 2 },
-	[5]  = { {  648000, HFPLL, 1, 0x18 },  LVL_NOM, 1050000, 4 },
-	[6]  = { {  702000, HFPLL, 1, 0x1A },  LVL_NOM, 1050000, 4 },
-	[7]  = { {  756000, HFPLL, 1, 0x1C }, LVL_HIGH, 1150000, 4 },
-	[8]  = { {  810000, HFPLL, 1, 0x1E }, LVL_HIGH, 1150000, 4 },
-	[9]  = { {  864000, HFPLL, 1, 0x20 }, LVL_HIGH, 1150000, 4 },
-	[10] = { {  918000, HFPLL, 1, 0x22 }, LVL_HIGH, 1150000, 5 },
-	[11] = { {  972000, HFPLL, 1, 0x24 }, LVL_HIGH, 1150000, 5 },
-	[12] = { { 1026000, HFPLL, 1, 0x26 }, LVL_HIGH, 1150000, 5 },
-	[13] = { { 1080000, HFPLL, 1, 0x28 }, LVL_HIGH, 1150000, 5 },
-	[14] = { { 1134000, HFPLL, 1, 0x2A }, LVL_HIGH, 1150000, 5 },
-	[15] = { { 1188000, HFPLL, 1, 0x2C }, LVL_HIGH, 1150000, 5 },
-	{ }
-};
-
-static struct acpu_level tbl_PVS0_1700MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),  1000000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),  1000000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),  1000000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),  1025000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1050000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1075000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1100000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1125000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1150000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1175000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1200000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1225000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1250000 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1275000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS1_1700MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   975000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   975000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),  1000000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),  1000000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1025000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1050000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1075000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1100000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1125000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1150000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1175000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1200000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1225000 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1250000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS2_1700MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   950000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   975000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10), 1000000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1025000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1050000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1075000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1100000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1125000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1150000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1175000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1200000 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1225000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS3_1700MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   925000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   925000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   925000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   950000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10),  975000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10), 1000000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1025000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1050000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1075000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1100000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1125000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1150000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1175000 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1200000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS4_1700MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   925000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   925000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   925000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   925000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10),  950000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10),  975000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10), 1000000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1025000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1050000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1075000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1100000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1125000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1150000 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1175000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS5_1700MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   900000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10),  925000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10),  950000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10),  975000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1000000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1025000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1050000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1075000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1100000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1125000 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1150000 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level tbl_PVS6_1700MHz[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(10),  900000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(10),  925000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(10),  950000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  975000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1000000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1025000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1050000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1075000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1100000 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1125000 },
-	{ 0, { 0 } }
-};
-
-static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
-	[0][0] = { tbl_PVS0_1700MHz, sizeof(tbl_PVS0_1700MHz), 0 },
-	[0][1] = { tbl_PVS1_1700MHz, sizeof(tbl_PVS1_1700MHz), 25000 },
-	[0][2] = { tbl_PVS2_1700MHz, sizeof(tbl_PVS2_1700MHz), 25000 },
-	[0][3] = { tbl_PVS3_1700MHz, sizeof(tbl_PVS3_1700MHz), 25000 },
-	[0][4] = { tbl_PVS4_1700MHz, sizeof(tbl_PVS4_1700MHz), 25000 },
-	[0][5] = { tbl_PVS5_1700MHz, sizeof(tbl_PVS5_1700MHz), 25000 },
-	[0][6] = { tbl_PVS6_1700MHz, sizeof(tbl_PVS6_1700MHz), 25000 },
-};
-
-static struct acpuclk_krait_params acpuclk_8930ab_params __initdata = {
-	.scalable = scalable,
-	.scalable_size = sizeof(scalable),
-	.hfpll_data = &hfpll_data,
-	.pvs_tables = pvs_tables,
-	.l2_freq_tbl = l2_freq_tbl,
-	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
-	.bus_scale = &bus_scale_data,
-	.pte_efuse_phys = 0x007000C0,
-	.get_bin_info = get_krait_bin_format_a,
-	.stby_khz = 384000,
-};
-
-static int __init acpuclk_8930ab_probe(struct platform_device *pdev)
-{
-	struct acpuclk_platform_data *pdata = pdev->dev.platform_data;
-	if (pdata && pdata->uses_pm8917)
-		acpuclk_8930ab_params.scalable = scalable_pm8917;
-
-	return acpuclk_krait_init(&pdev->dev, &acpuclk_8930ab_params);
-}
-
-static struct platform_driver acpuclk_8930ab_driver = {
-	.driver = {
-		.name = "acpuclk-8930ab",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init acpuclk_8930ab_init(void)
-{
-	return platform_driver_probe(&acpuclk_8930ab_driver,
-				     acpuclk_8930ab_probe);
-}
-device_initcall(acpuclk_8930ab_init);
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
deleted file mode 100644
index 317729f..0000000
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <mach/rpm-regulator.h>
-#include <mach/msm_bus_board.h>
-#include <mach/msm_bus.h>
-
-#include "acpuclock.h"
-#include "acpuclock-krait.h"
-
-static struct hfpll_data hfpll_data __initdata = {
-	.mode_offset = 0x00,
-	.l_offset = 0x08,
-	.m_offset = 0x0C,
-	.n_offset = 0x10,
-	.config_offset = 0x04,
-	.config_val = 0x7845C665,
-	.has_droop_ctl = true,
-	.droop_offset = 0x14,
-	.droop_val = 0x0108C000,
-	.low_vdd_l_max = 22,
-	.nom_vdd_l_max = 42,
-	.vdd[HFPLL_VDD_NONE] =       0,
-	.vdd[HFPLL_VDD_LOW]  =  945000,
-	.vdd[HFPLL_VDD_NOM]  = 1050000,
-	.vdd[HFPLL_VDD_HIGH] = 1150000,
-};
-
-static struct scalable scalable[] __initdata = {
-	[CPU0] = {
-		.hfpll_phys_base = 0x00903200,
-		.aux_clk_sel_phys = 0x02088014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x4501,
-		.vreg[VREG_CORE] = { "krait0", 1300000 },
-		.vreg[VREG_MEM]  = { "krait0_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait0_dig", 1150000 },
-		.vreg[VREG_HFPLL_A] = { "krait0_s8", 2050000 },
-		.vreg[VREG_HFPLL_B] = { "krait0_l23", 1800000 },
-	},
-	[CPU1] = {
-		.hfpll_phys_base = 0x00903300,
-		.aux_clk_sel_phys = 0x02098014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x5501,
-		.vreg[VREG_CORE] = { "krait1", 1300000 },
-		.vreg[VREG_MEM]  = { "krait1_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait1_dig", 1150000 },
-		.vreg[VREG_HFPLL_A] = { "krait1_s8", 2050000 },
-		.vreg[VREG_HFPLL_B] = { "krait1_l23", 1800000 },
-	},
-	[L2] = {
-		.hfpll_phys_base = 0x00903400,
-		.aux_clk_sel_phys = 0x02011028,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x0500,
-		.vreg[VREG_HFPLL_A] = { "l2_s8", 2050000 },
-		.vreg[VREG_HFPLL_B] = { "l2_l23", 1800000 },
-	},
-};
-
-static struct msm_bus_paths bw_level_tbl[] __initdata = {
-	[0] =  BW_MBPS(640), /* At least  80 MHz on bus. */
-	[1] = BW_MBPS(1064), /* At least 133 MHz on bus. */
-	[2] = BW_MBPS(1600), /* At least 200 MHz on bus. */
-	[3] = BW_MBPS(2128), /* At least 266 MHz on bus. */
-	[4] = BW_MBPS(3200), /* At least 400 MHz on bus. */
-	[5] = BW_MBPS(3600), /* At least 450 MHz on bus. */
-	[6] = BW_MBPS(3936), /* At least 492 MHz on bus. */
-};
-
-static struct msm_bus_scale_pdata bus_scale_data __initdata = {
-	.usecase = bw_level_tbl,
-	.num_usecases = ARRAY_SIZE(bw_level_tbl),
-	.active_only = 1,
-	.name = "acpuclk-8960",
-};
-
-static struct l2_level l2_freq_tbl[] __initdata = {
-	[0]  = { {  384000, PLL_8, 0, 0x00 }, 1050000, 1050000, 1 },
-	[1]  = { {  432000, HFPLL, 2, 0x20 }, 1050000, 1050000, 2 },
-	[2]  = { {  486000, HFPLL, 2, 0x24 }, 1050000, 1050000, 2 },
-	[3]  = { {  540000, HFPLL, 2, 0x28 }, 1050000, 1050000, 2 },
-	[4]  = { {  594000, HFPLL, 1, 0x16 }, 1050000, 1050000, 2 },
-	[5]  = { {  648000, HFPLL, 1, 0x18 }, 1050000, 1050000, 4 },
-	[6]  = { {  702000, HFPLL, 1, 0x1A }, 1050000, 1050000, 4 },
-	[7]  = { {  756000, HFPLL, 1, 0x1C }, 1150000, 1150000, 4 },
-	[8]  = { {  810000, HFPLL, 1, 0x1E }, 1150000, 1150000, 4 },
-	[9]  = { {  864000, HFPLL, 1, 0x20 }, 1150000, 1150000, 4 },
-	[10] = { {  918000, HFPLL, 1, 0x22 }, 1150000, 1150000, 6 },
-	[11] = { {  972000, HFPLL, 1, 0x24 }, 1150000, 1150000, 6 },
-	[12] = { { 1026000, HFPLL, 1, 0x26 }, 1150000, 1150000, 6 },
-	[13] = { { 1080000, HFPLL, 1, 0x28 }, 1150000, 1150000, 6 },
-	[14] = { { 1134000, HFPLL, 1, 0x2A }, 1150000, 1150000, 6 },
-	[15] = { { 1188000, HFPLL, 1, 0x2C }, 1150000, 1150000, 6 },
-	[16] = { { 1242000, HFPLL, 1, 0x2E }, 1150000, 1150000, 6 },
-	[17] = { { 1296000, HFPLL, 1, 0x30 }, 1150000, 1150000, 6 },
-	[18] = { { 1350000, HFPLL, 1, 0x32 }, 1150000, 1150000, 6 },
-	{ }
-};
-
-#define AVS(x) .avsdscr_setting = (x)
-
-static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000, AVS(0x40001F) },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(6),   975000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   975000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(6),  1000000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),  1000000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(6),  1025000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),  1025000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(6),  1075000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),  1075000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(6),  1100000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),  1100000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(6),  1125000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),  1125000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(18), 1175000, AVS(0x400015) },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(18), 1175000, AVS(0x400015) },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(18), 1200000, AVS(0x400015) },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(18), 1200000, AVS(0x400015) },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(18), 1225000, AVS(0x400015) },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(18), 1225000, AVS(0x400015) },
-	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(18), 1237500, AVS(0x400015) },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(18), 1237500, AVS(0x100018) },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(18), 1250000, AVS(0x400012) },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000, AVS(0x40007F) },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(6),   925000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   925000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(6),   950000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   950000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(6),   975000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   975000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(6),  1025000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),  1025000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(6),  1050000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),  1050000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(6),  1075000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),  1075000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(18), 1125000, AVS(0x400015) },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(18), 1125000, AVS(0x400015) },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(18), 1150000, AVS(0x400015) },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(18), 1150000, AVS(0x400015) },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(18), 1175000, AVS(0x400015) },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(18), 1175000, AVS(0x400015) },
-	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(18), 1187500, AVS(0x400015) },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(18), 1187500, AVS(0x100018) },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(18), 1200000, AVS(0x400012) },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   850000, AVS(0x4000FF) },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(6),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   875000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(6),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   900000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(6),   925000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   925000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(6),   975000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   975000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(6),  1000000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),  1000000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(6),  1025000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),  1025000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(18), 1075000, AVS(0x10001B) },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(18), 1075000, AVS(0x10001B) },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(18), 1100000, AVS(0x10001B) },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(18), 1100000, AVS(0x10001B) },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(18), 1125000, AVS(0x10001B) },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(18), 1125000, AVS(0x400012) },
-	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(18), 1137500, AVS(0x400012) },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(18), 1137500, AVS(0x400012) },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(18), 1150000, AVS(0x400012) },
-	{ 0, { 0 } }
-};
-
-static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
-[0][PVS_SLOW]    = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow),     0 },
-[0][PVS_NOMINAL] = { acpu_freq_tbl_nom,  sizeof(acpu_freq_tbl_nom),  25000 },
-[0][PVS_FAST]    = { acpu_freq_tbl_fast, sizeof(acpu_freq_tbl_fast), 25000 },
-};
-
-static struct acpuclk_krait_params acpuclk_8960_params __initdata = {
-	.scalable = scalable,
-	.scalable_size = sizeof(scalable),
-	.hfpll_data = &hfpll_data,
-	.pvs_tables = pvs_tables,
-	.l2_freq_tbl = l2_freq_tbl,
-	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
-	.bus_scale = &bus_scale_data,
-	.pte_efuse_phys = 0x007000C0,
-	.get_bin_info = get_krait_bin_format_a,
-	.stby_khz = 384000,
-};
-
-static int __init acpuclk_8960_probe(struct platform_device *pdev)
-{
-	return acpuclk_krait_init(&pdev->dev, &acpuclk_8960_params);
-}
-
-static struct platform_driver acpuclk_8960_driver = {
-	.driver = {
-		.name = "acpuclk-8960",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init acpuclk_8960_init(void)
-{
-	return platform_driver_probe(&acpuclk_8960_driver, acpuclk_8960_probe);
-}
-device_initcall(acpuclk_8960_init);
diff --git a/arch/arm/mach-msm/acpuclock-8960ab.c b/arch/arm/mach-msm/acpuclock-8960ab.c
deleted file mode 100644
index 0fa2cde..0000000
--- a/arch/arm/mach-msm/acpuclock-8960ab.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <mach/rpm-regulator.h>
-#include <mach/msm_bus_board.h>
-#include <mach/msm_bus.h>
-
-#include "acpuclock.h"
-#include "acpuclock-krait.h"
-
-static struct hfpll_data hfpll_data __initdata = {
-	.mode_offset = 0x00,
-	.l_offset = 0x08,
-	.m_offset = 0x0C,
-	.n_offset = 0x10,
-	.config_offset = 0x04,
-	.config_val = 0x7845C665,
-	.has_droop_ctl = true,
-	.droop_offset = 0x14,
-	.droop_val = 0x0108C000,
-	.low_vdd_l_max = 37,
-	.nom_vdd_l_max = 74,
-	.vdd[HFPLL_VDD_NONE] = 0,
-	.vdd[HFPLL_VDD_LOW]  = 945000,
-	.vdd[HFPLL_VDD_NOM]  = 1050000,
-	.vdd[HFPLL_VDD_HIGH] = 1150000,
-};
-
-static struct scalable scalable[] __initdata = {
-	[CPU0] = {
-		.hfpll_phys_base = 0x00903200,
-		.aux_clk_sel_phys = 0x02088014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x4501,
-		.vreg[VREG_CORE] = { "krait0", 1300000 },
-		.vreg[VREG_MEM]  = { "krait0_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait0_dig", 1150000 },
-		.vreg[VREG_HFPLL_A] = { "krait0_s8", 2050000 },
-		.vreg[VREG_HFPLL_B] = { "krait0_l23", 1800000 },
-	},
-	[CPU1] = {
-		.hfpll_phys_base = 0x00903300,
-		.aux_clk_sel_phys = 0x02098014,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x5501,
-		.vreg[VREG_CORE] = { "krait1", 1300000 },
-		.vreg[VREG_MEM]  = { "krait1_mem", 1150000 },
-		.vreg[VREG_DIG]  = { "krait1_dig", 1150000 },
-		.vreg[VREG_HFPLL_A] = { "krait1_s8", 2050000 },
-		.vreg[VREG_HFPLL_B] = { "krait1_l23", 1800000 },
-	},
-	[L2] = {
-		.hfpll_phys_base = 0x00903400,
-		.aux_clk_sel_phys = 0x02011028,
-		.aux_clk_sel = 3,
-		.sec_clk_sel = 2,
-		.l2cpmr_iaddr = 0x0500,
-		.vreg[VREG_HFPLL_A] = { "l2_s8", 2050000 },
-		.vreg[VREG_HFPLL_B] = { "l2_l23", 1800000 },
-	},
-};
-
-static struct msm_bus_paths bw_level_tbl[] __initdata = {
-	[0] =  BW_MBPS(640), /* At least  80 MHz on bus. */
-	[1] = BW_MBPS(1064), /* At least 133 MHz on bus. */
-	[2] = BW_MBPS(1600), /* At least 200 MHz on bus. */
-	[3] = BW_MBPS(2128), /* At least 266 MHz on bus. */
-	[4] = BW_MBPS(3200), /* At least 400 MHz on bus. */
-	[5] = BW_MBPS(4264), /* At least 533 MHz on bus. */
-};
-
-static struct msm_bus_scale_pdata bus_scale_data __initdata = {
-	.usecase = bw_level_tbl,
-	.num_usecases = ARRAY_SIZE(bw_level_tbl),
-	.active_only = 1,
-	.name = "acpuclk-8960ab",
-};
-
-static struct l2_level l2_freq_tbl[] __initdata = {
-	[0]  = { {  384000, PLL_8, 0, 0x00 }, 1050000, 1050000, 1 },
-	[1]  = { {  486000, HFPLL, 2, 0x24 }, 1050000, 1050000, 2 },
-	[2]  = { {  594000, HFPLL, 1, 0x16 }, 1050000, 1050000, 2 },
-	[3]  = { {  702000, HFPLL, 1, 0x1A }, 1050000, 1050000, 4 },
-	[4]  = { {  810000, HFPLL, 1, 0x1E }, 1050000, 1050000, 4 },
-	[5]  = { {  918000, HFPLL, 1, 0x22 }, 1150000, 1150000, 5 },
-	[6]  = { { 1026000, HFPLL, 1, 0x26 }, 1150000, 1150000, 5 },
-	[7]  = { { 1134000, HFPLL, 1, 0x2A }, 1150000, 1150000, 5 },
-	[8]  = { { 1242000, HFPLL, 1, 0x2E }, 1150000, 1150000, 5 },
-	[9]  = { { 1350000, HFPLL, 1, 0x32 }, 1150000, 1150000, 5 },
-	{ }
-};
-
-#define AVS(x) .avsdscr_setting = (x)
-
-static struct acpu_level freq_tbl_PVS0[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000, AVS(0x70001F) },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(4),   950000, AVS(0x0) },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(4),   975000, AVS(0x0) },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(4),  1000000, AVS(0x0) },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(4),  1025000, AVS(0x0) },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(4),  1050000, AVS(0x0) },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(4),  1075000, AVS(0x0) },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(9),  1100000, AVS(0x70000D) },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(9),  1125000, AVS(0x0) },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(9),  1150000, AVS(0x0) },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(9),  1175000, AVS(0x0) },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(9),  1200000, AVS(0x0) },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(9),  1225000, AVS(0x0) },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(9),  1250000, AVS(0x70000B) },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level freq_tbl_PVS1[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   925000, AVS(0x70001F) },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(4),   925000, AVS(0x0) },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(4),   950000, AVS(0x0) },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(4),   975000, AVS(0x0) },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(4),  1000000, AVS(0x0) },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(4),  1025000, AVS(0x0) },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(4),  1050000, AVS(0x0) },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(9),  1075000, AVS(0x70000D) },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(9),  1100000, AVS(0x0) },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(9),  1125000, AVS(0x0) },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(9),  1150000, AVS(0x0) },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(9),  1175000, AVS(0x0) },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(9),  1200000, AVS(0x0) },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(9),  1225000, AVS(0x70000B) },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level freq_tbl_PVS2[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000, AVS(0x70001F) },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(4),   900000, AVS(0x0) },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(4),   925000, AVS(0x0) },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(4),   950000, AVS(0x0) },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(4),   975000, AVS(0x0) },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(4),  1000000, AVS(0x0) },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(4),  1025000, AVS(0x0) },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(9),  1050000, AVS(0x70000D) },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(9),  1075000, AVS(0x0) },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(9),  1100000, AVS(0x0) },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(9),  1125000, AVS(0x0) },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(9),  1150000, AVS(0x0) },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(9),  1175000, AVS(0x0) },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(9),  1200000, AVS(0x70000B) },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level freq_tbl_PVS3[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000, AVS(0x70001F) },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(4),   900000, AVS(0x0) },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(4),   900000, AVS(0x0) },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(4),   925000, AVS(0x0) },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(4),   950000, AVS(0x0) },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(4),   975000, AVS(0x0) },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(4),  1000000, AVS(0x0) },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(9),  1025000, AVS(0x70000D) },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(9),  1050000, AVS(0x0) },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(9),  1075000, AVS(0x0) },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(9),  1100000, AVS(0x0) },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(9),  1125000, AVS(0x0) },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(9),  1150000, AVS(0x0) },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(9),  1175000, AVS(0x70000B) },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level freq_tbl_PVS4[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000, AVS(0x70001F) },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(4),   875000, AVS(0x0) },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(4),   875000, AVS(0x0) },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(4),   900000, AVS(0x0) },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(4),   925000, AVS(0x0) },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(4),   950000, AVS(0x0) },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(4),   975000, AVS(0x0) },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(9),  1000000, AVS(0x70000D) },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(9),  1025000, AVS(0x0) },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(9),  1050000, AVS(0x0) },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(9),  1075000, AVS(0x0) },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(9),  1100000, AVS(0x0) },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(9),  1125000, AVS(0x0) },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(9),  1150000, AVS(0x70000B) },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level freq_tbl_PVS5[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000, AVS(0x70001F) },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(4),   875000, AVS(0x0) },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(4),   875000, AVS(0x0) },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(4),   875000, AVS(0x0) },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(4),   900000, AVS(0x0) },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(4),   925000, AVS(0x0) },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(4),   950000, AVS(0x0) },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(9),   975000, AVS(0x70000D) },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(9),  1000000, AVS(0x0) },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(9),  1025000, AVS(0x0) },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(9),  1050000, AVS(0x0) },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(9),  1075000, AVS(0x0) },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(9),  1100000, AVS(0x0) },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(9),  1125000, AVS(0x70000B) },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level freq_tbl_PVS6[] __initdata = {
-	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   850000, AVS(0x70001F) },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(4),   850000, AVS(0x0) },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(4),   850000, AVS(0x0) },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(4),   850000, AVS(0x0) },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(4),   875000, AVS(0x0) },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(4),   900000, AVS(0x0) },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(4),   925000, AVS(0x0) },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(9),   950000, AVS(0x70000D) },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(9),   975000, AVS(0x0) },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(9),  1000000, AVS(0x0) },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(9),  1025000, AVS(0x0) },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(9),  1050000, AVS(0x0) },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(9),  1075000, AVS(0x0) },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(9),  1100000, AVS(0x70000B) },
-	{ 0, { 0 } }
-};
-
-static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
-[0][0] = { freq_tbl_PVS0, sizeof(freq_tbl_PVS0),  0 },
-[0][1] = { freq_tbl_PVS1, sizeof(freq_tbl_PVS1),  25000 },
-[0][2] = { freq_tbl_PVS2, sizeof(freq_tbl_PVS2),  25000 },
-[0][3] = { freq_tbl_PVS3, sizeof(freq_tbl_PVS3),  25000 },
-[0][4] = { freq_tbl_PVS4, sizeof(freq_tbl_PVS4),  25000 },
-[0][5] = { freq_tbl_PVS5, sizeof(freq_tbl_PVS5),  25000 },
-[0][6] = { freq_tbl_PVS6, sizeof(freq_tbl_PVS6),  25000 },
-};
-
-static struct acpuclk_krait_params acpuclk_8960ab_params __initdata = {
-	.scalable = scalable,
-	.scalable_size = sizeof(scalable),
-	.hfpll_data = &hfpll_data,
-	.pvs_tables = pvs_tables,
-	.l2_freq_tbl = l2_freq_tbl,
-	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
-	.bus_scale = &bus_scale_data,
-	.pte_efuse_phys = 0x007000C0,
-	.get_bin_info = get_krait_bin_format_a,
-	.stby_khz = 384000,
-};
-
-static int __init acpuclk_8960ab_probe(struct platform_device *pdev)
-{
-	return acpuclk_krait_init(&pdev->dev, &acpuclk_8960ab_params);
-}
-
-static struct platform_driver acpuclk_8960ab_driver = {
-	.driver = {
-		.name = "acpuclk-8960ab",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init acpuclk_8960ab_init(void)
-{
-	return platform_driver_probe(&acpuclk_8960ab_driver,
-					acpuclk_8960ab_probe);
-}
-device_initcall(acpuclk_8960ab_init);
diff --git a/arch/arm/mach-msm/acpuclock-8974.c b/arch/arm/mach-msm/acpuclock-8974.c
deleted file mode 100644
index 5117949..0000000
--- a/arch/arm/mach-msm/acpuclock-8974.c
+++ /dev/null
@@ -1,2451 +0,0 @@
-/*
- * 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
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/of.h>
-#include <mach/rpm-regulator-smd.h>
-#include <mach/msm_bus_board.h>
-#include <mach/msm_bus.h>
-#include <mach/socinfo.h>
-
-#include "acpuclock.h"
-#include "acpuclock-krait.h"
-
-/* Corner type vreg VDD values */
-#define LVL_NONE	RPM_REGULATOR_CORNER_NONE
-#define LVL_LOW		RPM_REGULATOR_CORNER_SVS_SOC
-#define LVL_NOM		RPM_REGULATOR_CORNER_NORMAL
-#define LVL_HIGH	RPM_REGULATOR_CORNER_SUPER_TURBO
-
-static struct hfpll_data hfpll_data __initdata = {
-	.mode_offset = 0x00,
-	.l_offset = 0x04,
-	.m_offset = 0x08,
-	.n_offset = 0x0C,
-	.has_user_reg = true,
-	.user_offset = 0x10,
-	.config_offset = 0x14,
-	.user_val = 0x8,
-	.user_vco_mask = BIT(20),
-	.config_val = 0x04D0405D,
-	.has_lock_status = true,
-	.status_offset = 0x1C,
-	.low_vco_l_max = 65,
-	.low_vdd_l_max = 52,
-	.nom_vdd_l_max = 104,
-	.vdd[HFPLL_VDD_NONE] = LVL_NONE,
-	.vdd[HFPLL_VDD_LOW]  = LVL_LOW,
-	.vdd[HFPLL_VDD_NOM]  = LVL_NOM,
-	.vdd[HFPLL_VDD_HIGH] = LVL_HIGH,
-};
-
-static struct scalable scalable[] __initdata = {
-	[CPU0] = {
-		.hfpll_phys_base = 0xF908A000,
-		.l2cpmr_iaddr = 0x4501,
-		.sec_clk_sel = 2,
-		.vreg[VREG_CORE] = { "krait0",     1120000 },
-		.vreg[VREG_MEM]  = { "krait0_mem", 1050000 },
-		.vreg[VREG_DIG]  = { "krait0_dig", LVL_HIGH },
-		.vreg[VREG_HFPLL_A] = { "krait0_hfpll", 1800000 },
-	},
-	[CPU1] = {
-		.hfpll_phys_base = 0xF909A000,
-		.l2cpmr_iaddr = 0x5501,
-		.sec_clk_sel = 2,
-		.vreg[VREG_CORE] = { "krait1",     1120000 },
-		.vreg[VREG_MEM]  = { "krait1_mem", 1050000 },
-		.vreg[VREG_DIG]  = { "krait1_dig", LVL_HIGH },
-		.vreg[VREG_HFPLL_A] = { "krait1_hfpll", 1800000 },
-	},
-	[CPU2] = {
-		.hfpll_phys_base = 0xF90AA000,
-		.l2cpmr_iaddr = 0x6501,
-		.sec_clk_sel = 2,
-		.vreg[VREG_CORE] = { "krait2",     1120000 },
-		.vreg[VREG_MEM]  = { "krait2_mem", 1050000 },
-		.vreg[VREG_DIG]  = { "krait2_dig", LVL_HIGH },
-		.vreg[VREG_HFPLL_A] = { "krait2_hfpll", 1800000 },
-	},
-	[CPU3] = {
-		.hfpll_phys_base = 0xF90BA000,
-		.l2cpmr_iaddr = 0x7501,
-		.sec_clk_sel = 2,
-		.vreg[VREG_CORE] = { "krait3",     1120000 },
-		.vreg[VREG_MEM]  = { "krait3_mem", 1050000 },
-		.vreg[VREG_DIG]  = { "krait3_dig", LVL_HIGH },
-		.vreg[VREG_HFPLL_A] = { "krait3_hfpll", 1800000 },
-	},
-	[L2] = {
-		.hfpll_phys_base = 0xF9016000,
-		.l2cpmr_iaddr = 0x0500,
-		.sec_clk_sel = 2,
-		.vreg[VREG_HFPLL_A] = { "l2_hfpll", 1800000 },
-	},
-};
-
-static struct msm_bus_paths bw_level_tbl[] __initdata = {
-	[0] =  BW_MBPS(600), /* At least  75 MHz on bus. */
-	[1] =  BW_MBPS(800), /* At least 100 MHz on bus. */
-	[2] = BW_MBPS(1200), /* At least 150 MHz on bus. */
-	[3] = BW_MBPS(1600), /* At least 200 MHz on bus. */
-	[4] = BW_MBPS(2456), /* At least 307 MHz on bus. */
-	[5] = BW_MBPS(3680), /* At least 460 MHz on bus. */
-	[6] = BW_MBPS(4912), /* At least 614 MHz on bus. */
-	[7] = BW_MBPS(6400), /* At least 800 MHz on bus. */
-	[8] = BW_MBPS(7448), /* At least 931 MHz on bus. */
-};
-
-static struct l2_level l2_freq_tbl[] __initdata = {
-	[0]  = { {  300000, PLL_0, 0,   0 }, LVL_LOW,   950000, 0 },
-	[1]  = { {  345600, HFPLL, 2,  36 }, LVL_LOW,   950000, 1 },
-	[2]  = { {  422400, HFPLL, 2,  44 }, LVL_LOW,   950000, 2 },
-	[3]  = { {  499200, HFPLL, 2,  52 }, LVL_LOW,   950000, 3 },
-	[4]  = { {  576000, HFPLL, 1,  30 }, LVL_LOW,   950000, 4 },
-	[5]  = { {  652800, HFPLL, 1,  34 }, LVL_NOM,   950000, 4 },
-	[6]  = { {  729600, HFPLL, 1,  38 }, LVL_NOM,   950000, 4 },
-	[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, 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, 6 },
-	[14] = { { 1344000, HFPLL, 1,  70 }, LVL_HIGH, 1050000, 6 },
-	[15] = { { 1420800, HFPLL, 1,  74 }, LVL_HIGH, 1050000, 6 },
-	[16] = { { 1497600, HFPLL, 1,  78 }, LVL_HIGH, 1050000, 6 },
-	[17] = { { 1574400, HFPLL, 1,  82 }, LVL_HIGH, 1050000, 7 },
-	[18] = { { 1651200, HFPLL, 1,  86 }, LVL_HIGH, 1050000, 7 },
-	[19] = { { 1728000, HFPLL, 1,  90 }, LVL_HIGH, 1050000, 8 },
-	{ }
-};
-
-static struct acpu_level acpu_freq_tbl_2g_pvs0[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  815000,  73 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  825000,  85 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  835000, 104 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  845000, 124 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  855000, 144 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  865000, 165 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  875000, 186 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  890000, 208 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  900000, 229 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  915000, 252 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  925000, 275 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  940000, 298 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  950000, 321 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  965000, 346 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  980000, 371 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  995000, 397 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16), 1010000, 423 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17), 1025000, 450 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17), 1040000, 477 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18), 1055000, 506 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18), 1070000, 536 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18), 1085000, 567 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1100000, 598 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2g_pvs1[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  73 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  810000,  85 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  820000, 104 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  830000, 124 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  840000, 144 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  850000, 165 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  860000, 186 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  875000, 208 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  885000, 229 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  895000, 252 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  910000, 275 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  920000, 298 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  930000, 321 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  945000, 346 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  960000, 371 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  975000, 397 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  990000, 423 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17), 1005000, 450 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17), 1020000, 477 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18), 1030000, 506 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18), 1045000, 536 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18), 1060000, 567 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1075000, 598 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2g_pvs2[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  785000,  73 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  795000,  85 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  805000, 104 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  815000, 124 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  825000, 144 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  835000, 165 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  845000, 186 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  855000, 208 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  865000, 229 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  875000, 252 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  890000, 275 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  900000, 298 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  910000, 321 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  925000, 346 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  940000, 371 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  955000, 397 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  970000, 423 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  980000, 450 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  995000, 477 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18), 1005000, 506 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18), 1020000, 536 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18), 1035000, 567 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1050000, 598 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2g_pvs3[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  73 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  780000,  85 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  790000, 104 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  800000, 124 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  810000, 144 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  820000, 165 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  830000, 186 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  840000, 208 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  850000, 229 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  860000, 252 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  875000, 275 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  885000, 298 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  895000, 321 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  910000, 346 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  925000, 371 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  935000, 397 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  950000, 423 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  960000, 450 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  970000, 477 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  985000, 506 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  995000, 536 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18), 1010000, 567 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1025000, 598 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2g_pvs4[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  73 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  85 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  780000, 104 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  790000, 124 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  800000, 144 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  810000, 165 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  820000, 186 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  830000, 208 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  840000, 229 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  850000, 252 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  860000, 275 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  870000, 298 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  880000, 321 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  895000, 346 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  910000, 371 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  920000, 397 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  930000, 423 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  940000, 450 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  950000, 477 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  960000, 506 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  975000, 536 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  985000, 567 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1000000, 598 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2g_pvs5[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  750000,  73 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  760000,  85 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  770000, 104 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  780000, 124 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  790000, 144 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  800000, 165 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  810000, 186 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  820000, 208 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  830000, 229 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  840000, 252 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  850000, 275 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  860000, 298 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  870000, 321 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  880000, 346 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  890000, 371 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  900000, 397 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  910000, 423 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  920000, 450 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  930000, 477 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  940000, 506 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  955000, 536 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  965000, 567 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  975000, 598 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2g_pvs6[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  750000,  73 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  750000,  85 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  760000, 104 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  770000, 124 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  780000, 144 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  790000, 165 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  800000, 186 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  810000, 208 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  820000, 229 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  830000, 252 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  840000, 275 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  850000, 298 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  860000, 321 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  870000, 346 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  875000, 371 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  885000, 397 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  895000, 423 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  905000, 450 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  915000, 477 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  920000, 506 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  930000, 536 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  940000, 567 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  950000, 598 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2p2g_pvs0[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  72 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  800000,  83 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  805000, 102 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  815000, 121 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  825000, 141 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  835000, 161 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  845000, 181 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  855000, 202 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  865000, 223 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  875000, 245 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  890000, 267 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  900000, 289 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  915000, 313 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  925000, 336 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  940000, 360 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  950000, 383 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  965000, 409 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  980000, 435 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  995000, 461 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18), 1010000, 488 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18), 1025000, 516 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18), 1040000, 543 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1055000, 573 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1070000, 604 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1085000, 636 },
-	{ 1, { 2150400, HFPLL, 1, 112 }, L2(19), 1100000, 656 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2p2g_pvs1[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  72 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  800000,  83 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  800000, 102 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  800000, 121 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  810000, 141 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  820000, 161 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  830000, 181 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  840000, 202 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  850000, 223 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  860000, 245 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  875000, 267 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  885000, 289 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  895000, 313 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  910000, 336 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  920000, 360 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  930000, 383 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  945000, 409 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  960000, 435 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  975000, 461 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  990000, 488 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18), 1005000, 516 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18), 1020000, 543 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1030000, 573 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1045000, 604 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1060000, 636 },
-	{ 1, { 2150400, HFPLL, 1, 112 }, L2(19), 1075000, 656 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2p2g_pvs2[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  72 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  83 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 102 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  785000, 121 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  795000, 141 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  805000, 161 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  815000, 181 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  825000, 202 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  835000, 223 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  845000, 245 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  855000, 267 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  865000, 289 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  875000, 313 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  890000, 336 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  900000, 360 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  910000, 383 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  925000, 409 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  940000, 435 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  955000, 461 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  970000, 488 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  980000, 516 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  995000, 543 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1005000, 573 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1020000, 604 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1035000, 636 },
-	{ 1, { 2150400, HFPLL, 1, 112 }, L2(19), 1050000, 656 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2p2g_pvs3[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  72 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  83 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 102 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 121 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  780000, 141 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  790000, 161 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  800000, 181 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  810000, 202 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  820000, 223 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  830000, 245 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  840000, 267 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  850000, 289 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  860000, 313 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  875000, 336 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  885000, 360 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  895000, 383 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  910000, 409 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  925000, 435 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  935000, 461 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  950000, 488 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  960000, 516 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  970000, 543 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  985000, 573 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  995000, 604 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1010000, 636 },
-	{ 1, { 2150400, HFPLL, 1, 112 }, L2(19), 1025000, 656 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2p2g_pvs4[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  72 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  83 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 102 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 121 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 141 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  780000, 161 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  790000, 181 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  800000, 202 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  810000, 223 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  820000, 245 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  830000, 267 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  840000, 289 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  850000, 313 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  860000, 336 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  870000, 360 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  880000, 383 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  895000, 409 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  910000, 435 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  920000, 461 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  930000, 488 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  940000, 516 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  950000, 543 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  960000, 573 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  975000, 604 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  985000, 636 },
-	{ 1, { 2150400, HFPLL, 1, 112 }, L2(19), 1000000, 656 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2p2g_pvs5[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  750000,  72 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  750000,  83 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  750000, 102 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  750000, 121 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  760000, 141 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  770000, 161 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  780000, 181 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  790000, 202 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  800000, 223 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  810000, 245 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  820000, 267 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  830000, 289 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  840000, 313 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  850000, 336 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  860000, 360 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  870000, 383 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  880000, 409 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  890000, 435 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  900000, 461 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  910000, 488 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  920000, 516 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  930000, 543 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  940000, 573 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  955000, 604 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  965000, 636 },
-	{ 1, { 2150400, HFPLL, 1, 112 }, L2(19),  975000, 656 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2p2g_pvs6[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  750000,  72 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  750000,  83 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  750000, 102 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  750000, 121 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  750000, 141 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  760000, 161 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  770000, 181 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  780000, 202 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  790000, 223 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  800000, 245 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  810000, 267 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  820000, 289 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  830000, 313 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  840000, 336 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  850000, 360 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  860000, 383 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  870000, 409 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  875000, 435 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  885000, 461 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  895000, 488 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  905000, 516 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  915000, 543 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  920000, 573 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  930000, 604 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  940000, 636 },
-	{ 1, { 2150400, HFPLL, 1, 112 }, L2(19),  950000, 656 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2p3g_pvs0[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  72 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  800000,  83 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  800000, 101 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  805000, 120 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  815000, 139 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  825000, 159 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  835000, 180 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  845000, 200 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  855000, 221 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  865000, 242 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  875000, 264 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  890000, 287 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  900000, 308 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  915000, 333 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  925000, 356 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  940000, 380 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  950000, 404 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  965000, 430 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  980000, 456 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  995000, 482 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18), 1010000, 510 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18), 1025000, 538 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1040000, 565 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1055000, 596 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1070000, 627 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1085000, 659 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1100000, 691 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2p3g_pvs1[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  72 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  800000,  83 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  800000, 101 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  800000, 120 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  800000, 139 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  810000, 159 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  820000, 180 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  830000, 200 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  840000, 221 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  850000, 242 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  860000, 264 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  875000, 287 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  885000, 308 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  895000, 333 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  910000, 356 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  920000, 380 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  930000, 404 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  945000, 430 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  960000, 456 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  975000, 482 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  990000, 510 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18), 1005000, 538 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1020000, 565 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1030000, 596 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1045000, 627 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1060000, 659 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1075000, 691 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2p3g_pvs2[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  72 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  83 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 101 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 120 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  785000, 139 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  795000, 159 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  805000, 180 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  815000, 200 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  825000, 221 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  835000, 242 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  845000, 264 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  855000, 287 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  865000, 308 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  875000, 333 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  890000, 356 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  900000, 380 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  910000, 404 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  925000, 430 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  940000, 456 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  955000, 482 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  970000, 510 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  980000, 538 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  995000, 565 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1005000, 596 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1020000, 627 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1035000, 659 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1050000, 691 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2p3g_pvs3[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  72 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  83 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 101 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 120 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 139 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  780000, 159 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  790000, 180 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  800000, 200 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  810000, 221 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  820000, 242 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  830000, 264 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  840000, 287 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  850000, 308 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  860000, 333 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  875000, 356 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  885000, 380 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  895000, 404 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  910000, 430 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  925000, 456 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  935000, 482 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  950000, 510 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  960000, 538 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  970000, 565 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  985000, 596 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  995000, 627 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1010000, 659 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1025000, 691 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2p3g_pvs4[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  72 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  83 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 101 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 120 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 139 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  775000, 159 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  780000, 180 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  790000, 200 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  800000, 221 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  810000, 242 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  820000, 264 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  830000, 287 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  840000, 308 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  850000, 333 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  860000, 356 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  870000, 380 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  880000, 404 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  895000, 430 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  910000, 456 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  920000, 482 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  930000, 510 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  940000, 538 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  950000, 565 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  960000, 596 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  975000, 627 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  985000, 659 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1000000, 691 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2p3g_pvs5[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  750000,  72 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  750000,  83 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  750000, 101 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  750000, 120 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  750000, 139 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  760000, 159 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  770000, 180 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  780000, 200 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  790000, 221 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  800000, 242 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  810000, 264 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  820000, 287 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  830000, 308 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  840000, 333 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  850000, 356 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  860000, 380 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  870000, 404 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  880000, 430 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  890000, 456 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  900000, 482 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  910000, 510 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  920000, 538 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  930000, 565 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  940000, 596 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  955000, 627 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  965000, 659 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  975000, 691 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_2p3g_pvs6[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  750000,  72 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  750000,  83 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  750000, 101 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  750000, 120 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  750000, 139 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  750000, 159 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  760000, 180 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  770000, 200 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  780000, 221 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  790000, 242 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  800000, 264 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  810000, 287 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  820000, 308 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  830000, 333 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  840000, 356 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  850000, 380 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  860000, 404 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  870000, 430 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  875000, 456 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  885000, 482 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  895000, 510 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  905000, 538 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  915000, 565 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  920000, 596 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  930000, 627 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  940000, 659 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  950000, 691 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev0_2p3g_pvs0[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  74 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  85 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 104 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  780000, 124 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  790000, 144 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  800000, 164 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  810000, 184 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  820000, 206 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  830000, 227 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  840000, 249 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  850000, 271 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  865000, 295 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  875000, 318 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  890000, 342 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  900000, 365 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  915000, 392 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  925000, 416 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  940000, 442 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  955000, 469 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  970000, 497 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  985000, 525 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18), 1000000, 554 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1015000, 583 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1030000, 613 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1045000, 642 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1060000, 663 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1060000, 675 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1075000, 708 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev0_2p3g_pvs1[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  74 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  85 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 104 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 124 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 144 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  785000, 164 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  795000, 184 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  805000, 206 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  815000, 227 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  825000, 249 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  835000, 271 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  850000, 295 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  860000, 318 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  870000, 342 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  885000, 365 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  895000, 392 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  905000, 416 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  920000, 442 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  935000, 469 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  950000, 497 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  965000, 525 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  980000, 554 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  995000, 583 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1005000, 613 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1020000, 642 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1035000, 663 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1035000, 675 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1050000, 708 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev0_2p3g_pvs2[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  750000,  74 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  750000,  85 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  750000, 104 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  750000, 124 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  760000, 144 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  770000, 164 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  780000, 184 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  790000, 206 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  800000, 227 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  810000, 249 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  820000, 271 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  830000, 295 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  840000, 318 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  850000, 342 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  865000, 365 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  875000, 392 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  885000, 416 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  900000, 442 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  915000, 469 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  930000, 497 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  945000, 525 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  955000, 554 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  970000, 583 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  980000, 613 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  995000, 642 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1010000, 663 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1010000, 675 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1025000, 708 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev0_2p3g_pvs3[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  750000,  74 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  750000,  85 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  750000, 104 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  750000, 124 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  750000, 144 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  755000, 164 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  765000, 184 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  775000, 206 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  785000, 227 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  795000, 249 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  805000, 271 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  815000, 295 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  825000, 318 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  835000, 342 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  850000, 365 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  860000, 392 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  870000, 416 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  885000, 442 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  900000, 469 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  910000, 497 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  925000, 525 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  935000, 554 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  945000, 583 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  960000, 613 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  970000, 642 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  985000, 663 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  985000, 675 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1000000, 708 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev0_2p3g_pvs4[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  750000,  74 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  750000,  85 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  750000, 104 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  750000, 124 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  750000, 144 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  750000, 164 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  755000, 184 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  765000, 206 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  775000, 227 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  785000, 249 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  795000, 271 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  805000, 295 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  815000, 318 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  825000, 342 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  835000, 365 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  845000, 392 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  855000, 416 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  870000, 442 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  885000, 469 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  895000, 497 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  905000, 525 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  915000, 554 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  925000, 583 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  935000, 613 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  950000, 642 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  960000, 663 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  960000, 675 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  975000, 708 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev0_2p3g_pvs5[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  725000,  74 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  725000,  85 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  725000, 104 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  725000, 124 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  725000, 144 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  735000, 164 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  745000, 184 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  755000, 206 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  765000, 227 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  775000, 249 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  785000, 271 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  795000, 295 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  805000, 318 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  815000, 342 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  825000, 365 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  835000, 392 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  845000, 416 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  855000, 442 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  865000, 469 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  875000, 497 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  885000, 525 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  895000, 554 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  905000, 583 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  915000, 613 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  930000, 642 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  940000, 663 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  940000, 675 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  950000, 708 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev0_2p3g_pvs6[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  725000,  74 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  725000,  85 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  725000, 104 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  725000, 124 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  725000, 144 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  725000, 164 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  735000, 184 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  745000, 206 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  755000, 227 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  765000, 249 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  775000, 271 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  785000, 295 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  795000, 318 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  805000, 342 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  815000, 365 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  825000, 392 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  835000, 416 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  845000, 442 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  850000, 469 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  860000, 497 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  870000, 525 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  880000, 554 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  890000, 583 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  895000, 613 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  905000, 642 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  915000, 663 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  915000, 675 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  925000, 708 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev0_2p5g_pvs0[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  800000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  800000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  800000, 125 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  800000, 145 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  810000, 165 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  820000, 186 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  830000, 208 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  840000, 229 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  850000, 251 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  860000, 273 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  870000, 296 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  880000, 319 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  890000, 342 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  900000, 365 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  910000, 390 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  920000, 415 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  930000, 439 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  945000, 465 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  960000, 493 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  975000, 521 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  990000, 549 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1005000, 579 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1020000, 608 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1035000, 638 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1050000, 667 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1050000, 667 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1065000, 700 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1080000, 734 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1095000, 769 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1100000, 785 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev0_2p5g_pvs1[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  800000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  800000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  800000, 125 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  800000, 145 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  800000, 165 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  800000, 186 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  805000, 208 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  815000, 229 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  825000, 251 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  835000, 273 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  845000, 296 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  855000, 319 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  865000, 342 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  875000, 365 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  885000, 390 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  895000, 415 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  905000, 439 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  920000, 465 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  935000, 493 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  950000, 521 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  965000, 549 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  980000, 579 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  995000, 608 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1010000, 638 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1025000, 667 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1025000, 667 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1040000, 700 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1055000, 734 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1070000, 769 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1075000, 785 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev0_2p5g_pvs2[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 125 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 145 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  775000, 165 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  775000, 186 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  780000, 208 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  790000, 229 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  800000, 251 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  810000, 273 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  820000, 296 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  830000, 319 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  840000, 342 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  850000, 365 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  860000, 390 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  870000, 415 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  880000, 439 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  895000, 465 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  910000, 493 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  925000, 521 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  940000, 549 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  955000, 579 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  970000, 608 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  985000, 638 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1000000, 667 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1000000, 667 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1015000, 700 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1030000, 734 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1045000, 769 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1050000, 785 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev0_2p5g_pvs3[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 125 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 145 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  775000, 165 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  775000, 186 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  775000, 208 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  775000, 229 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  780000, 251 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  785000, 273 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  795000, 296 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  805000, 319 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  815000, 342 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  825000, 365 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  835000, 390 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  845000, 415 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  855000, 439 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  870000, 465 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  885000, 493 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  900000, 521 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  915000, 549 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  930000, 579 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  945000, 608 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  960000, 638 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  975000, 667 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  975000, 667 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  990000, 700 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1005000, 734 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1020000, 769 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1025000, 785 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev0_2p5g_pvs4[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 125 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 145 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  775000, 165 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  775000, 186 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  775000, 208 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  775000, 229 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  775000, 251 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  775000, 273 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  775000, 296 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  780000, 319 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  790000, 342 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  800000, 365 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  810000, 390 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  820000, 415 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  830000, 439 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  845000, 465 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  860000, 493 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  875000, 521 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  890000, 549 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  905000, 579 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  920000, 608 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  935000, 638 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  950000, 667 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  950000, 667 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  965000, 700 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19),  980000, 734 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19),  995000, 769 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1000000, 785 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev0_2p5g_pvs5[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  750000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  750000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  750000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  750000, 125 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  750000, 145 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  750000, 165 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  750000, 186 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  750000, 208 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  750000, 229 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  750000, 251 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  750000, 273 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  750000, 296 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  760000, 319 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  770000, 342 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  780000, 365 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  790000, 390 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  800000, 415 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  810000, 439 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  820000, 465 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  835000, 493 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  850000, 521 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  865000, 549 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  880000, 579 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  895000, 608 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  910000, 638 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  925000, 667 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  925000, 667 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  940000, 700 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19),  955000, 734 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19),  970000, 769 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19),  975000, 785 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev0_2p5g_pvs6[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  750000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  750000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  750000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  750000, 125 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  750000, 145 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  750000, 165 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  750000, 186 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  750000, 208 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  750000, 229 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  750000, 251 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  750000, 273 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  750000, 296 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  750000, 319 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  755000, 342 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  765000, 365 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  775000, 390 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  785000, 415 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  795000, 439 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  805000, 465 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  815000, 493 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  825000, 521 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  840000, 549 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  855000, 579 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  870000, 608 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  885000, 638 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  900000, 667 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  900000, 667 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  915000, 700 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19),  930000, 734 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19),  945000, 769 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19),  950000, 785 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p5g_pvs0[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  800000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  800000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  810000, 126 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  820000, 147 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  830000, 168 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  840000, 189 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  850000, 211 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  860000, 233 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  870000, 256 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  880000, 278 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  890000, 301 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  900000, 324 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  910000, 348 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  920000, 372 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  930000, 396 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  940000, 421 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  950000, 446 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  965000, 473 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  980000, 501 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  995000, 529 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18), 1010000, 558 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1025000, 588 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1040000, 617 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1055000, 649 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1070000, 682 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1070000, 682 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1085000, 716 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1100000, 751 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1115000, 786 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1120000, 802 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p5g_pvs1[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  800000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  800000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  800000, 126 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  810000, 147 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  820000, 168 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  830000, 189 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  840000, 211 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  850000, 233 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  860000, 256 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  870000, 278 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  880000, 301 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  890000, 324 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  900000, 348 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  910000, 372 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  920000, 396 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  930000, 421 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  940000, 446 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  955000, 473 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  970000, 501 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  985000, 529 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18), 1000000, 558 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1015000, 588 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1030000, 617 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1045000, 649 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1060000, 682 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1060000, 682 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1075000, 716 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1090000, 751 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1105000, 786 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1110000, 802 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p5g_pvs2[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  800000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  800000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  800000, 126 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  800000, 147 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  810000, 168 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  820000, 189 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  830000, 211 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  840000, 233 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  850000, 256 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  860000, 278 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  870000, 301 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  880000, 324 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  890000, 348 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  900000, 372 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  910000, 396 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  920000, 421 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  930000, 446 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  945000, 473 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  960000, 501 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  975000, 529 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  990000, 558 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1005000, 588 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1020000, 617 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1035000, 649 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1050000, 682 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1050000, 682 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1065000, 716 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1080000, 751 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1095000, 786 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1100000, 802 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p5g_pvs3[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  800000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  800000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  800000, 126 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  800000, 147 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  800000, 168 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  810000, 189 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  820000, 211 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  830000, 233 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  840000, 256 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  850000, 278 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  860000, 301 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  870000, 324 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  880000, 348 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  890000, 372 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  900000, 396 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  910000, 421 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  920000, 446 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  935000, 473 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  950000, 501 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  965000, 529 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  980000, 558 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  995000, 588 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1010000, 617 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1025000, 649 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1040000, 682 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1040000, 682 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1055000, 716 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1070000, 751 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1085000, 786 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1090000, 802 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p5g_pvs4[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  800000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  800000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  800000, 126 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  800000, 147 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  800000, 168 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  800000, 189 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  810000, 211 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  820000, 233 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  830000, 256 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  840000, 278 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  850000, 301 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  860000, 324 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  870000, 348 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  880000, 372 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  890000, 396 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  900000, 421 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  910000, 446 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  925000, 473 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  940000, 501 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  955000, 529 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  970000, 558 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  985000, 588 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1000000, 617 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1015000, 649 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1030000, 682 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1030000, 682 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1045000, 716 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1060000, 751 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1075000, 786 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1080000, 802 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p5g_pvs5[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  800000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  800000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  800000, 126 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  800000, 147 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  800000, 168 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  800000, 189 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  800000, 211 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  810000, 233 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  820000, 256 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  830000, 278 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  840000, 301 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  850000, 324 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  860000, 348 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  870000, 372 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  880000, 396 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  890000, 421 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  900000, 446 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  915000, 473 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  930000, 501 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  945000, 529 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  960000, 558 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  975000, 588 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  990000, 617 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1005000, 649 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1020000, 682 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1020000, 682 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1035000, 716 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1050000, 751 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1065000, 786 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1070000, 802 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p5g_pvs6[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 126 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 147 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  775000, 168 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  780000, 189 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  790000, 211 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  800000, 233 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  810000, 256 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  820000, 278 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  830000, 301 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  840000, 324 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  850000, 348 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  860000, 372 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  870000, 396 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  880000, 421 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  890000, 446 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  905000, 473 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  920000, 501 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  935000, 529 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  950000, 558 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  965000, 588 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  980000, 617 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  995000, 649 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1010000, 682 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1010000, 682 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1025000, 716 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1040000, 751 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1055000, 786 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1060000, 802 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p5g_pvs7[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 126 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 147 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  775000, 168 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  775000, 189 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  780000, 211 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  790000, 233 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  800000, 256 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  810000, 278 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  820000, 301 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  830000, 324 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  840000, 348 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  850000, 372 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  860000, 396 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  870000, 421 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  880000, 446 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  895000, 473 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  910000, 501 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  925000, 529 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  940000, 558 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  955000, 588 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  970000, 617 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  985000, 649 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1000000, 682 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1000000, 682 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1015000, 716 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1030000, 751 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1045000, 786 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1050000, 802 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p5g_pvs8[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 126 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 147 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  775000, 168 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  775000, 189 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  775000, 211 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  780000, 233 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  790000, 256 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  800000, 278 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  810000, 301 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  820000, 324 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  830000, 348 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  840000, 372 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  850000, 396 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  860000, 421 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  870000, 446 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  885000, 473 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  900000, 501 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  915000, 529 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  930000, 558 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  945000, 588 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  960000, 617 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  975000, 649 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  990000, 682 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  990000, 682 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1005000, 716 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1020000, 751 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1035000, 786 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1040000, 802 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p5g_pvs9[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 126 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 147 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  775000, 168 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  775000, 189 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  775000, 211 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  775000, 233 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  780000, 256 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  790000, 278 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  800000, 301 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  810000, 324 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  820000, 348 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  830000, 372 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  840000, 396 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  850000, 421 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  860000, 446 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  875000, 473 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  890000, 501 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  905000, 529 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  920000, 558 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  935000, 588 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  950000, 617 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  965000, 649 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  980000, 682 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  980000, 682 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  995000, 716 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1010000, 751 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1025000, 786 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1030000, 802 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p5g_pvs10[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 126 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 147 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  775000, 168 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  775000, 189 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  775000, 211 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  775000, 233 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  775000, 256 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  780000, 278 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  790000, 301 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  800000, 324 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  810000, 348 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  820000, 372 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  830000, 396 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  840000, 421 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  850000, 446 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  865000, 473 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  880000, 501 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  895000, 529 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  910000, 558 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  925000, 588 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  940000, 617 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  955000, 649 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  970000, 682 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  970000, 682 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  985000, 716 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1000000, 751 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1015000, 786 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1020000, 802 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p5g_pvs11[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 126 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 147 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  775000, 168 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  775000, 189 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  775000, 211 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  775000, 233 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  775000, 256 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  775000, 278 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  780000, 301 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  790000, 324 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  800000, 348 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  810000, 372 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  820000, 396 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  830000, 421 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  840000, 446 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  855000, 473 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  870000, 501 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  885000, 529 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  900000, 558 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  915000, 588 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  930000, 617 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  945000, 649 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  960000, 682 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  960000, 682 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  975000, 716 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19),  990000, 751 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1005000, 786 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1010000, 802 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p5g_pvs12[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 126 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 147 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  775000, 168 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  775000, 189 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  775000, 211 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  775000, 233 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  775000, 256 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  775000, 278 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  775000, 301 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  780000, 324 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  790000, 348 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  800000, 372 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  810000, 396 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  820000, 421 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  830000, 446 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  845000, 473 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  860000, 501 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  875000, 529 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  890000, 558 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  905000, 588 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  920000, 617 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  935000, 649 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  950000, 682 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  950000, 682 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  965000, 716 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19),  980000, 751 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19),  995000, 786 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1000000, 802 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p5g_pvs13[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 126 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 147 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  775000, 168 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  775000, 189 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  775000, 211 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  775000, 233 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  775000, 256 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  775000, 278 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  775000, 301 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  775000, 324 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  780000, 348 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  790000, 372 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  800000, 396 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  810000, 421 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  820000, 446 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  835000, 473 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  850000, 501 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  865000, 529 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  880000, 558 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  895000, 588 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  910000, 617 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  925000, 649 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  940000, 682 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  940000, 682 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  955000, 716 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19),  970000, 751 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19),  985000, 786 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19),  990000, 802 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p5g_pvs14[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  750000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  750000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  750000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  750000, 126 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  750000, 147 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  750000, 168 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  750000, 189 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  750000, 211 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  750000, 233 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  750000, 256 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  750000, 278 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  750000, 301 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  760000, 324 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  770000, 348 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  780000, 372 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  790000, 396 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  800000, 421 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  810000, 446 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  825000, 473 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  840000, 501 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  855000, 529 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  870000, 558 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  885000, 588 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  900000, 617 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  915000, 649 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  930000, 682 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  930000, 682 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  945000, 716 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19),  960000, 751 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19),  975000, 786 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19),  980000, 802 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p5g_pvs15[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  750000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  750000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  750000, 106 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  750000, 126 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  750000, 147 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  750000, 168 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  750000, 189 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  750000, 211 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  750000, 233 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  750000, 256 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  750000, 278 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  750000, 301 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  750000, 324 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  760000, 348 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  770000, 372 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  780000, 396 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  790000, 421 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  800000, 446 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  815000, 473 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  830000, 501 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  845000, 529 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  860000, 558 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  875000, 588 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  890000, 617 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  905000, 649 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  920000, 682 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  920000, 682 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  935000, 716 },
-	{ 0, { 2342400, HFPLL, 1, 122 }, L2(19),  950000, 751 },
-	{ 0, { 2419200, HFPLL, 1, 126 }, L2(19),  965000, 786 },
-	{ 1, { 2457600, HFPLL, 1, 128 }, L2(19),  970000, 802 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p3g_pvs0[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  810000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  820000, 108 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  830000, 129 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  840000, 150 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  850000, 171 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  860000, 193 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  870000, 215 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  880000, 237 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  890000, 260 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  900000, 282 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  910000, 306 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  920000, 330 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  930000, 354 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  940000, 378 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  955000, 404 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  970000, 431 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  985000, 458 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17), 1000000, 486 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18), 1015000, 515 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18), 1030000, 543 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18), 1045000, 572 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1060000, 604 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1075000, 636 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1090000, 669 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1105000, 703 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1105000, 703 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1120000, 738 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p3g_pvs1[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  800000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  810000, 108 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  820000, 129 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  830000, 150 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  840000, 171 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  850000, 193 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  860000, 215 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  870000, 237 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  880000, 260 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  890000, 282 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  900000, 306 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  910000, 330 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  920000, 354 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  930000, 378 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  945000, 404 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  960000, 431 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  975000, 458 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  990000, 486 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18), 1005000, 515 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18), 1020000, 543 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18), 1035000, 572 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1050000, 604 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1065000, 636 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1080000, 669 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1095000, 703 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1095000, 703 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1110000, 738 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p3g_pvs2[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  800000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  800000, 108 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  810000, 129 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  820000, 150 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  830000, 171 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  840000, 193 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  850000, 215 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  860000, 237 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  870000, 260 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  880000, 282 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  890000, 306 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  900000, 330 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  910000, 354 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  920000, 378 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  935000, 404 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  950000, 431 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  965000, 458 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  980000, 486 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  995000, 515 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18), 1010000, 543 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18), 1025000, 572 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1040000, 604 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1055000, 636 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1070000, 669 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1085000, 703 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1085000, 703 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1100000, 738 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p3g_pvs3[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  800000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  800000, 108 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  800000, 129 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  810000, 150 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  820000, 171 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  830000, 193 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  840000, 215 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  850000, 237 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  860000, 260 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  870000, 282 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  880000, 306 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  890000, 330 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  900000, 354 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  910000, 378 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  925000, 404 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  940000, 431 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  955000, 458 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  970000, 486 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  985000, 515 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18), 1000000, 543 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18), 1015000, 572 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1030000, 604 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1045000, 636 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1060000, 669 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1075000, 703 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1075000, 703 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1090000, 738 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p3g_pvs4[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  800000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  800000, 108 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  800000, 129 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  800000, 150 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  810000, 171 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  820000, 193 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  830000, 215 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  840000, 237 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  850000, 260 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  860000, 282 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  870000, 306 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  880000, 330 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  890000, 354 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  900000, 378 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  915000, 404 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  930000, 431 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  945000, 458 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  960000, 486 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  975000, 515 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  990000, 543 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18), 1005000, 572 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1020000, 604 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1035000, 636 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1050000, 669 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1065000, 703 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1065000, 703 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1080000, 738 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p3g_pvs5[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  800000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  800000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  800000, 108 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  800000, 129 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  800000, 150 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  800000, 171 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  810000, 193 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  820000, 215 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  830000, 237 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  840000, 260 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  850000, 282 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  860000, 306 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  870000, 330 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  880000, 354 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  890000, 378 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  905000, 404 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  920000, 431 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  935000, 458 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  950000, 486 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  965000, 515 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  980000, 543 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  995000, 572 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1010000, 604 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1025000, 636 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1040000, 669 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1055000, 703 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1055000, 703 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1070000, 738 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p3g_pvs6[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 108 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 129 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  780000, 150 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  790000, 171 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  800000, 193 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  810000, 215 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  820000, 237 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  830000, 260 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  840000, 282 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  850000, 306 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  860000, 330 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  870000, 354 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  880000, 378 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  895000, 404 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  910000, 431 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  925000, 458 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  940000, 486 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  955000, 515 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  970000, 543 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  985000, 572 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1000000, 604 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1015000, 636 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1030000, 669 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1045000, 703 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1045000, 703 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1060000, 738 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p3g_pvs7[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 108 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 129 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 150 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  780000, 171 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  790000, 193 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  800000, 215 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  810000, 237 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  820000, 260 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  830000, 282 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  840000, 306 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  850000, 330 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  860000, 354 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  870000, 378 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  885000, 404 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  900000, 431 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  915000, 458 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  930000, 486 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  945000, 515 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  960000, 543 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  975000, 572 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  990000, 604 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1005000, 636 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1020000, 669 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1035000, 703 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1035000, 703 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1050000, 738 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p3g_pvs8[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 108 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 129 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 150 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  775000, 171 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  780000, 193 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  790000, 215 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  800000, 237 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  810000, 260 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  820000, 282 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  830000, 306 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  840000, 330 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  850000, 354 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  860000, 378 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  875000, 404 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  890000, 431 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  905000, 458 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  920000, 486 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  935000, 515 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  950000, 543 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  965000, 572 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  980000, 604 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  995000, 636 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1010000, 669 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1025000, 703 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1025000, 703 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1040000, 738 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p3g_pvs9[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 108 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 129 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 150 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  775000, 171 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  775000, 193 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  780000, 215 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  790000, 237 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  800000, 260 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  810000, 282 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  820000, 306 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  830000, 330 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  840000, 354 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  850000, 378 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  865000, 404 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  880000, 431 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  895000, 458 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  910000, 486 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  925000, 515 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  940000, 543 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  955000, 572 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  970000, 604 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  985000, 636 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1000000, 669 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1015000, 703 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1015000, 703 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1030000, 738 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p3g_pvs10[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 108 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 129 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 150 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  775000, 171 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  775000, 193 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  775000, 215 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  780000, 237 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  790000, 260 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  800000, 282 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  810000, 306 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  820000, 330 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  830000, 354 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  840000, 378 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  855000, 404 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  870000, 431 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  885000, 458 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  900000, 486 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  915000, 515 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  930000, 543 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  945000, 572 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  960000, 604 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  975000, 636 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  990000, 669 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19), 1005000, 703 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1005000, 703 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1020000, 738 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p3g_pvs11[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 108 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 129 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 150 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  775000, 171 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  775000, 193 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  775000, 215 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  775000, 237 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  780000, 260 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  790000, 282 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  800000, 306 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  810000, 330 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  820000, 354 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  830000, 378 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  845000, 404 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  860000, 431 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  875000, 458 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  890000, 486 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  905000, 515 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  920000, 543 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  935000, 572 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  950000, 604 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  965000, 636 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  980000, 669 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  995000, 703 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  995000, 703 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1010000, 738 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p3g_pvs12[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 108 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 129 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 150 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  775000, 171 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  775000, 193 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  775000, 215 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  775000, 237 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  775000, 260 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  780000, 282 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  790000, 306 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  800000, 330 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  810000, 354 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  820000, 378 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  835000, 404 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  850000, 431 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  865000, 458 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  880000, 486 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  895000, 515 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  910000, 543 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  925000, 572 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  940000, 604 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  955000, 636 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  970000, 669 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  985000, 703 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  985000, 703 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1000000, 738 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p3g_pvs13[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  775000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  775000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  775000, 108 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  775000, 129 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  775000, 150 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  775000, 171 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  775000, 193 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  775000, 215 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  775000, 237 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  775000, 260 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  775000, 282 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  780000, 306 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  790000, 330 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  800000, 354 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  810000, 378 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  825000, 404 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  840000, 431 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  855000, 458 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  870000, 486 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  885000, 515 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  900000, 543 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  915000, 572 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  930000, 604 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  945000, 636 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  960000, 669 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  975000, 703 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  975000, 703 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  990000, 738 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p3g_pvs14[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  750000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  750000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  750000, 108 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  750000, 129 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  750000, 150 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  750000, 171 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  750000, 193 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  750000, 215 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  750000, 237 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  750000, 260 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  760000, 282 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  770000, 306 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  780000, 330 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  790000, 354 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  800000, 378 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  815000, 404 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  830000, 431 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  845000, 458 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  860000, 486 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  875000, 515 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  890000, 543 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  905000, 572 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  920000, 604 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  935000, 636 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  950000, 669 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  965000, 703 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  965000, 703 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  980000, 738 },
-	{ 0, { 0 } }
-};
-
-static struct acpu_level pro_rev1_2p3g_pvs15[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 },  L2(0),  750000,  76 },
-	{ 0, {  345600, HFPLL, 2,  36 },  L2(1),  750000,  87 },
-	{ 1, {  422400, HFPLL, 2,  44 },  L2(2),  750000, 108 },
-	{ 0, {  499200, HFPLL, 2,  52 },  L2(2),  750000, 129 },
-	{ 0, {  576000, HFPLL, 1,  30 },  L2(3),  750000, 150 },
-	{ 1, {  652800, HFPLL, 1,  34 },  L2(3),  750000, 171 },
-	{ 1, {  729600, HFPLL, 1,  38 },  L2(4),  750000, 193 },
-	{ 0, {  806400, HFPLL, 1,  42 },  L2(4),  750000, 215 },
-	{ 1, {  883200, HFPLL, 1,  46 },  L2(4),  750000, 237 },
-	{ 1, {  960000, HFPLL, 1,  50 },  L2(9),  750000, 260 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(10),  750000, 282 },
-	{ 0, { 1113600, HFPLL, 1,  58 }, L2(10),  760000, 306 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(10),  770000, 330 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(13),  780000, 354 },
-	{ 0, { 1344000, HFPLL, 1,  70 }, L2(14),  790000, 378 },
-	{ 0, { 1420800, HFPLL, 1,  74 }, L2(15),  805000, 404 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  820000, 431 },
-	{ 1, { 1574400, HFPLL, 1,  82 }, L2(17),  835000, 458 },
-	{ 0, { 1651200, HFPLL, 1,  86 }, L2(17),  850000, 486 },
-	{ 1, { 1728000, HFPLL, 1,  90 }, L2(18),  865000, 515 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(18),  880000, 543 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(18),  895000, 572 },
-	{ 1, { 1958400, HFPLL, 1, 102 }, L2(19),  910000, 604 },
-	{ 0, { 2035200, HFPLL, 1, 106 }, L2(19),  925000, 636 },
-	{ 0, { 2112000, HFPLL, 1, 110 }, L2(19),  940000, 669 },
-	{ 0, { 2150400, HFPLL, 1, 112 }, L2(19),  955000, 703 },
-	{ 0, { 2188800, HFPLL, 1, 114 }, L2(19),  955000, 703 },
-	{ 1, { 2265600, HFPLL, 1, 118 }, L2(19),  970000, 738 },
-	{ 0, { 0 } }
-};
-
-static struct pvs_table pvs_v2[NUM_PVS_REVS][NUM_SPEED_BINS][NUM_PVS] __initdata = {
-	/* 8974v2 2.0GHz Parts */
-	[0][0][0] = { acpu_freq_tbl_2g_pvs0, sizeof(acpu_freq_tbl_2g_pvs0) },
-	[0][0][1] = { acpu_freq_tbl_2g_pvs1, sizeof(acpu_freq_tbl_2g_pvs1) },
-	[0][0][2] = { acpu_freq_tbl_2g_pvs2, sizeof(acpu_freq_tbl_2g_pvs2) },
-	[0][0][3] = { acpu_freq_tbl_2g_pvs3, sizeof(acpu_freq_tbl_2g_pvs3) },
-	[0][0][4] = { acpu_freq_tbl_2g_pvs4, sizeof(acpu_freq_tbl_2g_pvs4) },
-	[0][0][5] = { acpu_freq_tbl_2g_pvs5, sizeof(acpu_freq_tbl_2g_pvs5) },
-	[0][0][6] = { acpu_freq_tbl_2g_pvs6, sizeof(acpu_freq_tbl_2g_pvs6) },
-	[0][0][7] = { acpu_freq_tbl_2g_pvs6, sizeof(acpu_freq_tbl_2g_pvs6) },
-
-	/* 8974v2 2.3GHz Parts */
-	[0][1][0] = { acpu_freq_tbl_2p3g_pvs0, sizeof(acpu_freq_tbl_2p3g_pvs0) },
-	[0][1][1] = { acpu_freq_tbl_2p3g_pvs1, sizeof(acpu_freq_tbl_2p3g_pvs1) },
-	[0][1][2] = { acpu_freq_tbl_2p3g_pvs2, sizeof(acpu_freq_tbl_2p3g_pvs2) },
-	[0][1][3] = { acpu_freq_tbl_2p3g_pvs3, sizeof(acpu_freq_tbl_2p3g_pvs3) },
-	[0][1][4] = { acpu_freq_tbl_2p3g_pvs4, sizeof(acpu_freq_tbl_2p3g_pvs4) },
-	[0][1][5] = { acpu_freq_tbl_2p3g_pvs5, sizeof(acpu_freq_tbl_2p3g_pvs5) },
-	[0][1][6] = { acpu_freq_tbl_2p3g_pvs6, sizeof(acpu_freq_tbl_2p3g_pvs6) },
-	[0][1][7] = { acpu_freq_tbl_2p3g_pvs6, sizeof(acpu_freq_tbl_2p3g_pvs6) },
-
-	/* 8974v2 2.2GHz Parts */
-	[0][2][0] = { acpu_freq_tbl_2p2g_pvs0, sizeof(acpu_freq_tbl_2p2g_pvs0) },
-	[0][2][1] = { acpu_freq_tbl_2p2g_pvs1, sizeof(acpu_freq_tbl_2p2g_pvs1) },
-	[0][2][2] = { acpu_freq_tbl_2p2g_pvs2, sizeof(acpu_freq_tbl_2p2g_pvs2) },
-	[0][2][3] = { acpu_freq_tbl_2p2g_pvs3, sizeof(acpu_freq_tbl_2p2g_pvs3) },
-	[0][2][4] = { acpu_freq_tbl_2p2g_pvs4, sizeof(acpu_freq_tbl_2p2g_pvs4) },
-	[0][2][5] = { acpu_freq_tbl_2p2g_pvs5, sizeof(acpu_freq_tbl_2p2g_pvs5) },
-	[0][2][6] = { acpu_freq_tbl_2p2g_pvs6, sizeof(acpu_freq_tbl_2p2g_pvs6) },
-	[0][2][7] = { acpu_freq_tbl_2p2g_pvs6, sizeof(acpu_freq_tbl_2p2g_pvs6) },
-};
-
-static struct pvs_table pvs_pro[NUM_PVS_REVS][NUM_SPEED_BINS][NUM_PVS] __initdata = {
-	/* 2.0 GHz is not used on 8974Pro */
-	[0][0][0] = { acpu_freq_tbl_2g_pvs0, sizeof(acpu_freq_tbl_2g_pvs0) },
-	[0][0][1] = { acpu_freq_tbl_2g_pvs1, sizeof(acpu_freq_tbl_2g_pvs1) },
-	[0][0][2] = { acpu_freq_tbl_2g_pvs2, sizeof(acpu_freq_tbl_2g_pvs2) },
-	[0][0][3] = { acpu_freq_tbl_2g_pvs3, sizeof(acpu_freq_tbl_2g_pvs3) },
-	[0][0][4] = { acpu_freq_tbl_2g_pvs4, sizeof(acpu_freq_tbl_2g_pvs4) },
-	[0][0][5] = { acpu_freq_tbl_2g_pvs5, sizeof(acpu_freq_tbl_2g_pvs5) },
-	[0][0][6] = { acpu_freq_tbl_2g_pvs6, sizeof(acpu_freq_tbl_2g_pvs6) },
-	[0][0][7] = { acpu_freq_tbl_2g_pvs6, sizeof(acpu_freq_tbl_2g_pvs6) },
-
-	/* 8974Pro AB 2.3GHz */
-	[0][1][0] = { pro_rev0_2p3g_pvs0, sizeof(pro_rev0_2p3g_pvs0) },
-	[0][1][1] = { pro_rev0_2p3g_pvs1, sizeof(pro_rev0_2p3g_pvs1) },
-	[0][1][2] = { pro_rev0_2p3g_pvs2, sizeof(pro_rev0_2p3g_pvs2) },
-	[0][1][3] = { pro_rev0_2p3g_pvs3, sizeof(pro_rev0_2p3g_pvs3) },
-	[0][1][4] = { pro_rev0_2p3g_pvs4, sizeof(pro_rev0_2p3g_pvs4) },
-	[0][1][5] = { pro_rev0_2p3g_pvs5, sizeof(pro_rev0_2p3g_pvs5) },
-	[0][1][6] = { pro_rev0_2p3g_pvs6, sizeof(pro_rev0_2p3g_pvs6) },
-	[0][1][7] = { pro_rev0_2p3g_pvs6, sizeof(pro_rev0_2p3g_pvs6) },
-
-	/* 2.2GHz is not used on 8974Pro */
-	[0][2][0] = { acpu_freq_tbl_2p2g_pvs0, sizeof(acpu_freq_tbl_2p2g_pvs0) },
-	[0][2][1] = { acpu_freq_tbl_2p2g_pvs1, sizeof(acpu_freq_tbl_2p2g_pvs1) },
-	[0][2][2] = { acpu_freq_tbl_2p2g_pvs2, sizeof(acpu_freq_tbl_2p2g_pvs2) },
-	[0][2][3] = { acpu_freq_tbl_2p2g_pvs3, sizeof(acpu_freq_tbl_2p2g_pvs3) },
-	[0][2][4] = { acpu_freq_tbl_2p2g_pvs4, sizeof(acpu_freq_tbl_2p2g_pvs4) },
-	[0][2][5] = { acpu_freq_tbl_2p2g_pvs5, sizeof(acpu_freq_tbl_2p2g_pvs5) },
-	[0][2][6] = { acpu_freq_tbl_2p2g_pvs6, sizeof(acpu_freq_tbl_2p2g_pvs6) },
-	[0][2][7] = { acpu_freq_tbl_2p2g_pvs6, sizeof(acpu_freq_tbl_2p2g_pvs6) },
-
-	/* 8974Pro AC 2.5GHz */
-	[0][3][0] = { pro_rev0_2p5g_pvs0, sizeof(pro_rev0_2p5g_pvs0) },
-	[0][3][1] = { pro_rev0_2p5g_pvs1, sizeof(pro_rev0_2p5g_pvs1) },
-	[0][3][2] = { pro_rev0_2p5g_pvs2, sizeof(pro_rev0_2p5g_pvs2) },
-	[0][3][3] = { pro_rev0_2p5g_pvs3, sizeof(pro_rev0_2p5g_pvs3) },
-	[0][3][4] = { pro_rev0_2p5g_pvs4, sizeof(pro_rev0_2p5g_pvs4) },
-	[0][3][5] = { pro_rev0_2p5g_pvs5, sizeof(pro_rev0_2p5g_pvs5) },
-	[0][3][6] = { pro_rev0_2p5g_pvs6, sizeof(pro_rev0_2p5g_pvs6) },
-	[0][3][7] = { pro_rev0_2p5g_pvs6, sizeof(pro_rev0_2p5g_pvs6) },
-
-	/* 8974Pro AB 2.3GHz */
-	[1][1][0] = { pro_rev1_2p3g_pvs0, sizeof(pro_rev1_2p3g_pvs0) },
-	[1][1][1] = { pro_rev1_2p3g_pvs1, sizeof(pro_rev1_2p3g_pvs1) },
-	[1][1][2] = { pro_rev1_2p3g_pvs2, sizeof(pro_rev1_2p3g_pvs2) },
-	[1][1][3] = { pro_rev1_2p3g_pvs3, sizeof(pro_rev1_2p3g_pvs3) },
-	[1][1][4] = { pro_rev1_2p3g_pvs4, sizeof(pro_rev1_2p3g_pvs4) },
-	[1][1][5] = { pro_rev1_2p3g_pvs5, sizeof(pro_rev1_2p3g_pvs5) },
-	[1][1][6] = { pro_rev1_2p3g_pvs6, sizeof(pro_rev1_2p3g_pvs6) },
-	[1][1][7] = { pro_rev1_2p3g_pvs7, sizeof(pro_rev1_2p3g_pvs7) },
-	[1][1][8] = { pro_rev1_2p3g_pvs8, sizeof(pro_rev1_2p3g_pvs8) },
-	[1][1][9] = { pro_rev1_2p3g_pvs9, sizeof(pro_rev1_2p3g_pvs9) },
-	[1][1][10] = { pro_rev1_2p3g_pvs10, sizeof(pro_rev1_2p3g_pvs10) },
-	[1][1][11] = { pro_rev1_2p3g_pvs11, sizeof(pro_rev1_2p3g_pvs11) },
-	[1][1][12] = { pro_rev1_2p3g_pvs12, sizeof(pro_rev1_2p3g_pvs12) },
-	[1][1][13] = { pro_rev1_2p3g_pvs13, sizeof(pro_rev1_2p3g_pvs13) },
-	[1][1][14] = { pro_rev1_2p3g_pvs14, sizeof(pro_rev1_2p3g_pvs14) },
-	[1][1][15] = { pro_rev1_2p3g_pvs15, sizeof(pro_rev1_2p3g_pvs15) },
-
-	/* 8974Pro AC 2.5GHz */
-	[1][3][0] = { pro_rev1_2p5g_pvs0, sizeof(pro_rev1_2p5g_pvs0) },
-	[1][3][1] = { pro_rev1_2p5g_pvs1, sizeof(pro_rev1_2p5g_pvs1) },
-	[1][3][2] = { pro_rev1_2p5g_pvs2, sizeof(pro_rev1_2p5g_pvs2) },
-	[1][3][3] = { pro_rev1_2p5g_pvs3, sizeof(pro_rev1_2p5g_pvs3) },
-	[1][3][4] = { pro_rev1_2p5g_pvs4, sizeof(pro_rev1_2p5g_pvs4) },
-	[1][3][5] = { pro_rev1_2p5g_pvs5, sizeof(pro_rev1_2p5g_pvs5) },
-	[1][3][6] = { pro_rev1_2p5g_pvs6, sizeof(pro_rev1_2p5g_pvs6) },
-	[1][3][7] = { pro_rev1_2p5g_pvs7, sizeof(pro_rev1_2p5g_pvs7) },
-	[1][3][8] = { pro_rev1_2p5g_pvs8, sizeof(pro_rev1_2p5g_pvs8) },
-	[1][3][9] = { pro_rev1_2p5g_pvs9, sizeof(pro_rev1_2p5g_pvs9) },
-	[1][3][10] = { pro_rev1_2p5g_pvs10, sizeof(pro_rev1_2p5g_pvs10) },
-	[1][3][11] = { pro_rev1_2p5g_pvs11, sizeof(pro_rev1_2p5g_pvs11) },
-	[1][3][12] = { pro_rev1_2p5g_pvs12, sizeof(pro_rev1_2p5g_pvs12) },
-	[1][3][13] = { pro_rev1_2p5g_pvs13, sizeof(pro_rev1_2p5g_pvs13) },
-	[1][3][14] = { pro_rev1_2p5g_pvs14, sizeof(pro_rev1_2p5g_pvs14) },
-	[1][3][15] = { pro_rev1_2p5g_pvs15, sizeof(pro_rev1_2p5g_pvs15) },
-};
-
-static struct msm_bus_scale_pdata bus_scale_data __initdata = {
-	.usecase = bw_level_tbl,
-	.num_usecases = ARRAY_SIZE(bw_level_tbl),
-	.active_only = 1,
-	.name = "acpuclk-8974",
-};
-
-static struct acpuclk_krait_params acpuclk_8974_params __initdata = {
-	.scalable = scalable,
-	.scalable_size = sizeof(scalable),
-	.hfpll_data = &hfpll_data,
-	.l2_freq_tbl = l2_freq_tbl,
-	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
-	.bus_scale = &bus_scale_data,
-	.pte_efuse_phys = 0xFC4B80B0,
-	.get_bin_info = get_krait_bin_format_b,
-	.stby_khz = 300000,
-};
-
-#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 (cpu_is_msm8974pro())
-		acpuclk_8974_params.pvs_tables = pvs_pro;
-	else
-		acpuclk_8974_params.pvs_tables = pvs_v2;
-
-	return acpuclk_krait_init(&pdev->dev, &acpuclk_8974_params);
-}
-
-static struct of_device_id acpuclk_8974_match_table[] = {
-	{ .compatible = "qcom,acpuclk-8974" },
-	{}
-};
-
-static struct platform_driver acpuclk_8974_driver = {
-	.driver = {
-		.name = "acpuclk-8974",
-		.of_match_table = acpuclk_8974_match_table,
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init acpuclk_8974_init(void)
-{
-	return platform_driver_probe(&acpuclk_8974_driver,
-				     acpuclk_8974_probe);
-}
-device_initcall(acpuclk_8974_init);
diff --git a/arch/arm/mach-msm/acpuclock-krait-debug.c b/arch/arm/mach-msm/acpuclock-krait-debug.c
deleted file mode 100644
index f11b9fc..0000000
--- a/arch/arm/mach-msm/acpuclock-krait-debug.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-#define pr_fmt(fmt) "%s: " fmt, __func__
-
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/debugfs.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/err.h>
-#include <linux/errno.h>
-#include <linux/cpu.h>
-#include <linux/smp.h>
-
-#include <mach/msm_bus.h>
-#include <mach/msm-krait-l2-accessors.h>
-
-#include "acpuclock-krait.h"
-
-static struct drv_data *drv;
-static DEFINE_MUTEX(debug_lock);
-
-struct acg_action {
-	bool set;
-	bool enable;
-};
-static int l2_acg_en_val;
-static struct dentry *base_dir;
-static struct dentry *sc_dir[MAX_SCALABLES];
-
-static void cpu_action(void *info)
-{
-	struct acg_action *action = info;
-
-	u32 val;
-	asm volatile ("mrc p15, 7, %[cpmr0], c15, c0, 5\n\t"
-			: [cpmr0]"=r" (val));
-	if (action->set) {
-		if (action->enable)
-			val &= ~BIT(0);
-		else
-			val |= BIT(0);
-		asm volatile ("mcr p15, 7, %[cpmr0], c15, c0, 5\n\t"
-				: : [cpmr0]"r" (val));
-	} else {
-		action->enable = !(val & BIT(0));
-	}
-}
-
-/* Disable auto clock-gating for a scalable. */
-static void disable_acg(int sc_id)
-{
-	u32 regval;
-
-	if (sc_id == L2) {
-		regval = get_l2_indirect_reg(drv->scalable[sc_id].l2cpmr_iaddr);
-		l2_acg_en_val = regval & (0x3 << 10);
-		regval |= (0x3 << 10);
-		set_l2_indirect_reg(drv->scalable[sc_id].l2cpmr_iaddr, regval);
-	} else {
-		struct acg_action action = { .set = true, .enable = false };
-		smp_call_function_single(sc_id, cpu_action, &action, 1);
-	}
-}
-
-/* Enable auto clock-gating for a scalable. */
-static void enable_acg(int sc_id)
-{
-	u32 regval;
-
-	if (sc_id == L2) {
-		regval = get_l2_indirect_reg(drv->scalable[sc_id].l2cpmr_iaddr);
-		regval &= ~(0x3 << 10);
-		regval |= l2_acg_en_val;
-		set_l2_indirect_reg(drv->scalable[sc_id].l2cpmr_iaddr, regval);
-	} else {
-		struct acg_action action = { .set = true, .enable = true };
-		smp_call_function_single(sc_id, cpu_action, &action, 1);
-	}
-}
-
-/* Check if auto clock-gating for a scalable. */
-static bool acg_is_enabled(int sc_id)
-{
-	u32 regval;
-
-	if (sc_id == L2) {
-		regval = get_l2_indirect_reg(drv->scalable[sc_id].l2cpmr_iaddr);
-		return ((regval >> 10) & 0x3) != 0x3;
-	} else {
-		struct acg_action action = { .set = false };
-		smp_call_function_single(sc_id, cpu_action, &action, 1);
-		return action.enable;
-	}
-}
-
-/* Enable/Disable auto clock gating. */
-static int acg_set(void *data, u64 val)
-{
-	int ret = 0;
-	int sc_id = (int)data;
-
-	mutex_lock(&debug_lock);
-	get_online_cpus();
-	if (!sc_dir[sc_id]) {
-		ret = -ENODEV;
-		goto out;
-	}
-
-	if (val == 0 && acg_is_enabled(sc_id))
-		disable_acg(sc_id);
-	else if (val == 1)
-		enable_acg(sc_id);
-out:
-	put_online_cpus();
-	mutex_unlock(&debug_lock);
-
-	return ret;
-}
-
-/* Get auto clock-gating state. */
-static int acg_get(void *data, u64 *val)
-{
-	int ret = 0;
-	int sc_id = (int)data;
-
-	mutex_lock(&debug_lock);
-	get_online_cpus();
-	if (!sc_dir[sc_id]) {
-		ret = -ENODEV;
-		goto out;
-	}
-
-	*val = acg_is_enabled(sc_id);
-out:
-	put_online_cpus();
-	mutex_unlock(&debug_lock);
-
-	return ret;
-}
-DEFINE_SIMPLE_ATTRIBUTE(acgd_fops, acg_get, acg_set, "%lld\n");
-
-/* Get the rate */
-static int rate_get(void *data, u64 *val)
-{
-	int sc_id = (int)data;
-	*val = drv->scalable[sc_id].cur_speed->khz;
-	return 0;
-}
-DEFINE_SIMPLE_ATTRIBUTE(rate_fops, rate_get, NULL, "%lld\n");
-
-/* Get the HFPLL's L-value. */
-static int hfpll_l_get(void *data, u64 *val)
-{
-	int sc_id = (int)data;
-	*val = drv->scalable[sc_id].cur_speed->pll_l_val;
-	return 0;
-}
-DEFINE_SIMPLE_ATTRIBUTE(hfpll_l_fops, hfpll_l_get, NULL, "%lld\n");
-
-/* Get the L2 rate vote. */
-static int l2_vote_get(void *data, u64 *val)
-{
-	int level, sc_id = (int)data;
-
-	level = drv->scalable[sc_id].l2_vote;
-	*val = drv->l2_freq_tbl[level].speed.khz;
-
-	return 0;
-}
-DEFINE_SIMPLE_ATTRIBUTE(l2_vote_fops, l2_vote_get, NULL, "%lld\n");
-
-/* Get the bandwidth vote. */
-static int bw_vote_get(void *data, u64 *val)
-{
-	struct l2_level *l;
-
-	l = container_of(drv->scalable[L2].cur_speed,
-			 struct l2_level, speed);
-	*val = drv->bus_scale->usecase[l->bw_level].vectors->ib;
-
-	return 0;
-}
-DEFINE_SIMPLE_ATTRIBUTE(bw_vote_fops, bw_vote_get, NULL, "%lld\n");
-
-/* Get the name of the currently-selected clock source. */
-static int src_name_show(struct seq_file *m, void *unused)
-{
-	const char *const src_names[NUM_SRC_ID] = {
-		[PLL_0] = "PLL0",
-		[HFPLL] = "HFPLL",
-		[PLL_8] = "PLL8",
-	};
-	int src, sc_id = (int)m->private;
-
-	src = drv->scalable[sc_id].cur_speed->src;
-	if (src > ARRAY_SIZE(src_names))
-		return -EINVAL;
-
-	seq_printf(m, "%s\n", src_names[src]);
-
-	return 0;
-}
-
-static int src_name_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, src_name_show, inode->i_private);
-}
-
-static const struct file_operations src_name_fops = {
-	.open		= src_name_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= seq_release,
-};
-
-/* Get speed_bin ID */
-static int speed_bin_get(void *data, u64 *val)
-{
-	*val = drv->speed_bin;
-	return 0;
-}
-DEFINE_SIMPLE_ATTRIBUTE(speed_bin_fops, speed_bin_get, NULL, "%lld\n");
-
-/* Get pvs_bin ID */
-static int pvs_bin_get(void *data, u64 *val)
-{
-	*val = drv->pvs_bin;
-	return 0;
-}
-DEFINE_SIMPLE_ATTRIBUTE(pvs_bin_fops, pvs_bin_get, NULL, "%lld\n");
-
-/* Get boost_uv */
-static int boost_get(void *data, u64 *val)
-{
-	*val = drv->boost_uv;
-	return 0;
-}
-DEFINE_SIMPLE_ATTRIBUTE(boost_fops, boost_get, NULL, "%lld\n");
-
-static int acpu_table_show(struct seq_file *m, void *unused)
-{
-	const struct acpu_level *level;
-
-	seq_printf(m, "CPU_KHz  PLL_L_Val   L2_KHz  VDD_Dig  VDD_Mem  ");
-	seq_printf(m, "BW_Mbps  VDD_Core  UA_Core  AVS\n");
-
-	for (level = drv->acpu_freq_tbl; level->speed.khz != 0; level++) {
-
-		const struct l2_level *l2 =
-					&drv->l2_freq_tbl[level->l2_level];
-		u32 bw = drv->bus_scale->usecase[l2->bw_level].vectors[0].ib;
-
-		if (!level->use_for_scaling)
-			continue;
-
-		/* CPU speed information */
-		seq_printf(m, "%7lu  %9u  ",
-				level->speed.khz,
-				level->speed.pll_l_val);
-
-		/* L2 level information */
-		seq_printf(m, "%7lu  %7d  %7d  %7u  ",
-				l2->speed.khz,
-				l2->vdd_dig,
-				l2->vdd_mem,
-				bw / 1000000);
-
-		/* Core voltage information */
-		seq_printf(m, "%8d  %7d  %3d\n",
-				level->vdd_core,
-				level->ua_core,
-				level->avsdscr_setting);
-	}
-
-	return 0;
-}
-
-static int acpu_table_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpu_table_show, inode->i_private);
-}
-
-static const struct file_operations acpu_table_fops = {
-	.open		= acpu_table_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= seq_release,
-};
-
-static void __cpuinit add_scalable_dir(int sc_id)
-{
-	char sc_name[8];
-
-	if (sc_id == L2)
-		snprintf(sc_name, sizeof(sc_name), "l2");
-	else
-		snprintf(sc_name, sizeof(sc_name), "cpu%d", sc_id);
-
-	sc_dir[sc_id] = debugfs_create_dir(sc_name, base_dir);
-	if (!sc_dir[sc_id])
-		return;
-
-	debugfs_create_file("auto_gating", S_IRUGO | S_IWUSR,
-			sc_dir[sc_id], (void *)sc_id, &acgd_fops);
-
-	debugfs_create_file("rate", S_IRUGO,
-			sc_dir[sc_id], (void *)sc_id, &rate_fops);
-
-	debugfs_create_file("hfpll_l", S_IRUGO,
-			sc_dir[sc_id], (void *)sc_id, &hfpll_l_fops);
-
-	debugfs_create_file("src", S_IRUGO,
-			sc_dir[sc_id], (void *)sc_id, &src_name_fops);
-
-	if (sc_id == L2)
-		debugfs_create_file("bw_ib_vote", S_IRUGO,
-			sc_dir[sc_id], (void *)sc_id, &bw_vote_fops);
-	else
-		debugfs_create_file("l2_vote", S_IRUGO,
-			sc_dir[sc_id], (void *)sc_id, &l2_vote_fops);
-}
-
-static void __cpuinit remove_scalable_dir(int sc_id)
-{
-	debugfs_remove_recursive(sc_dir[sc_id]);
-	sc_dir[sc_id] = NULL;
-}
-
-static int __cpuinit debug_cpu_callback(struct notifier_block *nfb,
-			unsigned long action, void *hcpu)
-{
-	int cpu = (int)hcpu;
-
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_DOWN_FAILED:
-	case CPU_UP_PREPARE:
-		add_scalable_dir(cpu);
-		break;
-	case CPU_UP_CANCELED:
-	case CPU_DOWN_PREPARE:
-		remove_scalable_dir(cpu);
-		break;
-	default:
-		break;
-	}
-
-	return NOTIFY_OK;
-}
-
-static struct notifier_block __cpuinitdata debug_cpu_notifier = {
-	.notifier_call = debug_cpu_callback,
-};
-
-void __init acpuclk_krait_debug_init(struct drv_data *drv_data)
-{
-	int cpu;
-	drv = drv_data;
-
-	base_dir = debugfs_create_dir("acpuclk", NULL);
-	if (!base_dir)
-		return;
-
-	debugfs_create_file("speed_bin", S_IRUGO, base_dir, NULL,
-							&speed_bin_fops);
-	debugfs_create_file("pvs_bin", S_IRUGO, base_dir, NULL, &pvs_bin_fops);
-	debugfs_create_file("boost_uv", S_IRUGO, base_dir, NULL, &boost_fops);
-	debugfs_create_file("acpu_table", S_IRUGO, base_dir, NULL,
-				&acpu_table_fops);
-
-	for_each_online_cpu(cpu)
-		add_scalable_dir(cpu);
-	add_scalable_dir(L2);
-
-	register_hotcpu_notifier(&debug_cpu_notifier);
-}
diff --git a/arch/arm/mach-msm/acpuclock-krait.c b/arch/arm/mach-msm/acpuclock-krait.c
deleted file mode 100644
index c5b1deb..0000000
--- a/arch/arm/mach-msm/acpuclock-krait.c
+++ /dev/null
@@ -1,1250 +0,0 @@
-/*
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/err.h>
-#include <linux/errno.h>
-#include <linux/cpufreq.h>
-#include <linux/cpu.h>
-#include <linux/regulator/consumer.h>
-#include <linux/iopoll.h>
-
-#include <asm/mach-types.h>
-#include <asm/cpu.h>
-
-#include <mach/board.h>
-#include <mach/msm_iomap.h>
-#include <mach/socinfo.h>
-#include <mach/msm-krait-l2-accessors.h>
-#include <mach/rpm-regulator.h>
-#include <mach/rpm-regulator-smd.h>
-#include <mach/msm_bus.h>
-#include <mach/msm_dcvs.h>
-
-#include "acpuclock.h"
-#include "acpuclock-krait.h"
-#include "avs.h"
-
-/* MUX source selects. */
-#define PRI_SRC_SEL_SEC_SRC	0
-#define PRI_SRC_SEL_HFPLL	1
-#define PRI_SRC_SEL_HFPLL_DIV2	2
-
-static DEFINE_MUTEX(driver_lock);
-static DEFINE_SPINLOCK(l2_lock);
-
-static struct drv_data drv;
-
-static unsigned long acpuclk_krait_get_rate(int cpu)
-{
-	return drv.scalable[cpu].cur_speed->khz;
-}
-
-struct set_clk_src_args {
-	struct scalable *sc;
-	u32 src_sel;
-};
-
-static void __set_pri_clk_src(struct scalable *sc, u32 pri_src_sel)
-{
-	u32 regval;
-
-	regval = get_l2_indirect_reg(sc->l2cpmr_iaddr);
-	regval &= ~0x3;
-	regval |= pri_src_sel;
-	if (sc != &drv.scalable[L2]) {
-		regval &= ~(0x3 << 8);
-		regval |= pri_src_sel << 8;
-	}
-	set_l2_indirect_reg(sc->l2cpmr_iaddr, regval);
-	/* Wait for switch to complete. */
-	mb();
-	udelay(1);
-}
-
-static void __set_cpu_pri_clk_src(void *data)
-{
-	struct set_clk_src_args *args = data;
-	__set_pri_clk_src(args->sc, args->src_sel);
-}
-
-/* Select a source on the primary MUX. */
-static void set_pri_clk_src(struct scalable *sc, u32 pri_src_sel)
-{
-	int cpu = sc - drv.scalable;
-	if (sc != &drv.scalable[L2] && cpu_online(cpu)) {
-		struct set_clk_src_args args = {
-			.sc = sc,
-			.src_sel = pri_src_sel,
-		};
-		smp_call_function_single(cpu, __set_cpu_pri_clk_src, &args, 1);
-	} else {
-		__set_pri_clk_src(sc, pri_src_sel);
-	}
-}
-
-/* Select a source on the secondary MUX. */
-static void __cpuinit set_sec_clk_src(struct scalable *sc, u32 sec_src_sel)
-{
-	u32 regval;
-
-	regval = get_l2_indirect_reg(sc->l2cpmr_iaddr);
-	regval &= ~(0x3 << 2);
-	regval |= sec_src_sel << 2;
-	if (sc != &drv.scalable[L2]) {
-		regval &= ~(0x3 << 10);
-		regval |= sec_src_sel << 10;
-	}
-	set_l2_indirect_reg(sc->l2cpmr_iaddr, regval);
-	/* Wait for switch to complete. */
-	mb();
-	udelay(1);
-}
-
-static int enable_rpm_vreg(struct vreg *vreg)
-{
-	int ret = 0;
-
-	if (vreg->rpm_reg) {
-		ret = rpm_regulator_enable(vreg->rpm_reg);
-		if (ret)
-			dev_err(drv.dev, "%s regulator enable failed (%d)\n",
-				vreg->name, ret);
-	}
-
-	return ret;
-}
-
-static void disable_rpm_vreg(struct vreg *vreg)
-{
-	int rc;
-
-	if (vreg->rpm_reg) {
-		rc = rpm_regulator_disable(vreg->rpm_reg);
-		if (rc)
-			dev_err(drv.dev, "%s regulator disable failed (%d)\n",
-				vreg->name, rc);
-	}
-}
-
-/* Enable an already-configured HFPLL. */
-static void hfpll_enable(struct scalable *sc, bool skip_regulators)
-{
-	if (!skip_regulators) {
-		/* Enable regulators required by the HFPLL. */
-		enable_rpm_vreg(&sc->vreg[VREG_HFPLL_A]);
-		enable_rpm_vreg(&sc->vreg[VREG_HFPLL_B]);
-	}
-
-	/* Disable PLL bypass mode. */
-	writel_relaxed(0x2, sc->hfpll_base + drv.hfpll_data->mode_offset);
-
-	/*
-	 * H/W requires a 5us delay between disabling the bypass and
-	 * de-asserting the reset. Delay 10us just to be safe.
-	 */
-	mb();
-	udelay(10);
-
-	/* De-assert active-low PLL reset. */
-	writel_relaxed(0x6, sc->hfpll_base + drv.hfpll_data->mode_offset);
-
-	/* Wait for PLL to lock. */
-	if (drv.hfpll_data->has_lock_status) {
-		u32 regval;
-		readl_tight_poll(sc->hfpll_base + drv.hfpll_data->status_offset,
-			   regval, regval & BIT(16));
-	} else {
-		mb();
-		udelay(60);
-	}
-
-	/* Enable PLL output. */
-	writel_relaxed(0x7, sc->hfpll_base + drv.hfpll_data->mode_offset);
-}
-
-/* Disable a HFPLL for power-savings or while it's being reprogrammed. */
-static void hfpll_disable(struct scalable *sc, bool skip_regulators)
-{
-	/*
-	 * Disable the PLL output, disable test mode, enable the bypass mode,
-	 * and assert the reset.
-	 */
-	writel_relaxed(0, sc->hfpll_base + drv.hfpll_data->mode_offset);
-
-	if (!skip_regulators) {
-		/* Remove voltage votes required by the HFPLL. */
-		disable_rpm_vreg(&sc->vreg[VREG_HFPLL_B]);
-		disable_rpm_vreg(&sc->vreg[VREG_HFPLL_A]);
-	}
-}
-
-/* Program the HFPLL rate. Assumes HFPLL is already disabled. */
-static void hfpll_set_rate(struct scalable *sc, const struct core_speed *tgt_s)
-{
-	void __iomem *base = sc->hfpll_base;
-	u32 regval;
-
-	writel_relaxed(tgt_s->pll_l_val, base + drv.hfpll_data->l_offset);
-
-	if (drv.hfpll_data->has_user_reg) {
-		regval = readl_relaxed(base + drv.hfpll_data->user_offset);
-		if (tgt_s->pll_l_val <= drv.hfpll_data->low_vco_l_max)
-			regval &= ~drv.hfpll_data->user_vco_mask;
-		else
-			regval |= drv.hfpll_data->user_vco_mask;
-		writel_relaxed(regval, base  + drv.hfpll_data->user_offset);
-	}
-}
-
-/* Return the L2 speed that should be applied. */
-static unsigned int compute_l2_level(struct scalable *sc, unsigned int vote_l)
-{
-	unsigned int new_l = 0;
-	int cpu;
-
-	/* Find max L2 speed vote. */
-	sc->l2_vote = vote_l;
-	for_each_present_cpu(cpu)
-		new_l = max(new_l, drv.scalable[cpu].l2_vote);
-
-	return new_l;
-}
-
-/* Update the bus bandwidth request. */
-static void set_bus_bw(unsigned int bw)
-{
-	int ret;
-
-	/* Update bandwidth if request has changed. This may sleep. */
-	ret = msm_bus_scale_client_update_request(drv.bus_perf_client, bw);
-	if (ret)
-		dev_err(drv.dev, "bandwidth request failed (%d)\n", ret);
-}
-
-/* Set the CPU or L2 clock speed. */
-static void set_speed(struct scalable *sc, const struct core_speed *tgt_s,
-	bool skip_regulators)
-{
-	const struct core_speed *strt_s = sc->cur_speed;
-
-	if (strt_s == tgt_s)
-		return;
-
-	if (strt_s->src == HFPLL && tgt_s->src == HFPLL) {
-		/*
-		 * Move to an always-on source running at a frequency
-		 * that does not require an elevated CPU voltage.
-		 */
-		set_pri_clk_src(sc, PRI_SRC_SEL_SEC_SRC);
-
-		/* Re-program HFPLL. */
-		hfpll_disable(sc, true);
-		hfpll_set_rate(sc, tgt_s);
-		hfpll_enable(sc, true);
-
-		/* Move to HFPLL. */
-		set_pri_clk_src(sc, tgt_s->pri_src_sel);
-	} else if (strt_s->src == HFPLL && tgt_s->src != HFPLL) {
-		set_pri_clk_src(sc, tgt_s->pri_src_sel);
-		hfpll_disable(sc, skip_regulators);
-	} else if (strt_s->src != HFPLL && tgt_s->src == HFPLL) {
-		hfpll_set_rate(sc, tgt_s);
-		hfpll_enable(sc, skip_regulators);
-		set_pri_clk_src(sc, tgt_s->pri_src_sel);
-	}
-
-	sc->cur_speed = tgt_s;
-}
-
-struct vdd_data {
-	int vdd_mem;
-	int vdd_dig;
-	int vdd_core;
-	int ua_core;
-};
-
-/* Apply any per-cpu voltage increases. */
-static int increase_vdd(int cpu, struct vdd_data *data,
-			enum setrate_reason reason)
-{
-	struct scalable *sc = &drv.scalable[cpu];
-	int rc;
-
-	/*
-	 * Increase vdd_mem active-set before vdd_dig.
-	 * vdd_mem should be >= vdd_dig.
-	 */
-	if (data->vdd_mem > sc->vreg[VREG_MEM].cur_vdd) {
-		rc = rpm_regulator_set_voltage(sc->vreg[VREG_MEM].rpm_reg,
-				data->vdd_mem, sc->vreg[VREG_MEM].max_vdd);
-		if (rc) {
-			dev_err(drv.dev,
-				"vdd_mem (cpu%d) increase failed (%d)\n",
-				cpu, rc);
-			return rc;
-		}
-		 sc->vreg[VREG_MEM].cur_vdd = data->vdd_mem;
-	}
-
-	/* Increase vdd_dig active-set vote. */
-	if (data->vdd_dig > sc->vreg[VREG_DIG].cur_vdd) {
-		rc = rpm_regulator_set_voltage(sc->vreg[VREG_DIG].rpm_reg,
-				data->vdd_dig, sc->vreg[VREG_DIG].max_vdd);
-		if (rc) {
-			dev_err(drv.dev,
-				"vdd_dig (cpu%d) increase failed (%d)\n",
-				cpu, rc);
-			return rc;
-		}
-		sc->vreg[VREG_DIG].cur_vdd = data->vdd_dig;
-	}
-
-	/* Increase current request. */
-	if (data->ua_core > sc->vreg[VREG_CORE].cur_ua) {
-		rc = regulator_set_optimum_mode(sc->vreg[VREG_CORE].reg,
-						data->ua_core);
-		if (rc < 0) {
-			dev_err(drv.dev, "regulator_set_optimum_mode(%s) failed (%d)\n",
-				sc->vreg[VREG_CORE].name, rc);
-			return rc;
-		}
-		sc->vreg[VREG_CORE].cur_ua = data->ua_core;
-	}
-
-	/*
-	 * Update per-CPU core voltage. Don't do this for the hotplug path for
-	 * which it should already be correct. Attempting to set it is bad
-	 * because we don't know what CPU we are running on at this point, but
-	 * the CPU regulator API requires we call it from the affected CPU.
-	 */
-	if (data->vdd_core > sc->vreg[VREG_CORE].cur_vdd
-			&& reason != SETRATE_HOTPLUG) {
-		rc = regulator_set_voltage(sc->vreg[VREG_CORE].reg,
-				data->vdd_core, sc->vreg[VREG_CORE].max_vdd);
-		if (rc) {
-			dev_err(drv.dev,
-				"vdd_core (cpu%d) increase failed (%d)\n",
-				cpu, rc);
-			return rc;
-		}
-		sc->vreg[VREG_CORE].cur_vdd = data->vdd_core;
-	}
-
-	return 0;
-}
-
-/* Apply any per-cpu voltage decreases. */
-static void decrease_vdd(int cpu, struct vdd_data *data,
-			 enum setrate_reason reason)
-{
-	struct scalable *sc = &drv.scalable[cpu];
-	int ret;
-
-	/*
-	 * Update per-CPU core voltage. This must be called on the CPU
-	 * that's being affected. Don't do this in the hotplug remove path,
-	 * where the rail is off and we're executing on the other CPU.
-	 */
-	if (data->vdd_core < sc->vreg[VREG_CORE].cur_vdd
-			&& reason != SETRATE_HOTPLUG) {
-		ret = regulator_set_voltage(sc->vreg[VREG_CORE].reg,
-				data->vdd_core, sc->vreg[VREG_CORE].max_vdd);
-		if (ret) {
-			dev_err(drv.dev,
-				"vdd_core (cpu%d) decrease failed (%d)\n",
-				cpu, ret);
-			return;
-		}
-		sc->vreg[VREG_CORE].cur_vdd = data->vdd_core;
-	}
-
-	/* Decrease current request. */
-	if (data->ua_core < sc->vreg[VREG_CORE].cur_ua) {
-		ret = regulator_set_optimum_mode(sc->vreg[VREG_CORE].reg,
-						data->ua_core);
-		if (ret < 0) {
-			dev_err(drv.dev, "regulator_set_optimum_mode(%s) failed (%d)\n",
-				sc->vreg[VREG_CORE].name, ret);
-			return;
-		}
-		sc->vreg[VREG_CORE].cur_ua = data->ua_core;
-	}
-
-	/* Decrease vdd_dig active-set vote. */
-	if (data->vdd_dig < sc->vreg[VREG_DIG].cur_vdd) {
-		ret = rpm_regulator_set_voltage(sc->vreg[VREG_DIG].rpm_reg,
-				data->vdd_dig, sc->vreg[VREG_DIG].max_vdd);
-		if (ret) {
-			dev_err(drv.dev,
-				"vdd_dig (cpu%d) decrease failed (%d)\n",
-				cpu, ret);
-			return;
-		}
-		sc->vreg[VREG_DIG].cur_vdd = data->vdd_dig;
-	}
-
-	/*
-	 * Decrease vdd_mem active-set after vdd_dig.
-	 * vdd_mem should be >= vdd_dig.
-	 */
-	if (data->vdd_mem < sc->vreg[VREG_MEM].cur_vdd) {
-		ret = rpm_regulator_set_voltage(sc->vreg[VREG_MEM].rpm_reg,
-				data->vdd_mem, sc->vreg[VREG_MEM].max_vdd);
-		if (ret) {
-			dev_err(drv.dev,
-				"vdd_mem (cpu%d) decrease failed (%d)\n",
-				cpu, ret);
-			return;
-		}
-		sc->vreg[VREG_MEM].cur_vdd = data->vdd_mem;
-	}
-}
-
-static int calculate_vdd_mem(const struct acpu_level *tgt)
-{
-	return drv.l2_freq_tbl[tgt->l2_level].vdd_mem;
-}
-
-static int get_src_dig(const struct core_speed *s)
-{
-	const int *hfpll_vdd = drv.hfpll_data->vdd;
-	const u32 low_vdd_l_max = drv.hfpll_data->low_vdd_l_max;
-	const u32 nom_vdd_l_max = drv.hfpll_data->nom_vdd_l_max;
-
-	if (s->src != HFPLL)
-		return hfpll_vdd[HFPLL_VDD_NONE];
-	else if (s->pll_l_val > nom_vdd_l_max)
-		return hfpll_vdd[HFPLL_VDD_HIGH];
-	else if (s->pll_l_val > low_vdd_l_max)
-		return hfpll_vdd[HFPLL_VDD_NOM];
-	else
-		return hfpll_vdd[HFPLL_VDD_LOW];
-}
-
-static int calculate_vdd_dig(const struct acpu_level *tgt)
-{
-	int l2_pll_vdd_dig, cpu_pll_vdd_dig;
-
-	l2_pll_vdd_dig = get_src_dig(&drv.l2_freq_tbl[tgt->l2_level].speed);
-	cpu_pll_vdd_dig = get_src_dig(&tgt->speed);
-
-	return max(drv.l2_freq_tbl[tgt->l2_level].vdd_dig,
-		   max(l2_pll_vdd_dig, cpu_pll_vdd_dig));
-}
-
-static bool enable_boost = true;
-module_param_named(boost, enable_boost, bool, S_IRUGO | S_IWUSR);
-
-static int calculate_vdd_core(const struct acpu_level *tgt)
-{
-	return tgt->vdd_core + (enable_boost ? drv.boost_uv : 0);
-}
-
-static DEFINE_MUTEX(l2_regulator_lock);
-static int l2_vreg_count;
-
-static int enable_l2_regulators(void)
-{
-	int ret = 0;
-
-	mutex_lock(&l2_regulator_lock);
-	if (l2_vreg_count == 0) {
-		ret = enable_rpm_vreg(&drv.scalable[L2].vreg[VREG_HFPLL_A]);
-		if (ret)
-			goto out;
-		ret = enable_rpm_vreg(&drv.scalable[L2].vreg[VREG_HFPLL_B]);
-		if (ret) {
-			disable_rpm_vreg(&drv.scalable[L2].vreg[VREG_HFPLL_A]);
-			goto out;
-		}
-	}
-	l2_vreg_count++;
-out:
-	mutex_unlock(&l2_regulator_lock);
-
-	return ret;
-}
-
-static void disable_l2_regulators(void)
-{
-	mutex_lock(&l2_regulator_lock);
-
-	if (WARN(!l2_vreg_count, "L2 regulator votes are unbalanced!"))
-		goto out;
-
-	if (l2_vreg_count == 1) {
-		disable_rpm_vreg(&drv.scalable[L2].vreg[VREG_HFPLL_B]);
-		disable_rpm_vreg(&drv.scalable[L2].vreg[VREG_HFPLL_A]);
-	}
-	l2_vreg_count--;
-out:
-	mutex_unlock(&l2_regulator_lock);
-}
-
-/* Set the CPU's clock rate and adjust the L2 rate, voltage and BW requests. */
-static int acpuclk_krait_set_rate(int cpu, unsigned long rate,
-				  enum setrate_reason reason)
-{
-	const struct core_speed *strt_acpu_s, *tgt_acpu_s;
-	const struct acpu_level *tgt;
-	int tgt_l2_l;
-	enum src_id prev_l2_src = NUM_SRC_ID;
-	struct vdd_data vdd_data;
-	bool skip_regulators;
-	int rc = 0;
-
-	if (cpu > num_possible_cpus())
-		return -EINVAL;
-
-	if (reason == SETRATE_CPUFREQ || reason == SETRATE_HOTPLUG)
-		mutex_lock(&driver_lock);
-
-	strt_acpu_s = drv.scalable[cpu].cur_speed;
-
-	/* Return early if rate didn't change. */
-	if (rate == strt_acpu_s->khz)
-		goto out;
-
-	/* Find target frequency. */
-	for (tgt = drv.acpu_freq_tbl; tgt->speed.khz != 0; tgt++) {
-		if (tgt->speed.khz == rate) {
-			tgt_acpu_s = &tgt->speed;
-			break;
-		}
-	}
-	if (tgt->speed.khz == 0) {
-		rc = -EINVAL;
-		goto out;
-	}
-
-	/* Calculate voltage requirements for the current CPU. */
-	vdd_data.vdd_mem  = calculate_vdd_mem(tgt);
-	vdd_data.vdd_dig  = calculate_vdd_dig(tgt);
-	vdd_data.vdd_core = calculate_vdd_core(tgt);
-	vdd_data.ua_core = tgt->ua_core;
-
-	/* Disable AVS before voltage switch */
-	if (reason == SETRATE_CPUFREQ && drv.scalable[cpu].avs_enabled) {
-		AVS_DISABLE(cpu);
-		drv.scalable[cpu].avs_enabled = false;
-	}
-
-	/* Increase VDD levels if needed. */
-	if (reason == SETRATE_CPUFREQ || reason == SETRATE_HOTPLUG) {
-		rc = increase_vdd(cpu, &vdd_data, reason);
-		if (rc)
-			goto out;
-
-		prev_l2_src =
-			drv.l2_freq_tbl[drv.scalable[cpu].l2_vote].speed.src;
-		/* Vote for the L2 regulators here if necessary. */
-		if (drv.l2_freq_tbl[tgt->l2_level].speed.src == HFPLL) {
-			rc = enable_l2_regulators();
-			if (rc)
-				goto out;
-		}
-	}
-
-	dev_dbg(drv.dev, "Switching from ACPU%d rate %lu KHz -> %lu KHz\n",
-		cpu, strt_acpu_s->khz, tgt_acpu_s->khz);
-
-	/*
-	 * If we are setting the rate as part of power collapse or in the resume
-	 * path after power collapse, skip the vote for the HFPLL regulators,
-	 * which are active-set-only votes that will be removed when apps enters
-	 * its sleep set. This is needed to avoid voting for regulators with
-	 * sleeping APIs from an atomic context.
-	 */
-	skip_regulators = (reason == SETRATE_PC);
-
-	/* Set the new CPU speed. */
-	set_speed(&drv.scalable[cpu], tgt_acpu_s, skip_regulators);
-
-	/*
-	 * Update the L2 vote and apply the rate change. A spinlock is
-	 * necessary to ensure L2 rate is calculated and set atomically
-	 * with the CPU frequency, even if acpuclk_krait_set_rate() is
-	 * called from an atomic context and the driver_lock mutex is not
-	 * acquired.
-	 */
-	spin_lock(&l2_lock);
-	tgt_l2_l = compute_l2_level(&drv.scalable[cpu], tgt->l2_level);
-	set_speed(&drv.scalable[L2],
-			&drv.l2_freq_tbl[tgt_l2_l].speed, true);
-	spin_unlock(&l2_lock);
-
-	/* Nothing else to do for power collapse or SWFI. */
-	if (reason == SETRATE_PC || reason == SETRATE_SWFI)
-		goto out;
-
-	/*
-	 * Remove the vote for the L2 HFPLL regulators only if the L2
-	 * was already on an HFPLL source.
-	 */
-	if (prev_l2_src == HFPLL)
-		disable_l2_regulators();
-
-	/* Update bus bandwith request. */
-	set_bus_bw(drv.l2_freq_tbl[tgt_l2_l].bw_level);
-
-	/* Drop VDD levels if we can. */
-	decrease_vdd(cpu, &vdd_data, reason);
-
-	/* Re-enable AVS */
-	if (reason == SETRATE_CPUFREQ && tgt->avsdscr_setting) {
-		AVS_ENABLE(cpu, tgt->avsdscr_setting);
-		drv.scalable[cpu].avs_enabled = true;
-	}
-
-	dev_dbg(drv.dev, "ACPU%d speed change complete\n", cpu);
-
-out:
-	if (reason == SETRATE_CPUFREQ || reason == SETRATE_HOTPLUG)
-		mutex_unlock(&driver_lock);
-	return rc;
-}
-
-static struct acpuclk_data acpuclk_krait_data = {
-	.set_rate = acpuclk_krait_set_rate,
-	.get_rate = acpuclk_krait_get_rate,
-};
-
-/* Initialize a HFPLL at a given rate and enable it. */
-static void __cpuinit hfpll_init(struct scalable *sc,
-			      const struct core_speed *tgt_s)
-{
-	dev_dbg(drv.dev, "Initializing HFPLL%d\n", sc - drv.scalable);
-
-	/* Disable the PLL for re-programming. */
-	hfpll_disable(sc, true);
-
-	/* Configure PLL parameters for integer mode. */
-	writel_relaxed(drv.hfpll_data->config_val,
-		       sc->hfpll_base + drv.hfpll_data->config_offset);
-	writel_relaxed(0, sc->hfpll_base + drv.hfpll_data->m_offset);
-	writel_relaxed(1, sc->hfpll_base + drv.hfpll_data->n_offset);
-	if (drv.hfpll_data->has_user_reg)
-		writel_relaxed(drv.hfpll_data->user_val,
-			       sc->hfpll_base + drv.hfpll_data->user_offset);
-
-	/* Program droop controller, if supported */
-	if (drv.hfpll_data->has_droop_ctl)
-		writel_relaxed(drv.hfpll_data->droop_val,
-			       sc->hfpll_base + drv.hfpll_data->droop_offset);
-
-	/* Set an initial PLL rate. */
-	hfpll_set_rate(sc, tgt_s);
-}
-
-static int __cpuinit rpm_regulator_init(struct scalable *sc, enum vregs vreg,
-					 int vdd, bool enable)
-{
-	int ret;
-
-	if (!sc->vreg[vreg].name)
-		return 0;
-
-	sc->vreg[vreg].rpm_reg = rpm_regulator_get(drv.dev,
-						   sc->vreg[vreg].name);
-	if (IS_ERR(sc->vreg[vreg].rpm_reg)) {
-		ret = PTR_ERR(sc->vreg[vreg].rpm_reg);
-		dev_err(drv.dev, "rpm_regulator_get(%s) failed (%d)\n",
-			sc->vreg[vreg].name, ret);
-		goto err_get;
-	}
-
-	ret = rpm_regulator_set_voltage(sc->vreg[vreg].rpm_reg, vdd,
-					sc->vreg[vreg].max_vdd);
-	if (ret) {
-		dev_err(drv.dev, "%s initialization failed (%d)\n",
-			sc->vreg[vreg].name, ret);
-		goto err_conf;
-	}
-	sc->vreg[vreg].cur_vdd = vdd;
-
-	if (enable) {
-		ret = enable_rpm_vreg(&sc->vreg[vreg]);
-		if (ret)
-			goto err_conf;
-	}
-
-	return 0;
-
-err_conf:
-	rpm_regulator_put(sc->vreg[vreg].rpm_reg);
-err_get:
-	return ret;
-}
-
-static void __cpuinit rpm_regulator_cleanup(struct scalable *sc,
-						enum vregs vreg)
-{
-	if (!sc->vreg[vreg].rpm_reg)
-		return;
-
-	disable_rpm_vreg(&sc->vreg[vreg]);
-	rpm_regulator_put(sc->vreg[vreg].rpm_reg);
-}
-
-/* Voltage regulator initialization. */
-static int __cpuinit regulator_init(struct scalable *sc,
-				const struct acpu_level *acpu_level)
-{
-	int ret, vdd_mem, vdd_dig, vdd_core;
-
-	vdd_mem = calculate_vdd_mem(acpu_level);
-	ret = rpm_regulator_init(sc, VREG_MEM, vdd_mem, true);
-	if (ret)
-		goto err_mem;
-
-	vdd_dig = calculate_vdd_dig(acpu_level);
-	ret = rpm_regulator_init(sc, VREG_DIG, vdd_dig, true);
-	if (ret)
-		goto err_dig;
-
-	ret = rpm_regulator_init(sc, VREG_HFPLL_A,
-			   sc->vreg[VREG_HFPLL_A].max_vdd, false);
-	if (ret)
-		goto err_hfpll_a;
-	ret = rpm_regulator_init(sc, VREG_HFPLL_B,
-			   sc->vreg[VREG_HFPLL_B].max_vdd, false);
-	if (ret)
-		goto err_hfpll_b;
-
-	/* Setup Krait CPU regulators and initial core voltage. */
-	sc->vreg[VREG_CORE].reg = regulator_get(drv.dev,
-				  sc->vreg[VREG_CORE].name);
-	if (IS_ERR(sc->vreg[VREG_CORE].reg)) {
-		ret = PTR_ERR(sc->vreg[VREG_CORE].reg);
-		dev_err(drv.dev, "regulator_get(%s) failed (%d)\n",
-			sc->vreg[VREG_CORE].name, ret);
-		goto err_core_get;
-	}
-	ret = regulator_set_optimum_mode(sc->vreg[VREG_CORE].reg,
-					 acpu_level->ua_core);
-	if (ret < 0) {
-		dev_err(drv.dev, "regulator_set_optimum_mode(%s) failed (%d)\n",
-			sc->vreg[VREG_CORE].name, ret);
-		goto err_core_conf;
-	}
-	sc->vreg[VREG_CORE].cur_ua = acpu_level->ua_core;
-	vdd_core = calculate_vdd_core(acpu_level);
-	ret = regulator_set_voltage(sc->vreg[VREG_CORE].reg, vdd_core,
-				    sc->vreg[VREG_CORE].max_vdd);
-	if (ret) {
-		dev_err(drv.dev, "regulator_set_voltage(%s) (%d)\n",
-			sc->vreg[VREG_CORE].name, ret);
-		goto err_core_conf;
-	}
-	sc->vreg[VREG_CORE].cur_vdd = vdd_core;
-	ret = regulator_enable(sc->vreg[VREG_CORE].reg);
-	if (ret) {
-		dev_err(drv.dev, "regulator_enable(%s) failed (%d)\n",
-			sc->vreg[VREG_CORE].name, ret);
-		goto err_core_conf;
-	}
-
-	/*
-	 * Vote for the L2 HFPLL regulators if _this_ CPU's frequency requires
-	 * a corresponding target L2 frequency that needs the L2 an HFPLL.
-	 */
-	if (drv.l2_freq_tbl[acpu_level->l2_level].speed.src == HFPLL) {
-		ret = enable_l2_regulators();
-		if (ret) {
-			dev_err(drv.dev, "enable_l2_regulators() failed (%d)\n",
-				ret);
-			goto err_l2_regs;
-		}
-	}
-
-	return 0;
-
-err_l2_regs:
-	regulator_disable(sc->vreg[VREG_CORE].reg);
-err_core_conf:
-	regulator_put(sc->vreg[VREG_CORE].reg);
-err_core_get:
-	rpm_regulator_cleanup(sc, VREG_HFPLL_B);
-err_hfpll_b:
-	rpm_regulator_cleanup(sc, VREG_HFPLL_A);
-err_hfpll_a:
-	rpm_regulator_cleanup(sc, VREG_DIG);
-err_dig:
-	rpm_regulator_cleanup(sc, VREG_MEM);
-err_mem:
-	return ret;
-}
-
-static void __cpuinit regulator_cleanup(struct scalable *sc)
-{
-	regulator_disable(sc->vreg[VREG_CORE].reg);
-	regulator_put(sc->vreg[VREG_CORE].reg);
-	rpm_regulator_cleanup(sc, VREG_HFPLL_B);
-	rpm_regulator_cleanup(sc, VREG_HFPLL_A);
-	rpm_regulator_cleanup(sc, VREG_DIG);
-	rpm_regulator_cleanup(sc, VREG_MEM);
-}
-
-/* Set initial rate for a given core. */
-static int __cpuinit init_clock_sources(struct scalable *sc,
-					 const struct core_speed *tgt_s)
-{
-	u32 regval;
-	void __iomem *aux_reg;
-
-	/* Program AUX source input to the secondary MUX. */
-	if (sc->aux_clk_sel_phys) {
-		aux_reg = ioremap(sc->aux_clk_sel_phys, 4);
-		if (!aux_reg)
-			return -ENOMEM;
-		writel_relaxed(sc->aux_clk_sel, aux_reg);
-		iounmap(aux_reg);
-	}
-
-	/* Switch away from the HFPLL while it's re-initialized. */
-	set_sec_clk_src(sc, sc->sec_clk_sel);
-	set_pri_clk_src(sc, PRI_SRC_SEL_SEC_SRC);
-	hfpll_init(sc, tgt_s);
-
-	/* Set PRI_SRC_SEL_HFPLL_DIV2 divider to div-2. */
-	regval = get_l2_indirect_reg(sc->l2cpmr_iaddr);
-	regval &= ~(0x3 << 6);
-	if (sc != &drv.scalable[L2])
-		regval &= ~(0x3 << 14);
-	set_l2_indirect_reg(sc->l2cpmr_iaddr, regval);
-
-	/* Enable and switch to the target clock source. */
-	if (tgt_s->src == HFPLL)
-		hfpll_enable(sc, false);
-	set_pri_clk_src(sc, tgt_s->pri_src_sel);
-	sc->cur_speed = tgt_s;
-
-	return 0;
-}
-
-static void __cpuinit fill_cur_core_speed(struct core_speed *s,
-					  struct scalable *sc)
-{
-	s->pri_src_sel = get_l2_indirect_reg(sc->l2cpmr_iaddr) & 0x3;
-	s->pll_l_val = readl_relaxed(sc->hfpll_base + drv.hfpll_data->l_offset);
-}
-
-static bool __cpuinit speed_equal(const struct core_speed *s1,
-				  const struct core_speed *s2)
-{
-	return (s1->pri_src_sel == s2->pri_src_sel &&
-		s1->pll_l_val == s2->pll_l_val);
-}
-
-static const struct acpu_level __cpuinit *find_cur_acpu_level(int cpu)
-{
-	struct scalable *sc = &drv.scalable[cpu];
-	const struct acpu_level *l;
-	struct core_speed cur_speed;
-
-	fill_cur_core_speed(&cur_speed, sc);
-	for (l = drv.acpu_freq_tbl; l->speed.khz != 0; l++)
-		if (speed_equal(&l->speed, &cur_speed))
-			return l;
-	return NULL;
-}
-
-static const struct l2_level __init *find_cur_l2_level(void)
-{
-	struct scalable *sc = &drv.scalable[L2];
-	const struct l2_level *l;
-	struct core_speed cur_speed;
-
-	fill_cur_core_speed(&cur_speed, sc);
-	for (l = drv.l2_freq_tbl; l->speed.khz != 0; l++)
-		if (speed_equal(&l->speed, &cur_speed))
-			return l;
-	return NULL;
-}
-
-static const struct acpu_level __cpuinit *find_min_acpu_level(void)
-{
-	struct acpu_level *l;
-
-	for (l = drv.acpu_freq_tbl; l->speed.khz != 0; l++)
-		if (l->use_for_scaling)
-			return l;
-
-	return NULL;
-}
-
-static int __cpuinit per_cpu_init(int cpu)
-{
-	struct scalable *sc = &drv.scalable[cpu];
-	const struct acpu_level *acpu_level;
-	int ret;
-
-	sc->hfpll_base = ioremap(sc->hfpll_phys_base, SZ_32);
-	if (!sc->hfpll_base) {
-		ret = -ENOMEM;
-		goto err_ioremap;
-	}
-
-	acpu_level = find_cur_acpu_level(cpu);
-	if (!acpu_level) {
-		acpu_level = find_min_acpu_level();
-		if (!acpu_level) {
-			ret = -ENODEV;
-			goto err_table;
-		}
-		dev_warn(drv.dev, "CPU%d is running at an unknown rate. Defaulting to %lu KHz.\n",
-			cpu, acpu_level->speed.khz);
-	} else {
-		dev_dbg(drv.dev, "CPU%d is running at %lu KHz\n", cpu,
-			acpu_level->speed.khz);
-	}
-
-	ret = regulator_init(sc, acpu_level);
-	if (ret)
-		goto err_regulators;
-
-	ret = init_clock_sources(sc, &acpu_level->speed);
-	if (ret)
-		goto err_clocks;
-
-	sc->l2_vote = acpu_level->l2_level;
-	sc->initialized = true;
-
-	return 0;
-
-err_clocks:
-	regulator_cleanup(sc);
-err_regulators:
-err_table:
-	iounmap(sc->hfpll_base);
-err_ioremap:
-	return ret;
-}
-
-/* Register with bus driver. */
-static void __init bus_init(const struct l2_level *l2_level)
-{
-	int ret;
-
-	drv.bus_perf_client = msm_bus_scale_register_client(drv.bus_scale);
-	if (!drv.bus_perf_client) {
-		dev_err(drv.dev, "unable to register bus client\n");
-		BUG();
-	}
-
-	ret = msm_bus_scale_client_update_request(drv.bus_perf_client,
-			l2_level->bw_level);
-	if (ret)
-		dev_err(drv.dev, "initial bandwidth req failed (%d)\n", ret);
-}
-
-#ifdef CONFIG_CPU_FREQ_MSM
-static struct cpufreq_frequency_table freq_table[NR_CPUS][35];
-
-static void __init cpufreq_table_init(void)
-{
-	int cpu;
-	int freq_cnt = 0;
-
-	for_each_possible_cpu(cpu) {
-		int i;
-		/* Construct the freq_table tables from acpu_freq_tbl. */
-		for (i = 0, freq_cnt = 0; drv.acpu_freq_tbl[i].speed.khz != 0
-				&& freq_cnt < ARRAY_SIZE(*freq_table); i++) {
-			if (drv.acpu_freq_tbl[i].use_for_scaling) {
-				freq_table[cpu][freq_cnt].index = freq_cnt;
-				freq_table[cpu][freq_cnt].frequency
-					= drv.acpu_freq_tbl[i].speed.khz;
-				freq_cnt++;
-			}
-		}
-		/* freq_table not big enough to store all usable freqs. */
-		BUG_ON(drv.acpu_freq_tbl[i].speed.khz != 0);
-
-		freq_table[cpu][freq_cnt].index = freq_cnt;
-		freq_table[cpu][freq_cnt].frequency = CPUFREQ_TABLE_END;
-
-		/* Register table with CPUFreq. */
-		cpufreq_frequency_table_get_attr(freq_table[cpu], cpu);
-	}
-
-	dev_info(drv.dev, "CPU Frequencies Supported: %d\n", freq_cnt);
-}
-#else
-static void __init cpufreq_table_init(void) {}
-#endif
-
-static void __init dcvs_freq_init(void)
-{
-	int i;
-
-	for (i = 0; drv.acpu_freq_tbl[i].speed.khz != 0; i++)
-		if (drv.acpu_freq_tbl[i].use_for_scaling)
-			msm_dcvs_register_cpu_freq(
-				drv.acpu_freq_tbl[i].speed.khz,
-				drv.acpu_freq_tbl[i].vdd_core / 1000);
-}
-
-static int __cpuinit acpuclk_cpu_callback(struct notifier_block *nfb,
-					    unsigned long action, void *hcpu)
-{
-	static int prev_khz[NR_CPUS];
-	int rc, cpu = (int)hcpu;
-	struct scalable *sc = &drv.scalable[cpu];
-	unsigned long hot_unplug_khz = acpuclk_krait_data.power_collapse_khz;
-
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_DEAD:
-		prev_khz[cpu] = acpuclk_krait_get_rate(cpu);
-		/* Fall through. */
-	case CPU_UP_CANCELED:
-		acpuclk_krait_set_rate(cpu, hot_unplug_khz, SETRATE_HOTPLUG);
-
-		regulator_disable(sc->vreg[VREG_CORE].reg);
-		regulator_set_optimum_mode(sc->vreg[VREG_CORE].reg, 0);
-		regulator_set_voltage(sc->vreg[VREG_CORE].reg, 0,
-						sc->vreg[VREG_CORE].max_vdd);
-		break;
-	case CPU_UP_PREPARE:
-		if (!sc->initialized) {
-			rc = per_cpu_init(cpu);
-			if (rc)
-				return NOTIFY_BAD;
-			break;
-		}
-		if (WARN_ON(!prev_khz[cpu]))
-			return NOTIFY_BAD;
-
-		rc = regulator_set_voltage(sc->vreg[VREG_CORE].reg,
-					sc->vreg[VREG_CORE].cur_vdd,
-					sc->vreg[VREG_CORE].max_vdd);
-		if (rc < 0)
-			return NOTIFY_BAD;
-		rc = regulator_set_optimum_mode(sc->vreg[VREG_CORE].reg,
-						sc->vreg[VREG_CORE].cur_ua);
-		if (rc < 0)
-			return NOTIFY_BAD;
-		rc = regulator_enable(sc->vreg[VREG_CORE].reg);
-		if (rc < 0)
-			return NOTIFY_BAD;
-
-		acpuclk_krait_set_rate(cpu, prev_khz[cpu], SETRATE_HOTPLUG);
-		break;
-	default:
-		break;
-	}
-
-	return NOTIFY_OK;
-}
-
-static struct notifier_block __cpuinitdata acpuclk_cpu_notifier = {
-	.notifier_call = acpuclk_cpu_callback,
-};
-
-static const int __init krait_needs_vmin(void)
-{
-	switch (read_cpuid_id()) {
-	case 0x511F04D0: /* KR28M2A20 */
-	case 0x511F04D1: /* KR28M2A21 */
-	case 0x510F06F0: /* KR28M4A10 */
-		return 1;
-	default:
-		return 0;
-	};
-}
-
-static void __init krait_apply_vmin(struct acpu_level *tbl)
-{
-	for (; tbl->speed.khz != 0; tbl++) {
-		if (tbl->vdd_core < 1150000)
-			tbl->vdd_core = 1150000;
-		tbl->avsdscr_setting = 0;
-	}
-}
-
-void __init get_krait_bin_format_a(void __iomem *base, struct bin_info *bin)
-{
-	u32 pte_efuse = readl_relaxed(base);
-
-	bin->speed = pte_efuse & 0xF;
-	if (bin->speed == 0xF)
-		bin->speed = (pte_efuse >> 4) & 0xF;
-	bin->speed_valid = bin->speed != 0xF;
-
-	bin->pvs = (pte_efuse >> 10) & 0x7;
-	if (bin->pvs == 0x7)
-		bin->pvs = (pte_efuse >> 13) & 0x7;
-	bin->pvs_valid = bin->pvs != 0x7;
-}
-
-void __init get_krait_bin_format_b(void __iomem *base, struct bin_info *bin)
-{
-	u32 pte_efuse, redundant_sel;
-
-	pte_efuse = readl_relaxed(base);
-	redundant_sel = (pte_efuse >> 24) & 0x7;
-	bin->pvs_rev = (pte_efuse >> 4) & 0x3;
-	bin->speed = pte_efuse & 0x7;
-	/* PVS number is in bits 31, 8, 7, 6 */
-	bin->pvs = ((pte_efuse >> 28) & 0x8) | ((pte_efuse >> 6) & 0x7);
-
-	switch (redundant_sel) {
-	case 1:
-		bin->speed = (pte_efuse >> 27) & 0xF;
-		break;
-	case 2:
-		bin->pvs = (pte_efuse >> 27) & 0xF;
-		break;
-	}
-	bin->speed_valid = true;
-
-	/* Check PVS_BLOW_STATUS */
-	pte_efuse = readl_relaxed(base + 0x4);
-	bin->pvs_valid = !!(pte_efuse & BIT(21));
-}
-
-static struct pvs_table * __init select_freq_plan(
-		const struct acpuclk_krait_params *params)
-{
-	void __iomem *pte_efuse_base;
-	struct bin_info bin;
-
-	pte_efuse_base = ioremap(params->pte_efuse_phys, 8);
-	if (!pte_efuse_base) {
-		dev_err(drv.dev, "Unable to map PTE eFuse base\n");
-		return NULL;
-	}
-	params->get_bin_info(pte_efuse_base, &bin);
-	iounmap(pte_efuse_base);
-
-	if (bin.speed_valid) {
-		drv.speed_bin = bin.speed;
-		dev_info(drv.dev, "SPEED BIN: %d\n", drv.speed_bin);
-	} else {
-		drv.speed_bin = 0;
-		dev_warn(drv.dev, "SPEED BIN: Defaulting to %d\n",
-			 drv.speed_bin);
-	}
-
-	if (bin.pvs_valid) {
-		drv.pvs_bin = bin.pvs;
-		dev_info(drv.dev, "ACPU PVS: %d\n", drv.pvs_bin);
-		drv.pvs_rev = bin.pvs_rev;
-		dev_info(drv.dev, "ACPU PVS REVISION: %d\n", drv.pvs_rev);
-	} else {
-		drv.pvs_bin = 0;
-		dev_warn(drv.dev, "ACPU PVS: Defaulting to %d\n",
-			 drv.pvs_bin);
-	}
-
-	return &params->pvs_tables[drv.pvs_rev][drv.speed_bin][drv.pvs_bin];
-}
-
-static void __init drv_data_init(struct device *dev,
-				 const struct acpuclk_krait_params *params)
-{
-	struct pvs_table *pvs;
-
-	drv.dev = dev;
-	drv.scalable = kmemdup(params->scalable, params->scalable_size,
-				GFP_KERNEL);
-	BUG_ON(!drv.scalable);
-
-	drv.hfpll_data = kmemdup(params->hfpll_data, sizeof(*drv.hfpll_data),
-				GFP_KERNEL);
-	BUG_ON(!drv.hfpll_data);
-
-	drv.l2_freq_tbl = kmemdup(params->l2_freq_tbl, params->l2_freq_tbl_size,
-				GFP_KERNEL);
-	BUG_ON(!drv.l2_freq_tbl);
-
-	drv.bus_scale = kmemdup(params->bus_scale, sizeof(*drv.bus_scale),
-				GFP_KERNEL);
-	BUG_ON(!drv.bus_scale);
-	drv.bus_scale->usecase = kmemdup(drv.bus_scale->usecase,
-		drv.bus_scale->num_usecases * sizeof(*drv.bus_scale->usecase),
-		GFP_KERNEL);
-	BUG_ON(!drv.bus_scale->usecase);
-
-	pvs = select_freq_plan(params);
-	BUG_ON(!pvs->table);
-
-	drv.acpu_freq_tbl = kmemdup(pvs->table, pvs->size, GFP_KERNEL);
-	BUG_ON(!drv.acpu_freq_tbl);
-	drv.boost_uv = pvs->boost_uv;
-
-	acpuclk_krait_data.power_collapse_khz = params->stby_khz;
-	acpuclk_krait_data.wait_for_irq_khz = params->stby_khz;
-}
-
-static void __init hw_init(void)
-{
-	struct scalable *l2 = &drv.scalable[L2];
-	const struct l2_level *l2_level;
-	int cpu, rc;
-
-	if (krait_needs_vmin())
-		krait_apply_vmin(drv.acpu_freq_tbl);
-
-	l2->hfpll_base = ioremap(l2->hfpll_phys_base, SZ_32);
-	BUG_ON(!l2->hfpll_base);
-
-	rc = rpm_regulator_init(l2, VREG_HFPLL_A,
-				l2->vreg[VREG_HFPLL_A].max_vdd, false);
-	BUG_ON(rc);
-	rc = rpm_regulator_init(l2, VREG_HFPLL_B,
-				l2->vreg[VREG_HFPLL_B].max_vdd, false);
-	BUG_ON(rc);
-
-	l2_level = find_cur_l2_level();
-	if (!l2_level) {
-		l2_level = drv.l2_freq_tbl;
-		dev_warn(drv.dev, "L2 is running at an unknown rate. Defaulting to %lu KHz.\n",
-			l2_level->speed.khz);
-	} else {
-		dev_dbg(drv.dev, "L2 is running at %lu KHz\n",
-			l2_level->speed.khz);
-	}
-
-	rc = init_clock_sources(l2, &l2_level->speed);
-	BUG_ON(rc);
-
-	for_each_online_cpu(cpu) {
-		rc = per_cpu_init(cpu);
-		BUG_ON(rc);
-	}
-
-	bus_init(l2_level);
-}
-
-int __init acpuclk_krait_init(struct device *dev,
-			      const struct acpuclk_krait_params *params)
-{
-	drv_data_init(dev, params);
-	hw_init();
-
-	cpufreq_table_init();
-	dcvs_freq_init();
-	acpuclk_register(&acpuclk_krait_data);
-	register_hotcpu_notifier(&acpuclk_cpu_notifier);
-
-	acpuclk_krait_debug_init(&drv);
-
-	return 0;
-}
diff --git a/arch/arm/mach-msm/acpuclock-krait.h b/arch/arm/mach-msm/acpuclock-krait.h
deleted file mode 100644
index 4eff45d..0000000
--- a/arch/arm/mach-msm/acpuclock-krait.h
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef __ARCH_ARM_MACH_MSM_ACPUCLOCK_KRAIT_H
-#define __ARCH_ARM_MACH_MSM_ACPUCLOCK_KRAIT_H
-
-#define L2(x) (x)
-#define BW_MBPS(_bw) \
-	{ \
-		.vectors = (struct msm_bus_vectors[]){ \
-			{\
-				.src = MSM_BUS_MASTER_AMPSS_M0, \
-				.dst = MSM_BUS_SLAVE_EBI_CH0, \
-				.ib = (_bw) * 1000000ULL, \
-			}, \
-			{ \
-				.src = MSM_BUS_MASTER_AMPSS_M1, \
-				.dst = MSM_BUS_SLAVE_EBI_CH0, \
-				.ib = (_bw) * 1000000ULL, \
-			}, \
-		}, \
-		.num_paths = 2, \
-	}
-
-/**
- * src_id - Clock source IDs.
- */
-enum src_id {
-	PLL_0 = 0,
-	HFPLL,
-	PLL_8,
-	NUM_SRC_ID
-};
-
-/**
- * enum pvs - IDs to distinguish between CPU frequency tables.
- */
-enum pvs {
-	PVS_SLOW = 0,
-	PVS_NOMINAL = 1,
-	PVS_FAST = 3,
-	PVS_FASTER = 4,
-	NUM_PVS = 16
-};
-
-/**
- * The maximum number of PVS revisions.
- */
-#define NUM_PVS_REVS (4)
-
-/**
- * The maximum number of speed bins.
- */
-#define NUM_SPEED_BINS (16)
-
-/**
- * enum scalables - IDs of frequency scalable hardware blocks.
- */
-enum scalables {
-	CPU0 = 0,
-	CPU1,
-	CPU2,
-	CPU3,
-	L2,
-	MAX_SCALABLES
-};
-
-
-/**
- * enum hfpll_vdd_level - IDs of HFPLL voltage levels.
- */
-enum hfpll_vdd_levels {
-	HFPLL_VDD_NONE,
-	HFPLL_VDD_LOW,
-	HFPLL_VDD_NOM,
-	HFPLL_VDD_HIGH,
-	NUM_HFPLL_VDD
-};
-
-/**
- * enum vregs - IDs of voltage regulators.
- */
-enum vregs {
-	VREG_CORE,
-	VREG_MEM,
-	VREG_DIG,
-	VREG_HFPLL_A,
-	VREG_HFPLL_B,
-	NUM_VREG
-};
-
-/**
- * struct vreg - Voltage regulator data.
- * @name: Name of requlator.
- * @max_vdd: Limit the maximum-settable voltage.
- * @reg: Regulator handle.
- * @rpm_reg: RPM Regulator handle.
- * @cur_vdd: Last-set voltage in uV.
- * @cur_ua: Last-set current in uA.
- */
-struct vreg {
-	const char *name;
-	const int max_vdd;
-	struct regulator *reg;
-	struct rpm_regulator *rpm_reg;
-	int cur_vdd;
-	int cur_ua;
-};
-
-/**
- * struct core_speed - Clock tree and configuration parameters.
- * @khz: Clock rate in KHz.
- * @src: Clock source ID.
- * @pri_src_sel: Input to select on the primary MUX.
- * @pll_l_val: HFPLL "L" value to be applied when an HFPLL source is selected.
- */
-struct core_speed {
-	unsigned long khz;
-	int src;
-	u32 pri_src_sel;
-	u32 pll_l_val;
-};
-
-/**
- * struct l2_level - L2 clock rate and associated voltage and b/w requirements.
- * @speed: L2 clock configuration.
- * @vdd_dig: vdd_dig voltage in uV.
- * @vdd_mem: vdd_mem voltage in uV.
- * @bw_level: Bandwidth performance level number.
- */
-struct l2_level {
-	const struct core_speed speed;
-	const int vdd_dig;
-	const int vdd_mem;
-	const unsigned int bw_level;
-};
-
-/**
- * struct acpu_level - CPU clock rate and L2 rate and voltage requirements.
- * @use_for_scaling: Flag indicating whether or not the level should be used.
- * @speed: CPU clock configuration.
- * @l2_level: L2 configuration to use.
- * @vdd_core: CPU core voltage in uV.
- * @ua_core: CPU core current consumption in uA.
- * @avsdscr_setting: AVS DSCR configuration.
- */
-struct acpu_level {
-	const int use_for_scaling;
-	const struct core_speed speed;
-	unsigned int l2_level;
-	int vdd_core;
-	int ua_core;
-	unsigned int avsdscr_setting;
-};
-
-/**
- * struct hfpll_data - Descriptive data of HFPLL hardware.
- * @mode_offset: Mode register offset from base address.
- * @l_offset: "L" value register offset from base address.
- * @m_offset: "M" value register offset from base address.
- * @n_offset: "N" value register offset from base address.
- * @config_offset: Configuration register offset from base address.
- * @config_val: Value to initialize the @config_offset register to.
- * @has_user_reg: Indicates the presence of an addition config register.
- * @user_offset: User register offset from base address, if applicable.
- * @user_val: Value to initialize the @user_offset register to.
- * @user_vco_mask: Bit in the @user_offset to enable high-frequency VCO mode.
- * @has_droop_ctl: Indicates the presence of a voltage droop controller.
- * @has_lock_status: Indicates the presence of a lock status bit.
- * @droop_offset: Droop controller register offset from base address.
- * @droop_val: Value to initialize the @config_offset register to.
- * @status_offset: PLL status register offset.
- * @low_vdd_l_max: Maximum "L" value supported at HFPLL_VDD_LOW.
- * @nom_vdd_l_max: Maximum "L" value supported at HFPLL_VDD_NOM.
- * @low_vco_l_max: Maximum "L" value supported in low-frequency VCO mode.
- * @vdd: voltage requirements for each VDD level for the L2 PLL.
- */
-struct hfpll_data {
-	const u32 mode_offset;
-	const u32 l_offset;
-	const u32 m_offset;
-	const u32 n_offset;
-	const u32 config_offset;
-	const u32 config_val;
-	const bool has_user_reg;
-	const u32 user_offset;
-	const u32 user_val;
-	const u32 user_vco_mask;
-	const bool has_droop_ctl;
-	const bool has_lock_status;
-	const u32 droop_offset;
-	const u32 droop_val;
-	const u32 status_offset;
-	u32 low_vdd_l_max;
-	u32 nom_vdd_l_max;
-	const u32 low_vco_l_max;
-	const int vdd[NUM_HFPLL_VDD];
-};
-
-/**
- * struct scalable - Register locations and state associated with a scalable HW.
- * @hfpll_phys_base: Physical base address of HFPLL register.
- * @hfpll_base: Virtual base address of HFPLL registers.
- * @aux_clk_sel_phys: Physical address of auxiliary MUX.
- * @aux_clk_sel: Auxiliary mux input to select at boot.
- * @sec_clk_sel: Secondary mux input to select at boot.
- * @l2cpmr_iaddr: Indirect address of the CPMR MUX/divider CP15 register.
- * @cur_speed: Pointer to currently-set speed.
- * @l2_vote: L2 performance level vote associate with the current CPU speed.
- * @vreg: Array of voltage regulators needed by the scalable.
- * @initialized: Flag set to true when per_cpu_init() has been called.
- * @avs_enabled: True if avs is enabled for the scalabale. False otherwise.
- */
-struct scalable {
-	const phys_addr_t hfpll_phys_base;
-	void __iomem *hfpll_base;
-	const phys_addr_t aux_clk_sel_phys;
-	const u32 aux_clk_sel;
-	const u32 sec_clk_sel;
-	const u32 l2cpmr_iaddr;
-	const struct core_speed *cur_speed;
-	unsigned int l2_vote;
-	struct vreg vreg[NUM_VREG];
-	bool initialized;
-	bool avs_enabled;
-};
-
-/**
- * struct bin_info - Hardware speed and voltage binning info.
- * @speed_valid: @speed field is valid
- * @pvs_valid: @pvs field is valid
- * @speed: Speed bin ID
- * @pvs: PVS bin ID
- * @pvs_rev: PVS revision ID
- */
-struct bin_info {
-	bool speed_valid;
-	bool pvs_valid;
-	int speed;
-	int pvs;
-	int pvs_rev;
-};
-
-/**
- * struct pvs_table - CPU performance level table and size.
- * @table: CPU performance level table
- * @size: sizeof(@table)
- * @boost_uv: Voltage boost amount
- */
-struct pvs_table {
-	struct acpu_level *table;
-	size_t size;
-	int boost_uv;
-};
-
-/**
- * struct acpuclk_krait_params - SoC specific driver parameters.
- * @scalable: Array of scalables.
- * @scalable_size: Size of @scalable.
- * @hfpll_data: HFPLL configuration data.
- * @pvs_tables: 2D array of CPU frequency tables.
- * @l2_freq_tbl: L2 frequency table.
- * @l2_freq_tbl_size: Size of @l2_freq_tbl.
- * @pte_efuse_phys: Physical address of PTE EFUSE.
- * @get_bin_info: Function to populate bin_info from pte_efuse.
- * @bus_scale: MSM bus driver parameters.
- * @stby_khz: KHz value corresponding to an always-on clock source.
- */
-struct acpuclk_krait_params {
-	struct scalable *scalable;
-	size_t scalable_size;
-	struct hfpll_data *hfpll_data;
-	struct pvs_table (*pvs_tables)[NUM_SPEED_BINS][NUM_PVS];
-	struct l2_level *l2_freq_tbl;
-	size_t l2_freq_tbl_size;
-	phys_addr_t pte_efuse_phys;
-	void (*get_bin_info)(void __iomem *base, struct bin_info *bin);
-	struct msm_bus_scale_pdata *bus_scale;
-	unsigned long stby_khz;
-};
-
-/**
- * struct drv_data - Driver state
- * @acpu_freq_tbl: CPU frequency table.
- * @l2_freq_tbl: L2 frequency table.
- * @scalable: Array of scalables (CPUs and L2).
- * @hfpll_data: High-frequency PLL data.
- * @bus_perf_client: Bus driver client handle.
- * @bus_scale: Bus driver scaling data.
- * @boost_uv: Voltage boost amount
- * @speed_bin: Speed bin ID.
- * @pvs_bin: PVS bin ID.
- * @pvs_bin: PVS revision ID.
- * @dev: Device.
- */
-struct drv_data {
-	struct acpu_level *acpu_freq_tbl;
-	const struct l2_level *l2_freq_tbl;
-	struct scalable *scalable;
-	struct hfpll_data *hfpll_data;
-	u32 bus_perf_client;
-	struct msm_bus_scale_pdata *bus_scale;
-	int boost_uv;
-	int speed_bin;
-	int pvs_bin;
-	int pvs_rev;
-	struct device *dev;
-};
-
-/**
- * struct acpuclk_platform_data - PMIC configuration data.
- * @uses_pm8917: Boolean indicates presence of pm8917.
- */
-struct acpuclk_platform_data {
-	bool uses_pm8917;
-};
-
-/**
- * get_krait_bin_format_a - Populate bin_info from a 'Format A' pte_efuse
- */
-void __init get_krait_bin_format_a(void __iomem *base, struct bin_info *bin);
-
-/**
- * get_krait_bin_format_b - Populate bin_info from a 'Format B' pte_efuse
- */
-void __init get_krait_bin_format_b(void __iomem *base, struct bin_info *bin);
-
-/**
- * acpuclk_krait_init - Initialize the Krait CPU clock driver give SoC params.
- */
-extern int acpuclk_krait_init(struct device *dev,
-			      const struct acpuclk_krait_params *params);
-
-#ifdef CONFIG_DEBUG_FS
-/**
- * acpuclk_krait_debug_init - Initialize debugfs interface.
- */
-extern void __init acpuclk_krait_debug_init(struct drv_data *drv);
-#else
-static inline void acpuclk_krait_debug_init(void) { }
-#endif
-
-#endif
diff --git a/arch/arm/mach-msm/board-8610-gpiomux.c b/arch/arm/mach-msm/board-8610-gpiomux.c
index 03f8837..affe6bd 100644
--- a/arch/arm/mach-msm/board-8610-gpiomux.c
+++ b/arch/arm/mach-msm/board-8610-gpiomux.c
@@ -631,6 +631,28 @@
 	},
 };
 
+static struct gpiomux_setting gpio_cdc_dmic_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_4MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+
+static struct msm_gpiomux_config msm_cdc_dmic_configs[] __initdata = {
+	{
+		.gpio = 100,	/* DMIC CLK */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_cdc_dmic_cfg,
+		},
+	},
+	{
+		.gpio = 101,	/* DMIC DATA */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_cdc_dmic_cfg,
+		},
+	},
+};
+
 void __init msm8610_init_gpiomux(void)
 {
 	int rc;
@@ -668,4 +690,7 @@
 		msm_gpiomux_install(msm_non_qrd_configs,
 			ARRAY_SIZE(msm_non_qrd_configs));
 	}
+	if (of_board_is_cdp())
+		msm_gpiomux_install(msm_cdc_dmic_configs,
+			ARRAY_SIZE(msm_cdc_dmic_configs));
 }
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index d79464a..2050f38 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -98,7 +98,6 @@
 #include "pm-boot.h"
 #include "msm_watchdog.h"
 #include "board-8930.h"
-#include "acpuclock-krait.h"
 #include "platsmp.h"
 
 static struct platform_device msm_fm_platform_init = {
@@ -2655,8 +2654,6 @@
 /* Modify platform data values to match requirements for PM8917. */
 static void __init msm8930_pm8917_pdata_fixup(void)
 {
-	struct acpuclk_platform_data *pdata;
-
 	msm8930_pm8917_wcd9xxx_pdata_fixup(&sitar_platform_data);
 	msm8930_pm8917_wcd9xxx_pdata_fixup(&sitar1p1_platform_data);
 
@@ -2672,12 +2669,6 @@
 
 	msm8930_device_rpm_regulator.dev.platform_data
 		= &msm8930_pm8917_rpm_regulator_pdata;
-
-	pdata = msm8930_device_acpuclk.dev.platform_data;
-	pdata->uses_pm8917 = true;
-
-	pdata = msm8930ab_device_acpuclk.dev.platform_data;
-	pdata->uses_pm8917 = true;
 }
 
 static void __init msm8930ab_update_retention_spm(void)
diff --git a/arch/arm/mach-msm/board-8974.c b/arch/arm/mach-msm/board-8974.c
index 80a957f..7b13bbc 100644
--- a/arch/arm/mach-msm/board-8974.c
+++ b/arch/arm/mach-msm/board-8974.c
@@ -108,6 +108,11 @@
 	msm_thermal_device_init();
 }
 
+static struct of_dev_auxdata msm_hsic_host_adata[] = {
+	OF_DEV_AUXDATA("qcom,hsic-host", 0xF9A00000, "msm_hsic_host", NULL),
+	{}
+};
+
 static struct of_dev_auxdata msm8974_auxdata_lookup[] __initdata = {
 	OF_DEV_AUXDATA("qcom,hsusb-otg", 0xF9A55000, \
 			"msm_otg", NULL),
@@ -148,6 +153,8 @@
 			"qcrypto.0", NULL),
 	OF_DEV_AUXDATA("qcom,hsic-host", 0xF9A00000, \
 			"msm_hsic_host", NULL),
+	OF_DEV_AUXDATA("qcom,hsic-smsc-hub", 0, "msm_smsc_hub",
+			msm_hsic_host_adata),
 	{}
 };
 
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index 53cea4e..3a0c152 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -694,6 +694,7 @@
 	F_GCC(  56000000,      gpll0,   1,    7,   75),
 	F_GCC(  58982400,      gpll0,   1, 1536, 15625),
 	F_GCC(  60000000,      gpll0,  10,    0,    0),
+	F_GCC(  63160000,      gpll0, 9.5,    0,    0),
 	F_END
 };
 
@@ -1278,6 +1279,7 @@
 	.en_mask = BIT(5),
 	.base = &virt_bases[GCC_BASE],
 	.c = {
+		.parent = &ce1_clk_src.c,
 		.dbg_name = "gcc_ce1_clk",
 		.ops = &clk_ops_vote,
 		CLK_INIT(gcc_ce1_clk.c),
@@ -3148,7 +3150,7 @@
 	CLK_LOOKUP("iface_clk",   gcc_mss_cfg_ahb_clk.c, "fc880000.qcom,mss"),
 	CLK_LOOKUP("mem_clk",    gcc_boot_rom_ahb_clk.c, "fc880000.qcom,mss"),
 	/* NFC */
-	CLK_LOOKUP("ref_clk",            cxo_d1_a_pin.c, "2-000e"),
+	CLK_LOOKUP("ref_clk",            cxo_d1_pin.c, "2-000e"),
 	/* PIL-PRONTO */
 	CLK_LOOKUP("xo", cxo_pil_pronto_clk.c, "fb21b000.qcom,pronto"),
 
diff --git a/arch/arm/mach-msm/clock-8610.c b/arch/arm/mach-msm/clock-8610.c
index dcc7c76..c7bf92c 100644
--- a/arch/arm/mach-msm/clock-8610.c
+++ b/arch/arm/mach-msm/clock-8610.c
@@ -677,6 +677,7 @@
 	F(  960000, gcc_xo, 10, 1, 2),
 	F( 4800000, gcc_xo,  4, 0, 0),
 	F( 9600000, gcc_xo,  2, 0, 0),
+	F(12000000,  gpll0, 10, 1, 5),
 	F(15000000,  gpll0, 10, 1, 4),
 	F(19200000, gcc_xo,  1, 0, 0),
 	F(25000000,  gpll0, 12, 1, 2),
@@ -783,6 +784,7 @@
 	F(56000000,  gpll0,    1,    7,    75),
 	F(58982400,  gpll0,    1, 1536, 15625),
 	F(60000000,  gpll0,   10,    0,     0),
+	F(63160000,  gpll0,  9.5,    0,     0),
 	F_END,
 };
 
@@ -1284,6 +1286,7 @@
 	.en_mask = BIT(5),
 	.base = &virt_bases[GCC_BASE],
 	.c = {
+		.parent = &ce1_clk_src.c,
 		.dbg_name = "gcc_ce1_clk",
 		.ops = &clk_ops_vote,
 		CLK_INIT(gcc_ce1_clk.c),
diff --git a/arch/arm/mach-msm/clock-krypton.c b/arch/arm/mach-msm/clock-krypton.c
index 176dc32..2b529b0 100644
--- a/arch/arm/mach-msm/clock-krypton.c
+++ b/arch/arm/mach-msm/clock-krypton.c
@@ -515,6 +515,7 @@
 	F(  56000000,      gpll0,    1,    7,    75),
 	F(  58982400,      gpll0,    1, 1536, 15625),
 	F(  60000000,      gpll0,   10,    0,     0),
+	F(  63160000,      gpll0,  9.5,    0,     0),
 	F_END
 };
 
diff --git a/arch/arm/mach-msm/cpr-regulator.c b/arch/arm/mach-msm/cpr-regulator.c
index 6ddf340..1cf2e41 100644
--- a/arch/arm/mach-msm/cpr-regulator.c
+++ b/arch/arm/mach-msm/cpr-regulator.c
@@ -25,6 +25,7 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
+#include <linux/cpufreq.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/regulator/cpr-regulator.h>
@@ -130,6 +131,16 @@
 
 #define BYTES_PER_FUSE_ROW		8
 
+#define FLAGS_SET_MIN_VOLTAGE		BIT(1)
+#define FLAGS_UPLIFT_QUOT_VOLT		BIT(2)
+#define FLAGS_QUOT_ADJUST_WITH_FREQ	BIT(3)
+
+struct cpufreq_mapping_info {
+	int freq;
+	int quot_adjust;
+	int corner;
+};
+
 enum voltage_change_dir {
 	NO_CHANGE,
 	DOWN,
@@ -153,10 +164,7 @@
 	/* Process voltage variables */
 	u32		pvs_bin;
 	u32		process;
-
-	/* Control parameter to read efuse parameters by trustzone API */
-	bool		use_tz_api;
-
+	u32		speed_bin;
 	/* APC voltage regulator */
 	struct regulator	*vdd_apc;
 
@@ -171,6 +179,7 @@
 	bool		cpr_fuse_disable;
 	bool		cpr_fuse_local;
 	int		cpr_fuse_target_quot[CPR_CORNER_MAX];
+	int		cpr_fuse_original_quot[CPR_CORNER_MAX];
 	int		cpr_fuse_ro_sel[CPR_CORNER_MAX];
 	int		gcnt;
 
@@ -204,6 +213,11 @@
 	u32		gcnt_time_us;
 	u32		vdd_apc_step_up_limit;
 	u32		vdd_apc_step_down_limit;
+	u32		flags;
+	struct notifier_block freq_transition;
+	unsigned int	freq;
+	struct cpufreq_mapping_info *cpufreq_mapping;
+	u32		cpufreq_mapping_size;
 };
 
 #define CPR_DEBUG_MASK_IRQ	BIT(0)
@@ -228,7 +242,8 @@
 	} while (0)
 
 
-static u64 cpr_read_efuse_row(struct cpr_regulator *cpr_vreg, u32 row_num)
+static u64 cpr_read_efuse_row(struct cpr_regulator *cpr_vreg, u32 row_num,
+				bool use_tz_api)
 {
 	int rc;
 	u64 efuse_bits;
@@ -242,7 +257,7 @@
 		u32 status;
 	} rsp;
 
-	if (cpr_vreg->use_tz_api != true) {
+	if (!use_tz_api) {
 		efuse_bits = readll_relaxed(cpr_vreg->efuse_base
 			+ row_num * BYTES_PER_FUSE_ROW);
 		return efuse_bits;
@@ -265,6 +280,28 @@
 	return efuse_bits;
 }
 
+static int cpr_get_freq_corner(struct cpr_regulator *cpr_vreg, int freq)
+{
+	int i;
+
+	for (i = 0; i < cpr_vreg->cpufreq_mapping_size; i++) {
+		if (freq == cpr_vreg->cpufreq_mapping[i].freq)
+			return cpr_vreg->cpufreq_mapping[i].corner;
+	}
+
+	return -EINVAL;
+}
+
+static int cpr_get_freq_quot_adjust(struct cpr_regulator *cpr_vreg, int freq)
+{
+	int i;
+
+	for (i = 0; i < cpr_vreg->cpufreq_mapping_size; i++) {
+		if (freq == cpr_vreg->cpufreq_mapping[i].freq)
+			return cpr_vreg->cpufreq_mapping[i].quot_adjust;
+	}
+	return 0;
+}
 
 static bool cpr_is_allowed(struct cpr_regulator *cpr_vreg)
 {
@@ -339,6 +376,13 @@
 	cpr_ctl_modify(cpr_vreg, RBCPR_CTL_LOOP_EN, 0);
 }
 
+static bool cpr_ctl_is_enabled(struct cpr_regulator *cpr_vreg)
+{
+	u32 val;
+	val = cpr_read(cpr_vreg, REG_RBCPR_CTL);
+	return ((val & RBCPR_CTL_LOOP_EN) == RBCPR_CTL_LOOP_EN);
+}
+
 static void cpr_regs_save(struct cpr_regulator *cpr_vreg)
 {
 	int i, offset;
@@ -371,6 +415,13 @@
 static void cpr_corner_restore(struct cpr_regulator *cpr_vreg, int corner)
 {
 	u32 gcnt, ctl, irq, ro_sel;
+	int adjust;
+
+	if (cpr_vreg->flags & FLAGS_QUOT_ADJUST_WITH_FREQ) {
+		adjust = cpr_get_freq_quot_adjust(cpr_vreg, cpr_vreg->freq);
+		cpr_vreg->cpr_fuse_target_quot[corner] =
+		cpr_vreg->cpr_fuse_original_quot[corner] - adjust;
+	}
 
 	ro_sel = cpr_vreg->cpr_fuse_ro_sel[corner];
 	gcnt = cpr_vreg->gcnt | cpr_vreg->cpr_fuse_target_quot[corner];
@@ -973,23 +1024,54 @@
 	return 0;
 }
 
-static int __devinit cpr_is_fuse_redundant(struct cpr_regulator *cpr_vreg,
-					 u32 redun_sel[4])
+static int __devinit cpr_fuse_is_setting_expected(struct cpr_regulator *cpr_vreg,
+					u32 sel_array[5])
 {
 	u64 fuse_bits;
-	int redundant;
+	u32 ret;
 
-	fuse_bits = cpr_read_efuse_row(cpr_vreg, redun_sel[0]);
-	fuse_bits = (fuse_bits >> redun_sel[1]) & ((1 << redun_sel[2]) - 1);
-	if (fuse_bits == redun_sel[3])
-		redundant = 1;
+	fuse_bits = cpr_read_efuse_row(cpr_vreg, sel_array[0], sel_array[4]);
+	ret = (fuse_bits >> sel_array[1]) & ((1 << sel_array[2]) - 1);
+	if (ret == sel_array[3])
+		ret = 1;
 	else
-		redundant = 0;
+		ret = 0;
 
-	pr_info("[row:%d] = 0x%llx @%d:%d = %d?: redundant=%d\n",
-		redun_sel[0], fuse_bits,
-		redun_sel[1], redun_sel[2], redun_sel[3], redundant);
-	return redundant;
+	pr_info("[row:%d] = 0x%llx @%d:%d == %d ?: %s\n",
+			sel_array[0], fuse_bits,
+			sel_array[1], sel_array[2],
+			sel_array[3],
+			(ret == 1) ? "yes" : "no");
+	return ret;
+}
+
+static int cpr_voltage_uplift_wa_inc_volt(struct cpr_regulator *cpr_vreg,
+					struct device_node *of_node)
+{
+	u32 uplift_voltage;
+	u32 uplift_max_volt = 0;
+	int rc, i;
+
+	rc = of_property_read_u32(of_node,
+		"qti,cpr-uplift-voltage", &uplift_voltage);
+	if (rc < 0) {
+		pr_err("cpr-uplift-voltage is missing, rc = %d", rc);
+		return rc;
+	}
+	rc = of_property_read_u32(of_node,
+		"qti,cpr-uplift-max-volt", &uplift_max_volt);
+	if (rc < 0) {
+		pr_err("cpr-uplift-max-volt is missing, rc = %d", rc);
+		return rc;
+	}
+
+	for (i = 0; i < CPR_PVS_EFUSE_BINS_MAX; i++) {
+		cpr_vreg->pvs_init_v[i] += uplift_voltage;
+		if (cpr_vreg->pvs_init_v[i] > uplift_max_volt)
+			cpr_vreg->pvs_init_v[i] = uplift_max_volt;
+	}
+
+	return rc;
 }
 
 static int __devinit cpr_pvs_init(struct platform_device *pdev,
@@ -998,30 +1080,30 @@
 	struct device_node *of_node = pdev->dev.of_node;
 	u64 efuse_bits;
 	int rc, process;
-	u32 pvs_fuse[3], pvs_fuse_redun_sel[4];
+	u32 pvs_fuse[4], pvs_fuse_redun_sel[5];
 	u32 init_v;
 	bool redundant;
 	size_t pvs_bins;
 
-	rc = of_property_read_u32_array(of_node, "qcom,pvs-fuse-redun-sel",
-					pvs_fuse_redun_sel, 4);
+	rc = of_property_read_u32_array(of_node, "qti,pvs-fuse-redun-sel",
+					pvs_fuse_redun_sel, 5);
 	if (rc < 0) {
 		pr_err("pvs-fuse-redun-sel missing: rc=%d\n", rc);
 		return rc;
 	}
 
-	redundant = cpr_is_fuse_redundant(cpr_vreg, pvs_fuse_redun_sel);
+	redundant = cpr_fuse_is_setting_expected(cpr_vreg, pvs_fuse_redun_sel);
 
 	if (redundant) {
-		rc = of_property_read_u32_array(of_node, "qcom,pvs-fuse-redun",
-						pvs_fuse, 3);
+		rc = of_property_read_u32_array(of_node, "qti,pvs-fuse-redun",
+						pvs_fuse, 4);
 		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);
+		rc = of_property_read_u32_array(of_node, "qti,pvs-fuse",
+						pvs_fuse, 4);
 		if (rc < 0) {
 			pr_err("pvs-fuse missing: rc=%d\n", rc);
 			return rc;
@@ -1030,19 +1112,27 @@
 
 	/* Construct PVS process # from the efuse bits */
 
-	efuse_bits = cpr_read_efuse_row(cpr_vreg, pvs_fuse[0]);
+	efuse_bits = cpr_read_efuse_row(cpr_vreg, pvs_fuse[0], pvs_fuse[3]);
 	cpr_vreg->pvs_bin = (efuse_bits >> pvs_fuse[1]) &
 				   ((1 << pvs_fuse[2]) - 1);
 
 	pvs_bins = 1 << pvs_fuse[2];
 
-	rc = of_property_read_u32_array(of_node, "qcom,pvs-init-voltage",
+	rc = of_property_read_u32_array(of_node, "qti,pvs-init-voltage",
 					cpr_vreg->pvs_init_v, pvs_bins);
 	if (rc < 0) {
 		pr_err("pvs-init-voltage missing: rc=%d\n", rc);
 		return rc;
 	}
 
+	if (cpr_vreg->flags & FLAGS_UPLIFT_QUOT_VOLT) {
+		rc = cpr_voltage_uplift_wa_inc_volt(cpr_vreg, of_node);
+		if (rc < 0) {
+			pr_err("pvs volt uplift wa apply failed: %d", rc);
+			return rc;
+		}
+	}
+
 	init_v = cpr_vreg->pvs_init_v[cpr_vreg->pvs_bin];
 	for (process = NUM_APC_PVS - 1; process > APC_PVS_NO; process--) {
 		if (init_v <= cpr_vreg->pvs_corner_v[process][CPR_CORNER_TURBO])
@@ -1073,7 +1163,7 @@
 do {									\
 	if (!rc) {							\
 		rc = of_property_read_u32(of_node,			\
-				"qcom," cpr_property,			\
+				"qti," cpr_property,			\
 				cpr_config);				\
 		if (rc) {						\
 			pr_err("Missing " #cpr_property			\
@@ -1110,14 +1200,14 @@
 
 	/* Parse dependency parameters */
 	if (cpr_vreg->vdd_mx) {
-		rc = of_property_read_u32(of_node, "qcom,vdd-mx-vmax",
+		rc = of_property_read_u32(of_node, "qti,vdd-mx-vmax",
 				 &cpr_vreg->vdd_mx_vmax);
 		if (rc < 0) {
 			pr_err("vdd-mx-vmax missing: rc=%d\n", rc);
 			return rc;
 		}
 
-		rc = of_property_read_u32(of_node, "qcom,vdd-mx-vmin-method",
+		rc = of_property_read_u32(of_node, "qti,vdd-mx-vmin-method",
 				 &cpr_vreg->vdd_mx_vmin_method);
 		if (rc < 0) {
 			pr_err("vdd-mx-vmin-method missing: rc=%d\n", rc);
@@ -1143,40 +1233,131 @@
 	}
 }
 
+static int cpr_voltage_uplift_wa_inc_quot(struct cpr_regulator *cpr_vreg,
+					struct device_node *of_node)
+{
+	u32 delta_quot[3];
+	int rc, i;
+
+	rc = of_property_read_u32_array(of_node,
+			"qti,cpr-uplift-quotient", delta_quot, 3);
+	if (rc < 0) {
+		pr_err("cpr-uplift-quotient is missing: %d", rc);
+		return rc;
+	}
+	for (i = CPR_CORNER_SVS; i < CPR_CORNER_MAX; i++)
+		cpr_vreg->cpr_fuse_target_quot[i] += delta_quot[i-1];
+	return rc;
+}
+
+static int cpr_get_of_cprfreq_mappings(struct cpr_regulator *cpr_vreg,
+					struct device *dev)
+{
+	int rc = 0;
+	int i, j, size, stripe_size, length;
+	struct property *prop;
+	u32 *tmp;
+
+	prop = of_find_property(dev->of_node, "qti,cpr-quot-adjust-table",
+				NULL);
+	if (prop) {
+		size = prop->length / sizeof(u32);
+		tmp = kzalloc(sizeof(u32) * size, GFP_KERNEL);
+		if (!tmp)
+			return -ENOMEM;
+
+		rc = of_property_read_u32_array(dev->of_node,
+				"qti,cpr-quot-adjust-table", tmp, size);
+		if (rc) {
+			pr_err("qti,cpr-quot-adjust-table missing, rc = %d",
+				rc);
+			kfree(tmp);
+			return rc;
+		}
+
+		length = 0;
+		stripe_size = 1 + sizeof(struct cpufreq_mapping_info) /
+				sizeof(int);
+		for (i = 0; i < size; i += stripe_size) {
+			if (tmp[i] == cpr_vreg->speed_bin)
+				length++;
+		}
+		if (i != size) {
+			pr_err("qti,cpr-quot-adjust-table data is not correct\n");
+			kfree(tmp);
+			return -EINVAL;
+		}
+
+		cpr_vreg->cpufreq_mapping_size = length;
+		if (length) {
+			cpr_vreg->cpufreq_mapping = devm_kzalloc(dev,
+				sizeof(struct cpufreq_mapping_info) * length,
+				GFP_KERNEL);
+
+			if (!cpr_vreg->cpufreq_mapping) {
+				kfree(tmp);
+				return -ENOMEM;
+			}
+
+			cpr_vreg->flags |= FLAGS_QUOT_ADJUST_WITH_FREQ;
+
+			for (i = 0, j = 0; i < size; i += stripe_size) {
+				if (tmp[i] == cpr_vreg->speed_bin) {
+					cpr_vreg->cpufreq_mapping[j].freq =
+						tmp[i+1];
+					cpr_vreg->cpufreq_mapping[j].quot_adjust
+					= tmp[i+2];
+					cpr_vreg->cpufreq_mapping[j].corner =
+						tmp[i+3];
+					++j;
+				}
+
+			}
+
+		}
+
+		kfree(tmp);
+	}
+
+	return rc;
+}
+
 static int __devinit cpr_init_cpr_efuse(struct platform_device *pdev,
 				     struct cpr_regulator *cpr_vreg)
 {
 	struct device_node *of_node = pdev->dev.of_node;
 	int i, rc = 0;
 	bool redundant;
-	u32 cpr_fuse_redun_sel[4];
+	u32 cpr_fuse_redun_sel[5];
 	char *targ_quot_str, *ro_sel_str;
-	u32 cpr_fuse_row;
+	u32 cpr_fuse_row[2];
 	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, fuse_bits_2;
 
-	rc = of_property_read_u32_array(of_node, "qcom,cpr-fuse-redun-sel",
-					cpr_fuse_redun_sel, 4);
+	rc = of_property_read_u32_array(of_node, "qti,cpr-fuse-redun-sel",
+					cpr_fuse_redun_sel, 5);
 	if (rc < 0) {
 		pr_err("cpr-fuse-redun-sel missing: rc=%d\n", rc);
 		return rc;
 	}
 
-	redundant = cpr_is_fuse_redundant(cpr_vreg, cpr_fuse_redun_sel);
+	redundant = cpr_fuse_is_setting_expected(cpr_vreg, cpr_fuse_redun_sel);
 
 	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";
+		rc = of_property_read_u32_array(of_node,
+				"qti,cpr-fuse-redun-row",
+				cpr_fuse_row, 2);
+		targ_quot_str = "qti,cpr-fuse-redun-target-quot";
+		ro_sel_str = "qti,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";
+		rc = of_property_read_u32_array(of_node,
+				"qti,cpr-fuse-row",
+				cpr_fuse_row, 2);
+		targ_quot_str = "qti,cpr-fuse-target-quot";
+		ro_sel_str = "qti,cpr-fuse-ro-sel";
 	}
 	if (rc)
 		return rc;
@@ -1200,12 +1381,13 @@
 	}
 
 	/* Read the control bits of eFuse */
-	fuse_bits = cpr_read_efuse_row(cpr_vreg, cpr_fuse_row);
-	pr_info("[row:%d] = 0x%llx\n", cpr_fuse_row, fuse_bits);
+	fuse_bits = cpr_read_efuse_row(cpr_vreg, cpr_fuse_row[0],
+					cpr_fuse_row[1]);
+	pr_info("[row:%d] = 0x%llx\n", cpr_fuse_row[0], fuse_bits);
 
 	if (redundant) {
 		if (of_property_read_bool(of_node,
-				"qcom,cpr-fuse-redun-bp-cpr-disable")) {
+				"qti,cpr-fuse-redun-bp-cpr-disable")) {
 			CPR_PROP_READ_U32(of_node,
 					  "cpr-fuse-redun-bp-cpr-disable",
 					  &bp_cpr_disable, rc);
@@ -1216,21 +1398,23 @@
 				return rc;
 			fuse_bits_2 = fuse_bits;
 		} else {
-			u32 temp_row;
+			u32 temp_row[2];
 
 			/* 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);
+			rc = of_property_read_u32_array(of_node,
+					"qti,cpr-fuse-row",
+					temp_row, 2);
 			if (rc)
 				return rc;
 
-			fuse_bits_2 = cpr_read_efuse_row(cpr_vreg, temp_row);
+			fuse_bits_2 = cpr_read_efuse_row(cpr_vreg, temp_row[0],
+							temp_row[1]);
 			pr_info("[original row:%d] = 0x%llx\n",
-				temp_row, fuse_bits_2);
+				temp_row[0], fuse_bits_2);
 		}
 	} else {
 		CPR_PROP_READ_U32(of_node, "cpr-fuse-bp-cpr-disable",
@@ -1259,6 +1443,23 @@
 			i, ro_sel, val);
 	}
 
+	if (cpr_vreg->flags & FLAGS_UPLIFT_QUOT_VOLT) {
+		cpr_voltage_uplift_wa_inc_quot(cpr_vreg, of_node);
+		for (i = CPR_CORNER_SVS; i < CPR_CORNER_MAX; i++) {
+			pr_info("Corner[%d]: uplifted target quot = %d\n",
+				i, cpr_vreg->cpr_fuse_target_quot[i]);
+		}
+	}
+
+	for (i = CPR_CORNER_SVS; i < CPR_CORNER_MAX; i++) {
+		cpr_vreg->cpr_fuse_original_quot[i] =
+		cpr_vreg->cpr_fuse_target_quot[i];
+	}
+
+	rc = cpr_get_of_cprfreq_mappings(cpr_vreg, &pdev->dev);
+	if (rc)
+		return rc;
+
 	cpr_vreg->cpr_fuse_bits = fuse_bits;
 	if (!cpr_vreg->cpr_fuse_bits) {
 		cpr_vreg->cpr_fuse_disable = 1;
@@ -1364,7 +1565,7 @@
 		return rc;
 
 	/* Init module parameter with the DT value */
-	cpr_vreg->enable = of_property_read_bool(of_node, "qcom,cpr-enable");
+	cpr_vreg->enable = of_property_read_bool(of_node, "qti,cpr-enable");
 	cpr_enable = (int) cpr_vreg->enable;
 	pr_info("CPR is %s by default.\n",
 		cpr_vreg->enable ? "enabled" : "disabled");
@@ -1452,11 +1653,6 @@
 		return -EINVAL;
 	}
 
-	if (of_property_read_bool(pdev->dev.of_node, "qcom,use-tz-api"))
-		cpr_vreg->use_tz_api = true;
-	else
-		cpr_vreg->use_tz_api = false;
-
 	return 0;
 }
 
@@ -1465,14 +1661,84 @@
 	iounmap(cpr_vreg->efuse_base);
 }
 
+static void cpr_parse_cond_min_volt_fuse(struct cpr_regulator *cpr_vreg,
+						struct device_node *of_node)
+{
+	int rc;
+	u32 fuse_sel[5];
+	/*
+	 * Restrict all pvs corner voltages to a minimum value of
+	 * qti,cpr-cond-min-voltage if the fuse defined in
+	 * qti,cpr-fuse-cond-min-volt-sel does not read back with
+	 * the expected value.
+	 */
+	rc = of_property_read_u32_array(of_node,
+			"qti,cpr-fuse-cond-min-volt-sel", fuse_sel, 5);
+	if (!rc) {
+		if (!cpr_fuse_is_setting_expected(cpr_vreg, fuse_sel))
+			cpr_vreg->flags |= FLAGS_SET_MIN_VOLTAGE;
+	}
+}
+
+static void cpr_parse_speed_bin_fuse(struct cpr_regulator *cpr_vreg,
+				struct device_node *of_node)
+{
+	int rc;
+	u64 fuse_bits;
+	u32 fuse_sel[4];
+	u32 speed_bits;
+
+	rc = of_property_read_u32_array(of_node,
+			"qti,speed-bin-fuse-sel", fuse_sel, 4);
+
+	if (!rc) {
+		fuse_bits = cpr_read_efuse_row(cpr_vreg,
+				fuse_sel[0], fuse_sel[3]);
+		speed_bits = (fuse_bits >> fuse_sel[1]) &
+			((1 << fuse_sel[2]) - 1);
+		pr_info("[row: %d]: 0x%llx, speed_bits = %d\n",
+				fuse_sel[0], fuse_bits, speed_bits);
+		cpr_vreg->speed_bin = speed_bits;
+	} else {
+		cpr_vreg->speed_bin = UINT_MAX;
+	}
+}
+
+static int cpr_voltage_uplift_enable_check(struct cpr_regulator *cpr_vreg,
+					struct device_node *of_node)
+{
+	int rc;
+	u32 fuse_sel[5];
+	u32 uplift_speed_bin;
+
+	rc = of_property_read_u32_array(of_node,
+			"qti,cpr-fuse-uplift-sel", fuse_sel, 5);
+	if (!rc) {
+		rc = of_property_read_u32(of_node,
+				"qti,cpr-uplift-speed-bin",
+				&uplift_speed_bin);
+		if (rc < 0) {
+			pr_err("qti,cpr-uplift-speed-bin missing\n");
+			return rc;
+		}
+		if (cpr_fuse_is_setting_expected(cpr_vreg, fuse_sel)
+			&& (uplift_speed_bin == cpr_vreg->speed_bin)
+			&& !(cpr_vreg->flags & FLAGS_SET_MIN_VOLTAGE)) {
+			cpr_vreg->flags |= FLAGS_UPLIFT_QUOT_VOLT;
+		}
+	}
+	return 0;
+}
+
 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;
-	int rc, i;
+	int rc, i, j;
+	u32 min_uv = 0;
 
 	rc = of_property_read_u32_array(of_node,
-		"qcom,pvs-corner-ceiling-slow",
+		"qti,pvs-corner-ceiling-slow",
 		&cpr_vreg->pvs_corner_v[APC_PVS_SLOW][CPR_CORNER_SVS],
 		CPR_CORNER_MAX - CPR_CORNER_SVS);
 	if (rc < 0) {
@@ -1481,7 +1747,7 @@
 	}
 
 	rc = of_property_read_u32_array(of_node,
-		"qcom,pvs-corner-ceiling-nom",
+		"qti,pvs-corner-ceiling-nom",
 		&cpr_vreg->pvs_corner_v[APC_PVS_NOM][CPR_CORNER_SVS],
 		CPR_CORNER_MAX - CPR_CORNER_SVS);
 	if (rc < 0) {
@@ -1490,7 +1756,7 @@
 	}
 
 	rc = of_property_read_u32_array(of_node,
-		"qcom,pvs-corner-ceiling-fast",
+		"qti,pvs-corner-ceiling-fast",
 		&cpr_vreg->pvs_corner_v[APC_PVS_FAST][CPR_CORNER_SVS],
 		CPR_CORNER_MAX - CPR_CORNER_SVS);
 	if (rc < 0) {
@@ -1498,6 +1764,22 @@
 		return rc;
 	}
 
+	cpr_parse_cond_min_volt_fuse(cpr_vreg, of_node);
+	cpr_parse_speed_bin_fuse(cpr_vreg, of_node);
+	rc = cpr_voltage_uplift_enable_check(cpr_vreg, of_node);
+	if (rc < 0) {
+		pr_err("voltage uplift enable check failed, %d\n", rc);
+		return rc;
+	}
+	if (cpr_vreg->flags & FLAGS_SET_MIN_VOLTAGE) {
+		of_property_read_u32(of_node, "qti,cpr-cond-min-voltage",
+					&min_uv);
+		for (i = APC_PVS_SLOW; i < NUM_APC_PVS; i++)
+			for (j = CPR_CORNER_SVS; j < CPR_CORNER_MAX; j++)
+				if (cpr_vreg->pvs_corner_v[i][j] < min_uv)
+					cpr_vreg->pvs_corner_v[i][j] = min_uv;
+	}
+
 	/* 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];
@@ -1512,6 +1794,51 @@
 	return 0;
 }
 
+static int cpr_freq_transition(struct notifier_block *nb, unsigned long val,
+					void *data)
+{
+	int old_corner, new_corner;
+	struct cpr_regulator *cpr_vreg = container_of(nb, struct cpr_regulator,
+				freq_transition);
+	struct cpufreq_freqs *freqs = data;
+
+	mutex_lock(&cpr_vreg->cpr_mutex);
+	switch (val) {
+	case CPUFREQ_PRECHANGE:
+		cpr_vreg->freq = freqs->new;
+		if (freqs->new > freqs->old) {
+			old_corner = cpr_get_freq_corner(cpr_vreg, freqs->old);
+			new_corner = cpr_get_freq_corner(cpr_vreg, freqs->new);
+			if (new_corner > 0 && old_corner == new_corner &&
+				cpr_ctl_is_enabled(cpr_vreg)) {
+				cpr_ctl_disable(cpr_vreg);
+				cpr_irq_clr(cpr_vreg);
+				cpr_corner_restore(cpr_vreg, new_corner);
+				cpr_ctl_enable(cpr_vreg, new_corner);
+			}
+		}
+		break;
+	case CPUFREQ_POSTCHANGE:
+		if (freqs->new < freqs->old) {
+			old_corner = cpr_get_freq_corner(cpr_vreg, freqs->old);
+			new_corner = cpr_get_freq_corner(cpr_vreg, freqs->new);
+			if (new_corner > 0 && old_corner == new_corner &&
+				cpr_ctl_is_enabled(cpr_vreg)) {
+				cpr_ctl_disable(cpr_vreg);
+				cpr_irq_clr(cpr_vreg);
+				cpr_corner_restore(cpr_vreg, new_corner);
+				cpr_ctl_enable(cpr_vreg, new_corner);
+			}
+		}
+		break;
+	default:
+		break;
+	}
+	mutex_unlock(&cpr_vreg->cpr_mutex);
+
+	return NOTIFY_OK;
+}
+
 static int __devinit cpr_regulator_probe(struct platform_device *pdev)
 {
 	struct cpr_regulator *cpr_vreg;
@@ -1595,6 +1922,10 @@
 
 	platform_set_drvdata(pdev, cpr_vreg);
 	the_cpr = cpr_vreg;
+	cpr_vreg->freq_transition.notifier_call = cpr_freq_transition;
+	if (cpr_vreg->flags & FLAGS_QUOT_ADJUST_WITH_FREQ)
+		cpufreq_register_notifier(&cpr_vreg->freq_transition,
+						CPUFREQ_TRANSITION_NOTIFIER);
 
 	return 0;
 
@@ -1615,6 +1946,9 @@
 			cpr_irq_set(cpr_vreg, 0);
 		}
 
+		if (cpr_vreg->flags & FLAGS_QUOT_ADJUST_WITH_FREQ)
+			cpufreq_unregister_notifier(&cpr_vreg->freq_transition,
+						CPUFREQ_TRANSITION_NOTIFIER);
 		cpr_apc_exit(cpr_vreg);
 		regulator_unregister(cpr_vreg->rdev);
 	}
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index c4fe0df..94040b6 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -31,7 +31,6 @@
 #include "rpm_stats.h"
 #include "rpm_rbcpr_stats.h"
 #include "footswitch.h"
-#include "acpuclock-krait.h"
 #include "pm.h"
 
 #ifdef CONFIG_MSM_MPM
@@ -675,16 +674,9 @@
 	.id		= -1,
 };
 
-static struct acpuclk_platform_data acpuclk_8930_pdata = {
-	.uses_pm8917 = false,
-};
-
 struct platform_device msm8930_device_acpuclk = {
 	.name		= "acpuclk-8930",
 	.id		= -1,
-	.dev = {
-		.platform_data = &acpuclk_8930_pdata,
-	},
 };
 
 struct platform_device msm8930aa_device_acpuclk = {
@@ -692,16 +684,9 @@
 	.id		= -1,
 };
 
-static struct acpuclk_platform_data acpuclk_8930ab_pdata = {
-	.uses_pm8917 = false,
-};
-
 struct platform_device msm8930ab_device_acpuclk = {
 	.name		= "acpuclk-8930ab",
 	.id		= -1,
-	.dev = {
-		.platform_data = &acpuclk_8930ab_pdata,
-	},
 };
 
 static struct fs_driver_data gfx3d_fs_data = {
diff --git a/arch/arm/mach-msm/hsic_sysmon_test.c b/arch/arm/mach-msm/hsic_sysmon_test.c
index fac6575..a910cd26 100644
--- a/arch/arm/mach-msm/hsic_sysmon_test.c
+++ b/arch/arm/mach-msm/hsic_sysmon_test.c
@@ -63,9 +63,13 @@
 	if (!dev)
 		return -ENODEV;
 
+	/* Add check for user buf count greater than RD_BUF_SIZE */
+	if (count > RD_BUF_SIZE)
+		count = RD_BUF_SIZE;
+
 	if (copy_from_user(dev->buf, ubuf, count)) {
 		pr_err("error copying for writing");
-		return 0;
+		return -EFAULT;
 	}
 
 	ret = hsic_sysmon_write(id, dev->buf, count, 1000);
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h b/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h
index 2e15cae..9a27fd2 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h
@@ -73,7 +73,8 @@
 #define USF_TSC_PTR_EVENT_IND  1
 #define USF_MOUSE_EVENT_IND    2
 #define USF_KEYBOARD_EVENT_IND 3
-#define USF_MAX_EVENT_IND      4
+#define USF_TSC_EXT_EVENT_IND  4
+#define USF_MAX_EVENT_IND      5
 
 /* Types of events, produced by the calculators */
 #define USF_NO_EVENT 0
@@ -81,10 +82,12 @@
 #define USF_TSC_PTR_EVENT  (1 << USF_TSC_PTR_EVENT_IND)
 #define USF_MOUSE_EVENT    (1 << USF_MOUSE_EVENT_IND)
 #define USF_KEYBOARD_EVENT (1 << USF_KEYBOARD_EVENT_IND)
+#define USF_TSC_EXT_EVENT  (1 << USF_TSC_EXT_EVENT_IND)
 #define USF_ALL_EVENTS         (USF_TSC_EVENT |\
 				USF_TSC_PTR_EVENT |\
 				USF_MOUSE_EVENT |\
-				USF_KEYBOARD_EVENT)
+				USF_KEYBOARD_EVENT |\
+				USF_TSC_EXT_EVENT)
 
 /* min, max array dimension */
 #define MIN_MAX_DIM 2
@@ -146,6 +149,8 @@
 	int tsc_y_tilt[MIN_MAX_DIM];
 	/* Touch screen pressure limits: min & max; for input module */
 	int tsc_pressure[MIN_MAX_DIM];
+	/* The requested side buttons bitmap */
+	uint16_t req_side_buttons_bitmap;
 	/* Bitmap of types of events (USF_X_EVENT), produced by calculator */
 	uint16_t event_types;
 	/* Input event source */
@@ -174,6 +179,8 @@
 	int inclinations[TILTS_DIM];
 /* [0-1023] (10bits); 0 - pen up */
 	uint32_t pressure;
+/* Bitmap for side button state. 1 - down, 0 - up */
+	uint16_t side_buttons_state_bitmap;
 };
 
 /* Mouse buttons, supported by USF */
diff --git a/arch/arm/mach-msm/lpm_levels.c b/arch/arm/mach-msm/lpm_levels.c
index b707df1..b9dcf88 100644
--- a/arch/arm/mach-msm/lpm_levels.c
+++ b/arch/arm/mach-msm/lpm_levels.c
@@ -291,7 +291,7 @@
 			system_level->num_cpu_votes != num_powered_cores)
 			continue;
 
-		if (latency_us < pwr_param->latency_us)
+		if (latency_us < pwr_param->latency_us && from_idle)
 			continue;
 
 		if (sleep_us < pwr_param->time_overhead_us)
diff --git a/arch/arm/mach-msm/pil-msa.c b/arch/arm/mach-msm/pil-msa.c
index 3a26af9..76afe6c 100644
--- a/arch/arm/mach-msm/pil-msa.c
+++ b/arch/arm/mach-msm/pil-msa.c
@@ -233,18 +233,17 @@
 	if (drv->self_auth) {
 		ret = pil_msa_wait_for_mba_ready(drv);
 		if (ret)
-			goto err_auth;
+			goto err_q6v5_reset;
 	}
 
 	drv->is_booted = true;
 
 	return 0;
 
-err_auth:
-	pil_q6v5_shutdown(pil);
 err_q6v5_reset:
 	pil_msa_pbl_disable_clks(drv);
 err_clks:
+	writel_relaxed(1, drv->restart_reg);
 	pil_msa_pbl_power_down(drv);
 err_power:
 	return ret;
diff --git a/arch/arm/mach-msm/pm-stats.c b/arch/arm/mach-msm/pm-stats.c
index ac4ed25..c4e52be 100644
--- a/arch/arm/mach-msm/pm-stats.c
+++ b/arch/arm/mach-msm/pm-stats.c
@@ -36,72 +36,132 @@
 	struct msm_pm_time_stats stats[MSM_PM_STAT_COUNT];
 };
 
+static struct msm_pm_time_stats suspend_stats;
+
 static DEFINE_SPINLOCK(msm_pm_stats_lock);
 static DEFINE_PER_CPU_SHARED_ALIGNED(
 	struct msm_pm_cpu_time_stats, msm_pm_stats);
-
 /*
- * Add the given time data to the statistics collection.
+ *  Function to update stats
  */
-void msm_pm_add_stat(enum msm_pm_time_stats_id id, int64_t t)
+static void update_stats(struct msm_pm_time_stats *stats, int64_t t)
 {
-	unsigned long flags;
-	struct msm_pm_time_stats *stats;
 	int64_t bt;
 	int i;
 
-	spin_lock_irqsave(&msm_pm_stats_lock, flags);
-	stats = __get_cpu_var(msm_pm_stats).stats;
+	if (!stats)
+		return;
 
-	if (!stats[id].enabled)
-		goto add_bail;
-
-	stats[id].total_time += t;
-	stats[id].count++;
+	stats->total_time += t;
+	stats->count++;
 
 	bt = t;
-	do_div(bt, stats[id].first_bucket_time);
+	do_div(bt, stats->first_bucket_time);
 
 	if (bt < 1ULL << (CONFIG_MSM_IDLE_STATS_BUCKET_SHIFT *
-				(CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1)))
+			(CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1)))
 		i = DIV_ROUND_UP(fls((uint32_t)bt),
-					CONFIG_MSM_IDLE_STATS_BUCKET_SHIFT);
+			CONFIG_MSM_IDLE_STATS_BUCKET_SHIFT);
 	else
 		i = CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1;
 
 	if (i >= CONFIG_MSM_IDLE_STATS_BUCKET_COUNT)
 		i = CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1;
 
-	stats[id].bucket[i]++;
+	stats->bucket[i]++;
 
-	if (t < stats[id].min_time[i] || !stats[id].max_time[i])
-		stats[id].min_time[i] = t;
-	if (t > stats[id].max_time[i])
-		stats[id].max_time[i] = t;
+	if (t < stats->min_time[i] || !stats->max_time[i])
+		stats->min_time[i] = t;
+	if (t > stats->max_time[i])
+		stats->max_time[i] = t;
+}
 
+/*
+ * Add the given time data to the statistics collection.
+ */
+void msm_pm_add_stat(enum msm_pm_time_stats_id id, int64_t t)
+{
+	struct msm_pm_time_stats *stats;
+	unsigned long flags;
+
+	spin_lock_irqsave(&msm_pm_stats_lock, flags);
+	if (id == MSM_PM_STAT_SUSPEND) {
+		stats = &suspend_stats;
+	} else {
+		stats = __get_cpu_var(msm_pm_stats).stats;
+		if (!stats[id].enabled)
+			goto add_bail;
+		stats = &stats[id];
+	}
+	update_stats(stats, t);
 add_bail:
 	spin_unlock_irqrestore(&msm_pm_stats_lock, flags);
 }
 
-/*
- * Write out the power management statistics.
- */
-
-static int msm_pm_stats_show(struct seq_file *m, void *v)
+static void stats_show(struct seq_file *m,
+		struct msm_pm_time_stats *stats,
+		int cpu, int suspend)
 {
-	int cpu;
+	int64_t bucket_time;
+	int64_t s;
+	uint32_t ns;
+	int i;
 	int bucket_count = CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1;
 	int bucket_shift = CONFIG_MSM_IDLE_STATS_BUCKET_SHIFT;
 
-	for_each_possible_cpu(cpu) {
-		unsigned long flags;
-		struct msm_pm_time_stats *stats;
-		int i, id;
-		int64_t bucket_time;
-		int64_t s;
-		uint32_t ns;
+	if (!stats || !m)
+		return;
 
-		spin_lock_irqsave(&msm_pm_stats_lock, flags);
+	s = stats->total_time;
+	ns = do_div(s, NSEC_PER_SEC);
+	if (suspend)
+		seq_printf(m,
+			"%s:\n"
+			"  count: %7d\n"
+			"  total_time: %lld.%09u\n",
+			stats->name,
+			stats->count,
+			s, ns);
+	else
+		seq_printf(m,
+			"[cpu %u] %s:\n"
+			"  count: %7d\n"
+			"  total_time: %lld.%09u\n",
+			cpu, stats->name,
+			stats->count,
+			s, ns);
+
+	bucket_time = stats->first_bucket_time;
+	for (i = 0; i < bucket_count; i++) {
+		s = bucket_time;
+		ns = do_div(s, NSEC_PER_SEC);
+		seq_printf(m,
+			"   <%6lld.%09u: %7d (%lld-%lld)\n",
+			s, ns, stats->bucket[i],
+			stats->min_time[i],
+			stats->max_time[i]);
+			bucket_time <<= bucket_shift;
+	}
+
+	seq_printf(m, "  >=%6lld.%09u: %7d (%lld-%lld)\n",
+		s, ns, stats->bucket[i],
+		stats->min_time[i],
+		stats->max_time[i]);
+}
+/*
+ * Write out the power management statistics.
+ */
+static int msm_pm_stats_show(struct seq_file *m, void *v)
+{
+	int cpu;
+	int id;
+	unsigned long flags;
+
+	spin_lock_irqsave(&msm_pm_stats_lock, flags);
+
+	for_each_possible_cpu(cpu) {
+		struct msm_pm_time_stats *stats;
+
 		stats = per_cpu(msm_pm_stats, cpu).stats;
 
 		for (id = 0; id < MSM_PM_STAT_COUNT; id++) {
@@ -109,38 +169,14 @@
 			if (!stats[id].enabled)
 				continue;
 
-			s = stats[id].total_time;
-			ns = do_div(s, NSEC_PER_SEC);
-			seq_printf(m,
-				"[cpu %u] %s:\n"
-				"  count: %7d\n"
-				"  total_time: %lld.%09u\n",
-				cpu, stats[id].name,
-				stats[id].count,
-				s, ns);
+			if (id == MSM_PM_STAT_SUSPEND)
+				continue;
 
-			bucket_time = stats[id].first_bucket_time;
-			for (i = 0; i < bucket_count; i++) {
-				s = bucket_time;
-				ns = do_div(s, NSEC_PER_SEC);
-				seq_printf(m,
-					"   <%6lld.%09u: %7d (%lld-%lld)\n",
-					s, ns, stats[id].bucket[i],
-					stats[id].min_time[i],
-					stats[id].max_time[i]);
-
-				bucket_time <<= bucket_shift;
-			}
-
-			seq_printf(m, "  >=%6lld.%09u: %7d (%lld-%lld)\n",
-				s, ns, stats[id].bucket[i],
-				stats[id].min_time[i],
-				stats[id].max_time[i]);
+			stats_show(m, &stats[id], cpu, false);
 		}
-
-		spin_unlock_irqrestore(&msm_pm_stats_lock, flags);
 	}
-
+	stats_show(m, &suspend_stats, cpu, true);
+	spin_unlock_irqrestore(&msm_pm_stats_lock, flags);
 	return 0;
 }
 
@@ -259,14 +295,6 @@
 			first_bucket_time =
 			CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
 
-		stats[MSM_PM_STAT_SUSPEND].name = "suspend";
-		stats[MSM_PM_STAT_SUSPEND].first_bucket_time =
-			CONFIG_MSM_SUSPEND_STATS_FIRST_BUCKET;
-
-		stats[MSM_PM_STAT_FAILED_SUSPEND].name = "failed-suspend";
-		stats[MSM_PM_STAT_FAILED_SUSPEND].first_bucket_time =
-			CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
-
 		stats[MSM_PM_STAT_NOT_IDLE].name = "not-idle";
 		stats[MSM_PM_STAT_NOT_IDLE].first_bucket_time =
 			CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
@@ -275,6 +303,9 @@
 			stats[enable_stats[i]].enabled = true;
 
 	}
+	suspend_stats.name = "system_suspend";
+	suspend_stats.first_bucket_time =
+		CONFIG_MSM_SUSPEND_STATS_FIRST_BUCKET;
 
 	d_entry = proc_create_data("msm_pm_stats", S_IRUGO | S_IWUSR | S_IWGRP,
 			NULL, &msm_pm_stats_fops, NULL);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c b/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c
deleted file mode 100644
index 8aacb56..0000000
--- a/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c
+++ /dev/null
@@ -1,1731 +0,0 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/msm_audio.h>
-#include <linux/slab.h>
-#include <linux/wait.h>
-#include <linux/sched.h>
-#include <linux/workqueue.h>
-#include <asm/uaccess.h>
-#include <asm/atomic.h>
-#include <mach/qdsp6v2/audio_dev_ctl.h>
-#include <mach/debug_mm.h>
-#include <mach/qdsp6v2/q6voice.h>
-#include <sound/apr_audio.h>
-#include <sound/q6adm.h>
-
-#ifndef MAX
-#define  MAX(x, y) (((x) > (y)) ? (x) : (y))
-#endif
-
-
-static DEFINE_MUTEX(session_lock);
-static struct workqueue_struct *msm_reset_device_work_queue;
-static void reset_device_work(struct work_struct *work);
-static DECLARE_WORK(msm_reset_device_work, reset_device_work);
-
-struct audio_dev_ctrl_state {
-	struct msm_snddev_info *devs[AUDIO_DEV_CTL_MAX_DEV];
-	u32 num_dev;
-	atomic_t opened;
-	struct msm_snddev_info *voice_rx_dev;
-	struct msm_snddev_info *voice_tx_dev;
-	wait_queue_head_t      wait;
-};
-
-static struct audio_dev_ctrl_state audio_dev_ctrl;
-struct event_listner event;
-
-struct session_freq {
-	int freq;
-	int evt;
-};
-
-struct audio_routing_info {
-	unsigned short mixer_mask[MAX_SESSIONS];
-	unsigned short audrec_mixer_mask[MAX_SESSIONS];
-	struct session_freq dec_freq[MAX_SESSIONS];
-	struct session_freq enc_freq[MAX_SESSIONS];
-	unsigned int copp_list[MAX_SESSIONS][AFE_MAX_PORTS];
-	int voice_tx_dev_id;
-	int voice_rx_dev_id;
-	int voice_tx_sample_rate;
-	int voice_rx_sample_rate;
-	signed int voice_tx_vol;
-	signed int voice_rx_vol;
-	int tx_mute;
-	int rx_mute;
-	int voice_state;
-	struct mutex copp_list_mutex;
-	struct mutex adm_mutex;
-};
-
-static struct audio_routing_info routing_info;
-
-struct audio_copp_topology {
-	struct mutex lock;
-	int session_cnt;
-	int session_id[MAX_SESSIONS];
-	int topolog_id[MAX_SESSIONS];
-};
-static struct audio_copp_topology adm_tx_topology_tbl;
-
-int msm_reset_all_device(void)
-{
-	int rc = 0;
-	int dev_id = 0;
-	struct msm_snddev_info *dev_info = NULL;
-
-	for (dev_id = 0; dev_id < audio_dev_ctrl.num_dev; dev_id++) {
-		dev_info = audio_dev_ctrl_find_dev(dev_id);
-		if (IS_ERR(dev_info)) {
-			pr_err("%s:pass invalid dev_id\n", __func__);
-			rc = PTR_ERR(dev_info);
-			return rc;
-		}
-		if (!dev_info->opened)
-			continue;
-		pr_debug("%s:Resetting device %d active on COPP %d"
-			"with  %lld as routing\n", __func__,
-				dev_id, dev_info->copp_id, dev_info->sessions);
-		broadcast_event(AUDDEV_EVT_REL_PENDING,
-					dev_id,
-					SESSION_IGNORE);
-		rc = dev_info->dev_ops.close(dev_info);
-		if (rc < 0) {
-			pr_err("%s:Snd device failed close!\n", __func__);
-			return rc;
-		} else {
-			dev_info->opened = 0;
-			broadcast_event(AUDDEV_EVT_DEV_RLS,
-				dev_id,
-				SESSION_IGNORE);
-
-			if (dev_info->copp_id == VOICE_PLAYBACK_TX)
-				voice_start_playback(0);
-		}
-		dev_info->sessions = 0;
-	}
-	msm_clear_all_session();
-	return 0;
-}
-EXPORT_SYMBOL(msm_reset_all_device);
-
-static void reset_device_work(struct work_struct *work)
-{
-	msm_reset_all_device();
-}
-
-int reset_device(void)
-{
-	queue_work(msm_reset_device_work_queue, &msm_reset_device_work);
-	return 0;
-}
-EXPORT_SYMBOL(reset_device);
-
-int msm_set_copp_id(int session_id, int copp_id)
-{
-	int rc = 0;
-	int index;
-
-	if (session_id < 1 || session_id > 8)
-		return -EINVAL;
-	if (afe_validate_port(copp_id) < 0)
-		return -EINVAL;
-
-	index = afe_get_port_index(copp_id);
-	if (index < 0 || index > AFE_MAX_PORTS)
-		return -EINVAL;
-	pr_debug("%s: session[%d] copp_id[%d] index[%d]\n", __func__,
-			session_id, copp_id, index);
-	mutex_lock(&routing_info.copp_list_mutex);
-	if (routing_info.copp_list[session_id][index] == COPP_IGNORE)
-		routing_info.copp_list[session_id][index] = copp_id;
-	mutex_unlock(&routing_info.copp_list_mutex);
-
-	return rc;
-}
-EXPORT_SYMBOL(msm_set_copp_id);
-
-int msm_clear_copp_id(int session_id, int copp_id)
-{
-	int rc = 0;
-	int index = afe_get_port_index(copp_id);
-
-	if (session_id < 1 || session_id > 8)
-		return -EINVAL;
-	pr_debug("%s: session[%d] copp_id[%d] index[%d]\n", __func__,
-			session_id, copp_id, index);
-	mutex_lock(&routing_info.copp_list_mutex);
-	if (routing_info.copp_list[session_id][index] == copp_id)
-		routing_info.copp_list[session_id][index] = COPP_IGNORE;
-#ifdef CONFIG_MSM8X60_RTAC
-	rtac_remove_adm_device(copp_id, session_id);
-#endif
-	mutex_unlock(&routing_info.copp_list_mutex);
-
-	return rc;
-}
-EXPORT_SYMBOL(msm_clear_copp_id);
-
-int msm_clear_session_id(int session_id)
-{
-	int rc = 0;
-	int i = 0;
-	if (session_id < 1 || session_id > 8)
-		return -EINVAL;
-	pr_debug("%s: session[%d]\n", __func__, session_id);
-	mutex_lock(&routing_info.adm_mutex);
-	mutex_lock(&routing_info.copp_list_mutex);
-	for (i = 0; i < AFE_MAX_PORTS; i++) {
-		if (routing_info.copp_list[session_id][i] != COPP_IGNORE) {
-			rc = adm_close(routing_info.copp_list[session_id][i]);
-			if (rc < 0) {
-				pr_err("%s: adm close fail port[%d] rc[%d]\n",
-					__func__,
-					routing_info.copp_list[session_id][i],
-					rc);
-				continue;
-			}
-#ifdef CONFIG_MSM8X60_RTAC
-			rtac_remove_adm_device(
-			routing_info.copp_list[session_id][i], session_id);
-#endif
-			routing_info.copp_list[session_id][i] = COPP_IGNORE;
-			rc = 0;
-		}
-	}
-	mutex_unlock(&routing_info.copp_list_mutex);
-	mutex_unlock(&routing_info.adm_mutex);
-
-	return rc;
-}
-EXPORT_SYMBOL(msm_clear_session_id);
-
-int msm_clear_all_session()
-{
-	int rc = 0;
-	int i = 0, j = 0;
-	pr_info("%s:\n", __func__);
-	mutex_lock(&routing_info.adm_mutex);
-	mutex_lock(&routing_info.copp_list_mutex);
-	for (j = 1; j < MAX_SESSIONS; j++) {
-		for (i = 0; i < AFE_MAX_PORTS; i++) {
-			if (routing_info.copp_list[j][i] != COPP_IGNORE) {
-				rc = adm_close(
-					routing_info.copp_list[j][i]);
-				if (rc < 0) {
-					pr_err("%s: adm close fail copp[%d]"
-					"session[%d] rc[%d]\n",
-					__func__,
-					routing_info.copp_list[j][i],
-					j, rc);
-					continue;
-				}
-				routing_info.copp_list[j][i] = COPP_IGNORE;
-				rc = 0;
-			}
-		}
-	}
-	mutex_unlock(&routing_info.copp_list_mutex);
-	mutex_unlock(&routing_info.adm_mutex);
-	return rc;
-}
-EXPORT_SYMBOL(msm_clear_all_session);
-
-int msm_get_voice_state(void)
-{
-	pr_debug("voice state %d\n", routing_info.voice_state);
-	return routing_info.voice_state;
-}
-EXPORT_SYMBOL(msm_get_voice_state);
-
-int msm_set_voice_mute(int dir, int mute, u32 session_id)
-{
-	pr_debug("dir %x mute %x\n", dir, mute);
-	if (dir == DIR_TX) {
-		routing_info.tx_mute = mute;
-		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
-			routing_info.voice_tx_dev_id, session_id);
-	} else
-		return -EPERM;
-	return 0;
-}
-EXPORT_SYMBOL(msm_set_voice_mute);
-
-int msm_set_voice_vol(int dir, s32 volume, u32 session_id)
-{
-	if (dir == DIR_TX) {
-		routing_info.voice_tx_vol = volume;
-		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
-					routing_info.voice_tx_dev_id,
-					session_id);
-	} else if (dir == DIR_RX) {
-		routing_info.voice_rx_vol = volume;
-		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
-					routing_info.voice_rx_dev_id,
-					session_id);
-	} else
-		return -EINVAL;
-	return 0;
-}
-EXPORT_SYMBOL(msm_set_voice_vol);
-
-void msm_snddev_register(struct msm_snddev_info *dev_info)
-{
-	mutex_lock(&session_lock);
-	if (audio_dev_ctrl.num_dev < AUDIO_DEV_CTL_MAX_DEV) {
-		audio_dev_ctrl.devs[audio_dev_ctrl.num_dev] = dev_info;
-		/* roughly 0 DB for digital gain
-		 * If default gain is not desirable, it is expected that
-		 * application sets desired gain before activating sound
-		 * device
-		 */
-		dev_info->dev_volume = 75;
-		dev_info->sessions = 0x0;
-		dev_info->usage_count = 0;
-		audio_dev_ctrl.num_dev++;
-	} else
-		pr_err("%s: device registry max out\n", __func__);
-	mutex_unlock(&session_lock);
-}
-EXPORT_SYMBOL(msm_snddev_register);
-
-int msm_snddev_devcount(void)
-{
-	return audio_dev_ctrl.num_dev;
-}
-EXPORT_SYMBOL(msm_snddev_devcount);
-
-int msm_snddev_query(int dev_id)
-{
-	if (dev_id <= audio_dev_ctrl.num_dev)
-			return 0;
-	return -ENODEV;
-}
-EXPORT_SYMBOL(msm_snddev_query);
-
-int msm_snddev_is_set(int popp_id, int copp_id)
-{
-	return routing_info.mixer_mask[popp_id] & (0x1 << copp_id);
-}
-EXPORT_SYMBOL(msm_snddev_is_set);
-
-unsigned short msm_snddev_route_enc(int enc_id)
-{
-	if (enc_id >= MAX_SESSIONS)
-		return -EINVAL;
-	return routing_info.audrec_mixer_mask[enc_id];
-}
-EXPORT_SYMBOL(msm_snddev_route_enc);
-
-unsigned short msm_snddev_route_dec(int popp_id)
-{
-	if (popp_id >= MAX_SESSIONS)
-		return -EINVAL;
-	return routing_info.mixer_mask[popp_id];
-}
-EXPORT_SYMBOL(msm_snddev_route_dec);
-
-/*To check one->many case*/
-int msm_check_multicopp_per_stream(int session_id,
-				struct route_payload *payload)
-{
-	int i = 0;
-	int flag = 0;
-	pr_debug("%s: session_id=%d\n", __func__, session_id);
-	mutex_lock(&routing_info.copp_list_mutex);
-	for (i = 0; i < AFE_MAX_PORTS; i++) {
-		if (routing_info.copp_list[session_id][i] == COPP_IGNORE)
-			continue;
-		else {
-			pr_debug("Device enabled\n");
-			payload->copp_ids[flag++] =
-				routing_info.copp_list[session_id][i];
-		}
-	}
-	mutex_unlock(&routing_info.copp_list_mutex);
-	if (flag > 1) {
-		pr_debug("Multiple copp per stream case num_copps=%d\n", flag);
-	} else {
-		pr_debug("Stream routed to single copp\n");
-	}
-	payload->num_copps = flag;
-	return flag;
-}
-
-int msm_snddev_set_dec(int popp_id, int copp_id, int set,
-					int rate, int mode)
-{
-	int rc = 0, i = 0, num_copps;
-	struct route_payload payload;
-
-	if ((popp_id >= MAX_SESSIONS) || (popp_id <= 0)) {
-		pr_err("%s: Invalid session id %d\n", __func__, popp_id);
-		return 0;
-	}
-
-	mutex_lock(&routing_info.adm_mutex);
-	if (set) {
-		rc = adm_open(copp_id, ADM_PATH_PLAYBACK, rate, mode,
-			DEFAULT_COPP_TOPOLOGY);
-		if (rc < 0) {
-			pr_err("%s: adm open fail rc[%d]\n", __func__, rc);
-			rc = -EINVAL;
-			mutex_unlock(&routing_info.adm_mutex);
-			return rc;
-		}
-		msm_set_copp_id(popp_id, copp_id);
-		pr_debug("%s:Session id=%d copp_id=%d\n",
-			__func__, popp_id, copp_id);
-		memset(payload.copp_ids, COPP_IGNORE,
-				(sizeof(unsigned int) * AFE_MAX_PORTS));
-		num_copps = msm_check_multicopp_per_stream(popp_id, &payload);
-		/* Multiple streams per copp is handled, one stream at a time */
-		rc = adm_matrix_map(popp_id, ADM_PATH_PLAYBACK, num_copps,
-					payload.copp_ids, copp_id);
-		if (rc < 0) {
-			pr_err("%s: matrix map failed rc[%d]\n",
-				__func__, rc);
-			adm_close(copp_id);
-			rc = -EINVAL;
-			mutex_unlock(&routing_info.adm_mutex);
-			return rc;
-		}
-#ifdef CONFIG_MSM8X60_RTAC
-		for (i = 0; i < num_copps; i++)
-			rtac_add_adm_device(payload.copp_ids[i], popp_id);
-#endif
-	} else {
-		for (i = 0; i < AFE_MAX_PORTS; i++) {
-			if (routing_info.copp_list[popp_id][i] == copp_id) {
-				rc = adm_close(copp_id);
-				if (rc < 0) {
-					pr_err("%s: adm close fail copp[%d]"
-						"rc[%d]\n",
-						__func__, copp_id, rc);
-					rc = -EINVAL;
-					mutex_unlock(&routing_info.adm_mutex);
-					return rc;
-				}
-				msm_clear_copp_id(popp_id, copp_id);
-				break;
-			}
-		}
-	}
-
-	if (copp_id == VOICE_PLAYBACK_TX) {
-		/* Signal uplink playback. */
-		rc = voice_start_playback(set);
-	}
-	mutex_unlock(&routing_info.adm_mutex);
-	return rc;
-}
-EXPORT_SYMBOL(msm_snddev_set_dec);
-
-
-static int check_tx_copp_topology(int session_id)
-{
-	int cnt;
-	int ret_val = -ENOENT;
-
-	cnt = adm_tx_topology_tbl.session_cnt;
-	if (cnt) {
-		do {
-			if (adm_tx_topology_tbl.session_id[cnt-1]
-				== session_id)
-				ret_val = cnt-1;
-		} while (--cnt);
-	}
-
-	return ret_val;
-}
-
-static int add_to_tx_topology_lists(int session_id, int topology)
-{
-	int idx = 0, tbl_idx;
-	int ret_val = -ENOSPC;
-
-	mutex_lock(&adm_tx_topology_tbl.lock);
-
-	tbl_idx = check_tx_copp_topology(session_id);
-	if (tbl_idx == -ENOENT) {
-		while (adm_tx_topology_tbl.session_id[idx++])
-			;
-		tbl_idx = idx-1;
-	}
-
-	if (tbl_idx < MAX_SESSIONS) {
-		adm_tx_topology_tbl.session_id[tbl_idx] = session_id;
-		adm_tx_topology_tbl.topolog_id[tbl_idx] = topology;
-		adm_tx_topology_tbl.session_cnt++;
-
-		ret_val = 0;
-	}
-	mutex_unlock(&adm_tx_topology_tbl.lock);
-	return ret_val;
-}
-
-static void remove_from_tx_topology_lists(int session_id)
-{
-	int tbl_idx;
-
-	mutex_lock(&adm_tx_topology_tbl.lock);
-	tbl_idx = check_tx_copp_topology(session_id);
-	if (tbl_idx != -ENOENT) {
-
-		adm_tx_topology_tbl.session_cnt--;
-		adm_tx_topology_tbl.session_id[tbl_idx] = 0;
-		adm_tx_topology_tbl.topolog_id[tbl_idx] = 0;
-	}
-	mutex_unlock(&adm_tx_topology_tbl.lock);
-}
-
-int auddev_cfg_tx_copp_topology(int session_id, int cfg)
-{
-	int ret = 0;
-
-	if (cfg == DEFAULT_COPP_TOPOLOGY)
-		remove_from_tx_topology_lists(session_id);
-	else {
-		switch (cfg) {
-		case VPM_TX_SM_ECNS_COPP_TOPOLOGY:
-		case VPM_TX_DM_FLUENCE_COPP_TOPOLOGY:
-			ret = add_to_tx_topology_lists(session_id, cfg);
-			break;
-
-		default:
-			ret = -ENODEV;
-			break;
-		}
-	}
-	return ret;
-}
-
-int msm_snddev_set_enc(int popp_id, int copp_id, int set,
-					int rate, int mode)
-{
-	int topology;
-	int tbl_idx;
-	int rc = 0, i = 0;
-	mutex_lock(&routing_info.adm_mutex);
-	if (set) {
-		mutex_lock(&adm_tx_topology_tbl.lock);
-		tbl_idx = check_tx_copp_topology(popp_id);
-		if (tbl_idx == -ENOENT)
-			topology = DEFAULT_COPP_TOPOLOGY;
-		else {
-			topology = adm_tx_topology_tbl.topolog_id[tbl_idx];
-			rate = 16000;
-		}
-		mutex_unlock(&adm_tx_topology_tbl.lock);
-		rc = adm_open(copp_id, ADM_PATH_LIVE_REC, rate, mode, topology);
-		if (rc < 0) {
-			pr_err("%s: adm open fail rc[%d]\n", __func__, rc);
-			rc = -EINVAL;
-			goto fail_cmd;
-		}
-
-		rc = adm_matrix_map(popp_id, ADM_PATH_LIVE_REC, 1,
-					(unsigned int *)&copp_id, copp_id);
-		if (rc < 0) {
-			pr_err("%s: matrix map failed rc[%d]\n", __func__, rc);
-			adm_close(copp_id);
-			rc = -EINVAL;
-			goto fail_cmd;
-		}
-		msm_set_copp_id(popp_id, copp_id);
-#ifdef CONFIG_MSM8X60_RTAC
-	rtac_add_adm_device(copp_id, popp_id);
-#endif
-
-	} else {
-		for (i = 0; i < AFE_MAX_PORTS; i++) {
-			if (routing_info.copp_list[popp_id][i] == copp_id) {
-				rc = adm_close(copp_id);
-				if (rc < 0) {
-					pr_err("%s: adm close fail copp[%d]"
-					"rc[%d]\n",
-							__func__, copp_id, rc);
-					rc = -EINVAL;
-					goto fail_cmd;
-				}
-				msm_clear_copp_id(popp_id, copp_id);
-				break;
-			}
-		}
-	}
-fail_cmd:
-	mutex_unlock(&routing_info.adm_mutex);
-	return rc;
-}
-EXPORT_SYMBOL(msm_snddev_set_enc);
-
-int msm_device_is_voice(int dev_id)
-{
-	if ((dev_id == routing_info.voice_rx_dev_id)
-		|| (dev_id == routing_info.voice_tx_dev_id))
-		return 0;
-	else
-		return -EINVAL;
-}
-EXPORT_SYMBOL(msm_device_is_voice);
-
-int msm_set_voc_route(struct msm_snddev_info *dev_info,
-			int stream_type, int dev_id)
-{
-	int rc = 0;
-	u64 session_mask = 0;
-
-	mutex_lock(&session_lock);
-	switch (stream_type) {
-	case AUDIO_ROUTE_STREAM_VOICE_RX:
-		if (audio_dev_ctrl.voice_rx_dev)
-			audio_dev_ctrl.voice_rx_dev->sessions &= ~0xFFFF;
-
-		if (!(dev_info->capability & SNDDEV_CAP_RX) |
-		    !(dev_info->capability & SNDDEV_CAP_VOICE)) {
-			rc = -EINVAL;
-			break;
-		}
-		audio_dev_ctrl.voice_rx_dev = dev_info;
-		if (audio_dev_ctrl.voice_rx_dev) {
-			session_mask =
-				((u64)0x1) << (MAX_BIT_PER_CLIENT * \
-				((int)AUDDEV_CLNT_VOC-1));
-			audio_dev_ctrl.voice_rx_dev->sessions |=
-				session_mask;
-		}
-		routing_info.voice_rx_dev_id = dev_id;
-		break;
-	case AUDIO_ROUTE_STREAM_VOICE_TX:
-		if (audio_dev_ctrl.voice_tx_dev)
-			audio_dev_ctrl.voice_tx_dev->sessions &= ~0xFFFF;
-
-		if (!(dev_info->capability & SNDDEV_CAP_TX) |
-		    !(dev_info->capability & SNDDEV_CAP_VOICE)) {
-			rc = -EINVAL;
-			break;
-		}
-
-		audio_dev_ctrl.voice_tx_dev = dev_info;
-		if (audio_dev_ctrl.voice_rx_dev) {
-			session_mask =
-				((u64)0x1) << (MAX_BIT_PER_CLIENT * \
-					((int)AUDDEV_CLNT_VOC-1));
-			audio_dev_ctrl.voice_tx_dev->sessions |=
-				session_mask;
-		}
-		routing_info.voice_tx_dev_id = dev_id;
-		break;
-	default:
-		rc = -EINVAL;
-	}
-	mutex_unlock(&session_lock);
-	return rc;
-}
-EXPORT_SYMBOL(msm_set_voc_route);
-
-void msm_release_voc_thread(void)
-{
-	wake_up(&audio_dev_ctrl.wait);
-}
-EXPORT_SYMBOL(msm_release_voc_thread);
-
-int msm_snddev_get_enc_freq(session_id)
-{
-	return routing_info.enc_freq[session_id].freq;
-}
-EXPORT_SYMBOL(msm_snddev_get_enc_freq);
-
-int msm_get_voc_freq(int *tx_freq, int *rx_freq)
-{
-	*tx_freq = routing_info.voice_tx_sample_rate;
-	*rx_freq = routing_info.voice_rx_sample_rate;
-	return 0;
-}
-EXPORT_SYMBOL(msm_get_voc_freq);
-
-int msm_get_voc_route(u32 *rx_id, u32 *tx_id)
-{
-	int rc = 0;
-
-	if (!rx_id || !tx_id)
-		return -EINVAL;
-
-	mutex_lock(&session_lock);
-	if (!audio_dev_ctrl.voice_rx_dev || !audio_dev_ctrl.voice_tx_dev) {
-		rc = -ENODEV;
-		mutex_unlock(&session_lock);
-		return rc;
-	}
-
-	*rx_id = audio_dev_ctrl.voice_rx_dev->acdb_id;
-	*tx_id = audio_dev_ctrl.voice_tx_dev->acdb_id;
-
-	mutex_unlock(&session_lock);
-
-	return rc;
-}
-EXPORT_SYMBOL(msm_get_voc_route);
-
-struct msm_snddev_info *audio_dev_ctrl_find_dev(u32 dev_id)
-{
-	struct msm_snddev_info *info;
-
-	if ((audio_dev_ctrl.num_dev - 1) < dev_id) {
-		info = ERR_PTR(-ENODEV);
-		goto error;
-	}
-
-	info = audio_dev_ctrl.devs[dev_id];
-error:
-	return info;
-
-}
-EXPORT_SYMBOL(audio_dev_ctrl_find_dev);
-
-int snddev_voice_set_volume(int vol, int path)
-{
-	if (audio_dev_ctrl.voice_rx_dev
-		&& audio_dev_ctrl.voice_tx_dev) {
-		if (path)
-			audio_dev_ctrl.voice_tx_dev->dev_volume = vol;
-		else
-			audio_dev_ctrl.voice_rx_dev->dev_volume = vol;
-	} else
-		return -ENODEV;
-	return 0;
-}
-EXPORT_SYMBOL(snddev_voice_set_volume);
-
-static int audio_dev_ctrl_get_devices(struct audio_dev_ctrl_state *dev_ctrl,
-				      void __user *arg)
-{
-	int rc = 0;
-	u32 index;
-	struct msm_snd_device_list work_list;
-	struct msm_snd_device_info *work_tbl;
-
-	if (copy_from_user(&work_list, arg, sizeof(work_list))) {
-		rc = -EFAULT;
-		goto error;
-	}
-
-	if (work_list.num_dev > dev_ctrl->num_dev) {
-		rc = -EINVAL;
-		goto error;
-	}
-
-	work_tbl = kmalloc(work_list.num_dev *
-		sizeof(struct msm_snd_device_info), GFP_KERNEL);
-	if (!work_tbl) {
-		rc = -ENOMEM;
-		goto error;
-	}
-
-	for (index = 0; index < dev_ctrl->num_dev; index++) {
-		work_tbl[index].dev_id = index;
-		work_tbl[index].dev_cap = dev_ctrl->devs[index]->capability;
-		strlcpy(work_tbl[index].dev_name, dev_ctrl->devs[index]->name,
-		64);
-	}
-
-	if (copy_to_user((void *) (work_list.list), work_tbl,
-		 work_list.num_dev * sizeof(struct msm_snd_device_info)))
-		rc = -EFAULT;
-	kfree(work_tbl);
-error:
-	return rc;
-}
-
-
-int auddev_register_evt_listner(u32 evt_id, u32 clnt_type, u32 clnt_id,
-		void (*listner)(u32 evt_id,
-			union auddev_evt_data *evt_payload,
-			void *private_data),
-		void *private_data)
-{
-	int rc;
-	struct msm_snd_evt_listner *callback = NULL;
-	struct msm_snd_evt_listner *new_cb;
-
-	new_cb = kzalloc(sizeof(struct msm_snd_evt_listner), GFP_KERNEL);
-	if (!new_cb) {
-		pr_err("No memory to add new listener node\n");
-		return -ENOMEM;
-	}
-
-	mutex_lock(&session_lock);
-	new_cb->cb_next = NULL;
-	new_cb->auddev_evt_listener = listner;
-	new_cb->evt_id = evt_id;
-	new_cb->clnt_type = clnt_type;
-	new_cb->clnt_id = clnt_id;
-	new_cb->private_data = private_data;
-	if (event.cb == NULL) {
-		event.cb = new_cb;
-		new_cb->cb_prev = NULL;
-	} else {
-		callback = event.cb;
-		for (; ;) {
-			if (callback->cb_next == NULL)
-				break;
-			else {
-				callback = callback->cb_next;
-				continue;
-			}
-		}
-		callback->cb_next = new_cb;
-		new_cb->cb_prev = callback;
-	}
-	event.num_listner++;
-	mutex_unlock(&session_lock);
-	rc = 0;
-	return rc;
-}
-EXPORT_SYMBOL(auddev_register_evt_listner);
-
-int auddev_unregister_evt_listner(u32 clnt_type, u32 clnt_id)
-{
-	struct msm_snd_evt_listner *callback = event.cb;
-	struct msm_snddev_info *info;
-	u64 session_mask = 0;
-	int i = 0;
-
-	mutex_lock(&session_lock);
-	while (callback != NULL) {
-		if ((callback->clnt_type == clnt_type)
-			&& (callback->clnt_id == clnt_id))
-			break;
-		 callback = callback->cb_next;
-	}
-	if (callback == NULL) {
-		mutex_unlock(&session_lock);
-		return -EINVAL;
-	}
-
-	if ((callback->cb_next == NULL) && (callback->cb_prev == NULL))
-		event.cb = NULL;
-	else if (callback->cb_next == NULL)
-		callback->cb_prev->cb_next = NULL;
-	else if (callback->cb_prev == NULL) {
-		callback->cb_next->cb_prev = NULL;
-		event.cb = callback->cb_next;
-	} else {
-		callback->cb_prev->cb_next = callback->cb_next;
-		callback->cb_next->cb_prev = callback->cb_prev;
-	}
-	kfree(callback);
-
-	session_mask = (((u64)0x1) << clnt_id) << (MAX_BIT_PER_CLIENT * \
-				((int)clnt_type-1));
-	for (i = 0; i < audio_dev_ctrl.num_dev; i++) {
-		info = audio_dev_ctrl.devs[i];
-		info->sessions &= ~session_mask;
-	}
-	mutex_unlock(&session_lock);
-	return 0;
-}
-EXPORT_SYMBOL(auddev_unregister_evt_listner);
-
-int msm_snddev_withdraw_freq(u32 session_id, u32 capability, u32 clnt_type)
-{
-	int i = 0;
-	struct msm_snddev_info *info;
-	u64 session_mask = 0;
-
-	if ((clnt_type == AUDDEV_CLNT_VOC) && (session_id != 0))
-		return -EINVAL;
-	if ((clnt_type == AUDDEV_CLNT_DEC)
-			&& (session_id >= MAX_SESSIONS))
-		return -EINVAL;
-	if ((clnt_type == AUDDEV_CLNT_ENC)
-			&& (session_id >= MAX_SESSIONS))
-		return -EINVAL;
-
-	session_mask = (((u64)0x1) << session_id) << (MAX_BIT_PER_CLIENT * \
-				((int)clnt_type-1));
-
-	for (i = 0; i < audio_dev_ctrl.num_dev; i++) {
-		info = audio_dev_ctrl.devs[i];
-		if ((info->sessions & session_mask)
-			&& (info->capability & capability)) {
-			if (!(info->sessions & ~(session_mask)))
-				info->set_sample_rate = 0;
-		}
-	}
-	if (clnt_type == AUDDEV_CLNT_DEC)
-		routing_info.dec_freq[session_id].freq
-					= 0;
-	else if (clnt_type == AUDDEV_CLNT_ENC)
-		routing_info.enc_freq[session_id].freq
-					= 0;
-	else if (capability == SNDDEV_CAP_TX)
-		routing_info.voice_tx_sample_rate = 0;
-	else
-		routing_info.voice_rx_sample_rate = 48000;
-	return 0;
-}
-
-int msm_snddev_request_freq(int *freq, u32 session_id,
-			u32 capability, u32 clnt_type)
-{
-	int i = 0;
-	int rc = 0;
-	struct msm_snddev_info *info;
-	u32 set_freq;
-	u64 session_mask = 0;
-	u64 clnt_type_mask = 0;
-
-	pr_debug(": clnt_type 0x%08x\n", clnt_type);
-
-	if ((clnt_type == AUDDEV_CLNT_VOC) && (session_id != 0))
-		return -EINVAL;
-	if ((clnt_type == AUDDEV_CLNT_DEC)
-			&& (session_id >= MAX_SESSIONS))
-		return -EINVAL;
-	if ((clnt_type == AUDDEV_CLNT_ENC)
-			&& (session_id >= MAX_SESSIONS))
-		return -EINVAL;
-	session_mask = (((u64)0x1) << session_id) << (MAX_BIT_PER_CLIENT * \
-				((int)clnt_type-1));
-	clnt_type_mask = (0xFFFF << (MAX_BIT_PER_CLIENT * (clnt_type-1)));
-	if (!(*freq == 8000) && !(*freq == 11025) &&
-		!(*freq == 12000) && !(*freq == 16000) &&
-		!(*freq == 22050) && !(*freq == 24000) &&
-		!(*freq == 32000) && !(*freq == 44100) &&
-		!(*freq == 48000))
-		return -EINVAL;
-
-	for (i = 0; i < audio_dev_ctrl.num_dev; i++) {
-		info = audio_dev_ctrl.devs[i];
-		if ((info->sessions & session_mask)
-			&& (info->capability & capability)) {
-			rc = 0;
-			if ((info->sessions & ~clnt_type_mask)
-				&& ((*freq != 8000) && (*freq != 16000)
-					&& (*freq != 48000))) {
-				if (clnt_type == AUDDEV_CLNT_ENC) {
-					routing_info.enc_freq[session_id].freq
-							= 0;
-					return -EPERM;
-				} else if (clnt_type == AUDDEV_CLNT_DEC) {
-					routing_info.dec_freq[session_id].freq
-							= 0;
-					return -EPERM;
-				}
-			}
-			if (*freq == info->set_sample_rate) {
-				rc = info->set_sample_rate;
-				continue;
-			}
-			set_freq = MAX(*freq, info->set_sample_rate);
-
-
-			if (clnt_type == AUDDEV_CLNT_DEC) {
-				routing_info.dec_freq[session_id].evt = 1;
-				routing_info.dec_freq[session_id].freq
-						= set_freq;
-			} else if (clnt_type == AUDDEV_CLNT_ENC) {
-				routing_info.enc_freq[session_id].evt = 1;
-				routing_info.enc_freq[session_id].freq
-						= set_freq;
-			} else if (capability == SNDDEV_CAP_TX)
-				routing_info.voice_tx_sample_rate = set_freq;
-
-			rc = set_freq;
-			info->set_sample_rate = set_freq;
-			*freq = info->set_sample_rate;
-
-			if (info->opened) {
-				broadcast_event(AUDDEV_EVT_FREQ_CHG, i,
-							SESSION_IGNORE);
-				set_freq = info->dev_ops.set_freq(info,
-								set_freq);
-				broadcast_event(AUDDEV_EVT_DEV_RDY, i,
-							SESSION_IGNORE);
-			}
-		}
-		pr_debug("info->set_sample_rate = %d\n", info->set_sample_rate);
-		pr_debug("routing_info.enc_freq.freq = %d\n",
-					routing_info.enc_freq[session_id].freq);
-	}
-	return rc;
-}
-EXPORT_SYMBOL(msm_snddev_request_freq);
-
-int msm_snddev_enable_sidetone(u32 dev_id, u32 enable, uint16_t gain)
-{
-	int rc;
-	struct msm_snddev_info *dev_info;
-
-	pr_debug("dev_id %d enable %d\n", dev_id, enable);
-
-	dev_info = audio_dev_ctrl_find_dev(dev_id);
-
-	if (IS_ERR(dev_info)) {
-		pr_err("bad dev_id %d\n", dev_id);
-		rc = -EINVAL;
-	} else if (!dev_info->dev_ops.enable_sidetone) {
-		pr_debug("dev %d no sidetone support\n", dev_id);
-		rc = -EPERM;
-	} else
-		rc = dev_info->dev_ops.enable_sidetone(dev_info, enable, gain);
-
-	return rc;
-}
-EXPORT_SYMBOL(msm_snddev_enable_sidetone);
-
-int msm_enable_incall_recording(int popp_id, int rec_mode, int rate,
-				int channel_mode)
-{
-	int rc = 0;
-	unsigned int port_id[2];
-	port_id[0] = VOICE_RECORD_TX;
-	port_id[1] = VOICE_RECORD_RX;
-
-	pr_debug("%s: popp_id %d, rec_mode %d, rate %d, channel_mode %d\n",
-		 __func__, popp_id, rec_mode, rate, channel_mode);
-
-	mutex_lock(&routing_info.adm_mutex);
-
-	if (rec_mode == VOC_REC_UPLINK) {
-		rc = afe_start_pseudo_port(port_id[0]);
-		if (rc < 0) {
-			pr_err("%s: Error %d in Tx pseudo port start\n",
-			       __func__, rc);
-
-			goto fail_cmd;
-		}
-
-		rc = adm_open(port_id[0], ADM_PATH_LIVE_REC, rate, channel_mode,
-				DEFAULT_COPP_TOPOLOGY);
-		if (rc < 0) {
-			pr_err("%s: Error %d in ADM open %d\n",
-			       __func__, rc, port_id[0]);
-
-			goto fail_cmd;
-		}
-
-		rc = adm_matrix_map(popp_id, ADM_PATH_LIVE_REC, 1,
-				&port_id[0], port_id[0]);
-		if (rc < 0) {
-			pr_err("%s: Error %d in ADM matrix map %d\n",
-			       __func__, rc, port_id[0]);
-
-			goto fail_cmd;
-		}
-
-		msm_set_copp_id(popp_id, port_id[0]);
-
-	} else if (rec_mode == VOC_REC_DOWNLINK) {
-		rc = afe_start_pseudo_port(port_id[1]);
-		if (rc < 0) {
-			pr_err("%s: Error %d in Rx pseudo port start\n",
-			       __func__, rc);
-
-			goto fail_cmd;
-		}
-
-		rc = adm_open(port_id[1], ADM_PATH_LIVE_REC, rate, channel_mode,
-				DEFAULT_COPP_TOPOLOGY);
-		if (rc < 0) {
-			pr_err("%s: Error %d in ADM open %d\n",
-			       __func__, rc, port_id[1]);
-
-			goto fail_cmd;
-		}
-
-		rc = adm_matrix_map(popp_id, ADM_PATH_LIVE_REC, 1,
-				&port_id[1], port_id[1]);
-		if (rc < 0) {
-			pr_err("%s: Error %d in ADM matrix map %d\n",
-			       __func__, rc, port_id[1]);
-
-			goto fail_cmd;
-		}
-
-		msm_set_copp_id(popp_id, port_id[1]);
-
-	} else if (rec_mode == VOC_REC_BOTH) {
-		rc = afe_start_pseudo_port(port_id[0]);
-		if (rc < 0) {
-			pr_err("%s: Error %d in Tx pseudo port start\n",
-			       __func__, rc);
-
-			goto fail_cmd;
-		}
-
-		rc = adm_open(port_id[0], ADM_PATH_LIVE_REC, rate, channel_mode,
-				DEFAULT_COPP_TOPOLOGY);
-		if (rc < 0) {
-			pr_err("%s: Error %d in ADM open %d\n",
-			       __func__, rc, port_id[0]);
-
-			goto fail_cmd;
-		}
-
-		msm_set_copp_id(popp_id, port_id[0]);
-
-		rc = afe_start_pseudo_port(port_id[1]);
-		if (rc < 0) {
-			pr_err("%s: Error %d in Rx pseudo port start\n",
-			       __func__, rc);
-
-			goto fail_cmd;
-		}
-
-		rc = adm_open(port_id[1], ADM_PATH_LIVE_REC, rate, channel_mode,
-				DEFAULT_COPP_TOPOLOGY);
-		if (rc < 0) {
-			pr_err("%s: Error %d in ADM open %d\n",
-			       __func__, rc, port_id[0]);
-
-			goto fail_cmd;
-		}
-
-		rc = adm_matrix_map(popp_id, ADM_PATH_LIVE_REC, 2,
-				&port_id[0], port_id[1]);
-		if (rc < 0) {
-			pr_err("%s: Error %d in ADM matrix map\n",
-			       __func__, rc);
-
-			goto fail_cmd;
-		}
-
-		msm_set_copp_id(popp_id, port_id[1]);
-	} else {
-		pr_err("%s Unknown rec_mode %d\n", __func__, rec_mode);
-
-		goto fail_cmd;
-	}
-
-	rc = voice_start_record(rec_mode, 1);
-
-fail_cmd:
-	mutex_unlock(&routing_info.adm_mutex);
-	return rc;
-}
-
-int msm_disable_incall_recording(uint32_t popp_id, uint32_t rec_mode)
-{
-	int rc = 0;
-	uint32_t port_id[2];
-	port_id[0] = VOICE_RECORD_TX;
-	port_id[1] = VOICE_RECORD_RX;
-
-	pr_debug("%s: popp_id %d, rec_mode %d\n", __func__, popp_id, rec_mode);
-
-	mutex_lock(&routing_info.adm_mutex);
-
-	rc = voice_start_record(rec_mode, 0);
-	if (rc < 0) {
-		pr_err("%s: Error %d stopping record\n", __func__, rc);
-
-		goto fail_cmd;
-	}
-
-	if (rec_mode == VOC_REC_UPLINK) {
-		rc = adm_close(port_id[0]);
-		if (rc < 0) {
-			pr_err("%s: Error %d in ADM close %d\n",
-			       __func__, rc, port_id[0]);
-
-			goto fail_cmd;
-		}
-
-		msm_clear_copp_id(popp_id, port_id[0]);
-
-		rc = afe_stop_pseudo_port(port_id[0]);
-		if (rc < 0) {
-			pr_err("%s: Error %d in Tx pseudo port stop\n",
-			       __func__, rc);
-			goto fail_cmd;
-		}
-
-	} else if (rec_mode == VOC_REC_DOWNLINK) {
-		rc = adm_close(port_id[1]);
-		if (rc < 0) {
-			pr_err("%s: Error %d in ADM close %d\n",
-			       __func__, rc, port_id[1]);
-
-			goto fail_cmd;
-		}
-
-		msm_clear_copp_id(popp_id, port_id[1]);
-
-		rc = afe_stop_pseudo_port(port_id[1]);
-		if (rc < 0) {
-			pr_err("%s: Error %d in Rx pseudo port stop\n",
-			       __func__, rc);
-			goto fail_cmd;
-		}
-	} else if (rec_mode == VOC_REC_BOTH) {
-		rc = adm_close(port_id[0]);
-		if (rc < 0) {
-			pr_err("%s: Error %d in ADM close %d\n",
-			       __func__, rc, port_id[0]);
-
-			goto fail_cmd;
-		}
-
-		msm_clear_copp_id(popp_id, port_id[0]);
-
-		rc = afe_stop_pseudo_port(port_id[0]);
-		if (rc < 0) {
-			pr_err("%s: Error %d in Tx pseudo port stop\n",
-			       __func__, rc);
-			goto fail_cmd;
-		}
-
-		rc = adm_close(port_id[1]);
-		if (rc < 0) {
-			pr_err("%s: Error %d in ADM close %d\n",
-			       __func__, rc, port_id[1]);
-
-			goto fail_cmd;
-		}
-
-		msm_clear_copp_id(popp_id, port_id[1]);
-
-		rc = afe_stop_pseudo_port(port_id[1]);
-		if (rc < 0) {
-			pr_err("%s: Error %d in Rx pseudo port stop\n",
-			       __func__, rc);
-			goto fail_cmd;
-		}
-	} else {
-		pr_err("%s Unknown rec_mode %d\n", __func__, rec_mode);
-
-		goto fail_cmd;
-	}
-
-fail_cmd:
-	mutex_unlock(&routing_info.adm_mutex);
-	return rc;
-}
-
-static long audio_dev_ctrl_ioctl(struct file *file,
-	unsigned int cmd, unsigned long arg)
-{
-	int rc = 0;
-	struct audio_dev_ctrl_state *dev_ctrl = file->private_data;
-
-	mutex_lock(&session_lock);
-	switch (cmd) {
-	case AUDIO_GET_NUM_SND_DEVICE:
-		rc = put_user(dev_ctrl->num_dev, (uint32_t __user *) arg);
-		break;
-	case AUDIO_GET_SND_DEVICES:
-		rc = audio_dev_ctrl_get_devices(dev_ctrl, (void __user *) arg);
-		break;
-	case AUDIO_ENABLE_SND_DEVICE: {
-		struct msm_snddev_info *dev_info;
-		u32 dev_id;
-
-		if (get_user(dev_id, (u32 __user *) arg)) {
-			rc = -EFAULT;
-			break;
-		}
-		dev_info = audio_dev_ctrl_find_dev(dev_id);
-		if (IS_ERR(dev_info))
-			rc = PTR_ERR(dev_info);
-		else {
-			rc = dev_info->dev_ops.open(dev_info);
-			if (!rc)
-				dev_info->opened = 1;
-			wake_up(&audio_dev_ctrl.wait);
-		}
-		break;
-
-	}
-
-	case AUDIO_DISABLE_SND_DEVICE: {
-		struct msm_snddev_info *dev_info;
-		u32 dev_id;
-
-		if (get_user(dev_id, (u32 __user *) arg)) {
-			rc = -EFAULT;
-			break;
-		}
-		dev_info = audio_dev_ctrl_find_dev(dev_id);
-		if (IS_ERR(dev_info))
-			rc = PTR_ERR(dev_info);
-		else {
-			rc = dev_info->dev_ops.close(dev_info);
-			dev_info->opened = 0;
-		}
-		break;
-	}
-
-	case AUDIO_ROUTE_STREAM: {
-		struct msm_audio_route_config route_cfg;
-		struct msm_snddev_info *dev_info;
-
-		if (copy_from_user(&route_cfg, (void __user *) arg,
-			sizeof(struct msm_audio_route_config))) {
-			rc = -EFAULT;
-			break;
-		}
-		pr_debug("%s: route cfg %d %d type\n", __func__,
-		route_cfg.dev_id, route_cfg.stream_type);
-		dev_info = audio_dev_ctrl_find_dev(route_cfg.dev_id);
-		if (IS_ERR(dev_info)) {
-			pr_err("%s: pass invalid dev_id\n", __func__);
-			rc = PTR_ERR(dev_info);
-			break;
-		}
-
-		switch (route_cfg.stream_type) {
-
-		case AUDIO_ROUTE_STREAM_VOICE_RX:
-			if (!(dev_info->capability & SNDDEV_CAP_RX) |
-			    !(dev_info->capability & SNDDEV_CAP_VOICE)) {
-				rc = -EINVAL;
-				break;
-			}
-			dev_ctrl->voice_rx_dev = dev_info;
-			break;
-		case AUDIO_ROUTE_STREAM_VOICE_TX:
-			if (!(dev_info->capability & SNDDEV_CAP_TX) |
-			    !(dev_info->capability & SNDDEV_CAP_VOICE)) {
-				rc = -EINVAL;
-				break;
-			}
-			dev_ctrl->voice_tx_dev = dev_info;
-			break;
-		}
-		break;
-	}
-
-	default:
-		rc = -EINVAL;
-	}
-	mutex_unlock(&session_lock);
-	return rc;
-}
-
-static int audio_dev_ctrl_open(struct inode *inode, struct file *file)
-{
-	pr_debug("open audio_dev_ctrl\n");
-	atomic_inc(&audio_dev_ctrl.opened);
-	file->private_data = &audio_dev_ctrl;
-	return 0;
-}
-
-static int audio_dev_ctrl_release(struct inode *inode, struct file *file)
-{
-	pr_debug("release audio_dev_ctrl\n");
-	atomic_dec(&audio_dev_ctrl.opened);
-	return 0;
-}
-
-static const struct file_operations audio_dev_ctrl_fops = {
-	.owner = THIS_MODULE,
-	.open = audio_dev_ctrl_open,
-	.release = audio_dev_ctrl_release,
-	.unlocked_ioctl = audio_dev_ctrl_ioctl,
-};
-
-
-struct miscdevice audio_dev_ctrl_misc = {
-	.minor	= MISC_DYNAMIC_MINOR,
-	.name	= "msm_audio_dev_ctrl",
-	.fops	= &audio_dev_ctrl_fops,
-};
-
-/* session id is 64 bit routing mask per device
- * 0-15 for voice clients
- * 16-31 for Decoder clients
- * 32-47 for Encoder clients
- * 48-63 Do not care
- */
-void broadcast_event(u32 evt_id, u32 dev_id, u64 session_id)
-{
-	int clnt_id = 0, i;
-	union auddev_evt_data *evt_payload;
-	struct msm_snd_evt_listner *callback;
-	struct msm_snddev_info *dev_info = NULL;
-	u64 session_mask = 0;
-	static int pending_sent;
-
-	pr_debug(": evt_id = %d\n", evt_id);
-
-	if ((evt_id != AUDDEV_EVT_START_VOICE)
-		&& (evt_id != AUDDEV_EVT_END_VOICE)
-		&& (evt_id != AUDDEV_EVT_STREAM_VOL_CHG)
-		&& (evt_id != AUDDEV_EVT_VOICE_STATE_CHG)) {
-		dev_info = audio_dev_ctrl_find_dev(dev_id);
-		if (IS_ERR(dev_info)) {
-			pr_err("%s: pass invalid dev_id(%d)\n",
-					 __func__, dev_id);
-			return;
-		}
-	}
-
-	if (event.cb != NULL)
-		callback = event.cb;
-	else
-		return;
-	mutex_lock(&session_lock);
-
-	if (evt_id == AUDDEV_EVT_VOICE_STATE_CHG)
-		routing_info.voice_state = dev_id;
-
-	evt_payload = kzalloc(sizeof(union auddev_evt_data),
-			GFP_KERNEL);
-
-	if (evt_payload == NULL) {
-		pr_err("broadcast_event: cannot allocate memory\n");
-		mutex_unlock(&session_lock);
-		return;
-	}
-	for (; ;) {
-		if (!(evt_id & callback->evt_id)) {
-			if (callback->cb_next == NULL)
-				break;
-			else {
-				callback = callback->cb_next;
-				continue;
-			}
-		}
-		clnt_id = callback->clnt_id;
-		memset(evt_payload, 0, sizeof(union auddev_evt_data));
-
-		if ((evt_id == AUDDEV_EVT_START_VOICE)
-			|| (evt_id == AUDDEV_EVT_END_VOICE)
-			|| evt_id == AUDDEV_EVT_DEVICE_VOL_MUTE_CHG)
-			goto skip_check;
-		if (callback->clnt_type == AUDDEV_CLNT_AUDIOCAL)
-			goto aud_cal;
-
-		session_mask = (((u64)0x1) << clnt_id)
-				<< (MAX_BIT_PER_CLIENT * \
-				((int)callback->clnt_type-1));
-
-		if ((evt_id == AUDDEV_EVT_STREAM_VOL_CHG) || \
-			(evt_id == AUDDEV_EVT_VOICE_STATE_CHG)) {
-			pr_debug("AUDDEV_EVT_STREAM_VOL_CHG or\
-				AUDDEV_EVT_VOICE_STATE_CHG\n");
-			goto volume_strm;
-		}
-
-		pr_debug("dev_info->sessions = %llu\n", dev_info->sessions);
-
-		if ((!session_id && !(dev_info->sessions & session_mask)) ||
-			(session_id && ((dev_info->sessions & session_mask) !=
-						session_id))) {
-			if (callback->cb_next == NULL)
-				break;
-			else {
-				callback = callback->cb_next;
-				continue;
-			}
-		}
-		if (evt_id == AUDDEV_EVT_DEV_CHG_VOICE)
-			goto voc_events;
-
-volume_strm:
-		if (callback->clnt_type == AUDDEV_CLNT_DEC) {
-			pr_debug("AUDDEV_CLNT_DEC\n");
-			if (evt_id == AUDDEV_EVT_STREAM_VOL_CHG) {
-				pr_debug("clnt_id = %d, session_id = %llu\n",
-					clnt_id, session_id);
-				if (session_mask != session_id)
-					goto sent_dec;
-				else
-					evt_payload->session_vol =
-						msm_vol_ctl.volume;
-			} else if (evt_id == AUDDEV_EVT_FREQ_CHG) {
-				if (routing_info.dec_freq[clnt_id].evt) {
-					routing_info.dec_freq[clnt_id].evt
-							= 0;
-					goto sent_dec;
-				} else if (routing_info.dec_freq[clnt_id].freq
-					== dev_info->set_sample_rate)
-					goto sent_dec;
-				else {
-					evt_payload->freq_info.sample_rate
-						= dev_info->set_sample_rate;
-					evt_payload->freq_info.dev_type
-						= dev_info->capability;
-					evt_payload->freq_info.acdb_dev_id
-						= dev_info->acdb_id;
-				}
-			} else if (evt_id == AUDDEV_EVT_VOICE_STATE_CHG)
-				evt_payload->voice_state =
-					routing_info.voice_state;
-			else
-				evt_payload->routing_id = dev_info->copp_id;
-			callback->auddev_evt_listener(
-					evt_id,
-					evt_payload,
-					callback->private_data);
-sent_dec:
-			if ((evt_id != AUDDEV_EVT_STREAM_VOL_CHG) &&
-				(evt_id != AUDDEV_EVT_VOICE_STATE_CHG))
-				routing_info.dec_freq[clnt_id].freq
-						= dev_info->set_sample_rate;
-
-			if (callback->cb_next == NULL)
-				break;
-			else {
-				callback = callback->cb_next;
-				continue;
-			}
-		}
-		if (callback->clnt_type == AUDDEV_CLNT_ENC) {
-			pr_debug("AUDDEV_CLNT_ENC\n");
-			if (evt_id == AUDDEV_EVT_FREQ_CHG) {
-				if (routing_info.enc_freq[clnt_id].evt) {
-					routing_info.enc_freq[clnt_id].evt
-							= 0;
-					goto sent_enc;
-				 } else {
-					evt_payload->freq_info.sample_rate
-						= dev_info->set_sample_rate;
-					evt_payload->freq_info.dev_type
-						= dev_info->capability;
-					evt_payload->freq_info.acdb_dev_id
-						= dev_info->acdb_id;
-				}
-			} else if (evt_id == AUDDEV_EVT_VOICE_STATE_CHG)
-				evt_payload->voice_state =
-					routing_info.voice_state;
-			else
-				evt_payload->routing_id = dev_info->copp_id;
-			callback->auddev_evt_listener(
-					evt_id,
-					evt_payload,
-					callback->private_data);
-sent_enc:
-			if (callback->cb_next == NULL)
-					break;
-			else {
-				callback = callback->cb_next;
-				continue;
-			}
-		}
-aud_cal:
-		if (callback->clnt_type == AUDDEV_CLNT_AUDIOCAL) {
-			pr_debug("AUDDEV_CLNT_AUDIOCAL\n");
-			if (evt_id == AUDDEV_EVT_VOICE_STATE_CHG)
-				evt_payload->voice_state =
-					routing_info.voice_state;
-			else if (!dev_info->sessions)
-				goto sent_aud_cal;
-			else {
-				evt_payload->audcal_info.dev_id =
-						dev_info->copp_id;
-				evt_payload->audcal_info.acdb_id =
-						dev_info->acdb_id;
-				evt_payload->audcal_info.dev_type =
-					(dev_info->capability & SNDDEV_CAP_TX) ?
-					SNDDEV_CAP_TX : SNDDEV_CAP_RX;
-				evt_payload->audcal_info.sample_rate =
-					dev_info->set_sample_rate ?
-					dev_info->set_sample_rate :
-					dev_info->sample_rate;
-			}
-			callback->auddev_evt_listener(
-				evt_id,
-				evt_payload,
-				callback->private_data);
-
-sent_aud_cal:
-			if (callback->cb_next == NULL)
-				break;
-			else {
-				callback = callback->cb_next;
-				continue;
-			}
-		}
-skip_check:
-voc_events:
-		if (callback->clnt_type == AUDDEV_CLNT_VOC) {
-			pr_debug("AUDDEV_CLNT_VOC\n");
-			if (evt_id == AUDDEV_EVT_DEV_RLS) {
-				if (!pending_sent)
-					goto sent_voc;
-				else
-					pending_sent = 0;
-			}
-			if (evt_id == AUDDEV_EVT_REL_PENDING)
-				pending_sent = 1;
-
-			if (evt_id == AUDDEV_EVT_DEVICE_VOL_MUTE_CHG) {
-				evt_payload->voc_vm_info.voice_session_id =
-								session_id;
-
-				if (dev_info->capability & SNDDEV_CAP_TX) {
-					evt_payload->voc_vm_info.dev_type =
-						SNDDEV_CAP_TX;
-					evt_payload->voc_vm_info.acdb_dev_id =
-						dev_info->acdb_id;
-					evt_payload->
-					voc_vm_info.dev_vm_val.mute =
-						routing_info.tx_mute;
-				} else {
-					evt_payload->voc_vm_info.dev_type =
-						SNDDEV_CAP_RX;
-					evt_payload->voc_vm_info.acdb_dev_id =
-						dev_info->acdb_id;
-					evt_payload->
-					voc_vm_info.dev_vm_val.vol =
-						routing_info.voice_rx_vol;
-				}
-			} else if ((evt_id == AUDDEV_EVT_START_VOICE)
-					|| (evt_id == AUDDEV_EVT_END_VOICE)) {
-				memset(evt_payload, 0,
-					sizeof(union auddev_evt_data));
-
-				evt_payload->voice_session_id = session_id;
-			} else if (evt_id == AUDDEV_EVT_FREQ_CHG) {
-				if (routing_info.voice_tx_sample_rate
-						!= dev_info->set_sample_rate) {
-					routing_info.voice_tx_sample_rate
-						= dev_info->set_sample_rate;
-					evt_payload->freq_info.sample_rate
-						= dev_info->set_sample_rate;
-					evt_payload->freq_info.dev_type
-						= dev_info->capability;
-					evt_payload->freq_info.acdb_dev_id
-						= dev_info->acdb_id;
-				} else
-					goto sent_voc;
-			} else if (evt_id == AUDDEV_EVT_VOICE_STATE_CHG)
-				evt_payload->voice_state =
-						routing_info.voice_state;
-			else {
-				evt_payload->voc_devinfo.dev_type =
-					(dev_info->capability & SNDDEV_CAP_TX) ?
-					SNDDEV_CAP_TX : SNDDEV_CAP_RX;
-				evt_payload->voc_devinfo.acdb_dev_id =
-					dev_info->acdb_id;
-				evt_payload->voc_devinfo.dev_port_id =
-					dev_info->copp_id;
-				evt_payload->voc_devinfo.dev_sample =
-					dev_info->set_sample_rate ?
-					dev_info->set_sample_rate :
-					dev_info->sample_rate;
-				evt_payload->voc_devinfo.dev_id = dev_id;
-				if (dev_info->capability & SNDDEV_CAP_RX) {
-					for (i = 0; i < VOC_RX_VOL_ARRAY_NUM;
-						i++) {
-						evt_payload->
-						voc_devinfo.max_rx_vol[i] =
-						dev_info->max_voc_rx_vol[i];
-						evt_payload
-						->voc_devinfo.min_rx_vol[i] =
-						dev_info->min_voc_rx_vol[i];
-					}
-				}
-			}
-			callback->auddev_evt_listener(
-				evt_id,
-				evt_payload,
-				callback->private_data);
-			if (evt_id == AUDDEV_EVT_DEV_RLS)
-				dev_info->sessions &= ~(0xFFFF);
-sent_voc:
-			if (callback->cb_next == NULL)
-				break;
-			else {
-				callback = callback->cb_next;
-				continue;
-			}
-		}
-	}
-	kfree(evt_payload);
-	mutex_unlock(&session_lock);
-}
-EXPORT_SYMBOL(broadcast_event);
-
-
-void mixer_post_event(u32 evt_id, u32 id)
-{
-
-	pr_debug("evt_id = %d\n", evt_id);
-	switch (evt_id) {
-	case AUDDEV_EVT_DEV_CHG_VOICE: /* Called from Voice_route */
-		broadcast_event(AUDDEV_EVT_DEV_CHG_VOICE, id, SESSION_IGNORE);
-		break;
-	case AUDDEV_EVT_DEV_RDY:
-		broadcast_event(AUDDEV_EVT_DEV_RDY, id, SESSION_IGNORE);
-		break;
-	case AUDDEV_EVT_DEV_RLS:
-		broadcast_event(AUDDEV_EVT_DEV_RLS, id, SESSION_IGNORE);
-		break;
-	case AUDDEV_EVT_REL_PENDING:
-		broadcast_event(AUDDEV_EVT_REL_PENDING, id, SESSION_IGNORE);
-		break;
-	case AUDDEV_EVT_DEVICE_VOL_MUTE_CHG:
-		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG, id,
-							SESSION_IGNORE);
-		break;
-	case AUDDEV_EVT_STREAM_VOL_CHG:
-		broadcast_event(AUDDEV_EVT_STREAM_VOL_CHG, id,
-							SESSION_IGNORE);
-		break;
-	case AUDDEV_EVT_START_VOICE:
-		broadcast_event(AUDDEV_EVT_START_VOICE,
-				id, SESSION_IGNORE);
-		break;
-	case AUDDEV_EVT_END_VOICE:
-		broadcast_event(AUDDEV_EVT_END_VOICE,
-				id, SESSION_IGNORE);
-		break;
-	case AUDDEV_EVT_FREQ_CHG:
-		broadcast_event(AUDDEV_EVT_FREQ_CHG, id, SESSION_IGNORE);
-		break;
-	default:
-		break;
-	}
-}
-EXPORT_SYMBOL(mixer_post_event);
-
-static int __init audio_dev_ctrl_init(void)
-{
-	init_waitqueue_head(&audio_dev_ctrl.wait);
-
-	event.cb = NULL;
-	msm_reset_device_work_queue = create_workqueue("reset_device");
-	if (msm_reset_device_work_queue == NULL)
-		return -ENOMEM;
-	atomic_set(&audio_dev_ctrl.opened, 0);
-	audio_dev_ctrl.num_dev = 0;
-	audio_dev_ctrl.voice_tx_dev = NULL;
-	audio_dev_ctrl.voice_rx_dev = NULL;
-	routing_info.voice_state = VOICE_STATE_INVALID;
-
-	mutex_init(&adm_tx_topology_tbl.lock);
-	mutex_init(&routing_info.copp_list_mutex);
-	mutex_init(&routing_info.adm_mutex);
-
-	memset(routing_info.copp_list, COPP_IGNORE,
-		(sizeof(unsigned int) * MAX_SESSIONS * AFE_MAX_PORTS));
-	return misc_register(&audio_dev_ctrl_misc);
-}
-
-static void __exit audio_dev_ctrl_exit(void)
-{
-	destroy_workqueue(msm_reset_device_work_queue);
-}
-module_init(audio_dev_ctrl_init);
-module_exit(audio_dev_ctrl_exit);
-
-MODULE_DESCRIPTION("MSM 8K Audio Device Control driver");
-MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils.c b/arch/arm/mach-msm/qdsp6v2/audio_utils.c
index ccacd3e..2f1ff3e 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils.c
@@ -393,7 +393,7 @@
 	uint32_t mfield_size = (audio->buf_cfg.meta_info_enable == 0) ? 0 :
 		(sizeof(unsigned char) +
 		(sizeof(struct meta_out_dsp)*(audio->buf_cfg.frames_per_buf)));
-
+	memset(&meta, 0, sizeof(meta));
 	pr_debug("%s:session id %d: read - %d\n", __func__, audio->ac->session,
 			count);
 	if (!audio->enabled)
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
index 5fa7b1b..5bdd10a 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
@@ -1199,6 +1199,7 @@
 	case AUDIO_GET_STATS: {
 		struct msm_audio_stats stats;
 		uint64_t timestamp;
+		memset(&stats, 0, sizeof(struct msm_audio_stats));
 		stats.byte_count = atomic_read(&audio->in_bytes);
 		stats.sample_count = atomic_read(&audio->in_samples);
 		rc = q6asm_get_session_time(audio->ac, &timestamp);
diff --git a/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c b/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
deleted file mode 100644
index c6def46..0000000
--- a/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
+++ /dev/null
@@ -1,464 +0,0 @@
-/* Copyright (c) 2011, 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.
- */
-
-#define pr_fmt(fmt) "%s: " fmt, __func__
-
-#include <linux/fs.h>
-#include <linux/module.h>
-#include <linux/miscdevice.h>
-#include <linux/mutex.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/uaccess.h>
-#include <linux/dma-mapping.h>
-#include <linux/msm_audio.h>
-#include <mach/msm_hdmi_audio.h>
-#include <mach/audio_dma_msm8k.h>
-#include <sound/dai.h>
-#include <mach/qdsp6v2/q6core.h>
-
-#define DMA_ALLOC_BUF_SZ		(SZ_4K * 16)
-
-#define HDMI_AUDIO_FIFO_WATER_MARK	4
-
-struct audio_buffer {
-	dma_addr_t phys;
-	void *data;
-	uint32_t size;
-	uint32_t used;	/* 1 = CPU is waiting for DMA to consume this buf */
-	uint32_t actual_size;	/* actual number of bytes read by DMA */
-};
-
-struct lpa_if {
-	struct mutex lock;
-	struct msm_audio_config cfg;
-	struct audio_buffer audio_buf[6];
-	int cpu_buf;		/* next buffer the CPU will touch */
-	int dma_buf;		/* next buffer the DMA will touch */
-	u8 *buffer;
-	dma_addr_t buffer_phys;
-	u32 dma_ch;
-	wait_queue_head_t wait;
-	u32 config;
-	u32 dma_period_sz;
-	unsigned int num_periods;
-};
-
-static struct lpa_if  *lpa_if_ptr;
-
-static unsigned int dma_buf_index;
-
-static irqreturn_t lpa_if_irq(int intrsrc, void *data)
-{
-	struct lpa_if *lpa_if = data;
-	int dma_ch = 0;
-	unsigned int pending;
-
-	if (lpa_if)
-		dma_ch = lpa_if->dma_ch;
-	else {
-		pr_err("invalid lpa_if\n");
-		return IRQ_NONE;
-	}
-
-	pending = (intrsrc
-		   & (UNDER_CH(dma_ch) | PER_CH(dma_ch) | ERR_CH(dma_ch)));
-
-	if (pending & UNDER_CH(dma_ch))
-		pr_err("under run\n");
-	if (pending & ERR_CH(dma_ch))
-		pr_err("DMA %x Master Error\n", dma_ch);
-
-	if (pending & PER_CH(dma_ch)) {
-
-		lpa_if->audio_buf[lpa_if->dma_buf].used = 0;
-
-		pr_debug("dma_buf %d  used %d\n", lpa_if->dma_buf,
-			lpa_if->audio_buf[lpa_if->dma_buf].used);
-		lpa_if->dma_buf++;
-		lpa_if->dma_buf = lpa_if->dma_buf % lpa_if->cfg.buffer_count;
-
-		if (lpa_if->dma_buf == lpa_if->cpu_buf)
-			pr_err("Err:both dma_buf and cpu_buf are on same index\n");
-		wake_up(&lpa_if->wait);
-	}
-	return IRQ_HANDLED;
-}
-
-
-int lpa_if_start(struct lpa_if *lpa_if)
-{
-	pr_debug("buf1 0x%x, buf2 0x%x dma_ch %d\n",
-		(unsigned int)lpa_if->audio_buf[0].data,
-		(unsigned int)lpa_if->audio_buf[1].data, lpa_if->dma_ch);
-
-	dai_start_hdmi(lpa_if->dma_ch);
-
-	hdmi_audio_enable(1, HDMI_AUDIO_FIFO_WATER_MARK);
-
-	hdmi_audio_packet_enable(1);
-	return 0;
-}
-
-int lpa_if_config(struct lpa_if *lpa_if)
-{
-	struct dai_dma_params dma_params;
-
-	dma_params.src_start = lpa_if->buffer_phys;
-	dma_params.buffer = lpa_if->buffer;
-	dma_params.buffer_size = lpa_if->dma_period_sz * lpa_if->num_periods;
-	dma_params.period_size = lpa_if->dma_period_sz;
-	dma_params.channels = 2;
-
-	lpa_if->dma_ch = 4;
-	dai_set_params(lpa_if->dma_ch, &dma_params);
-
-	register_dma_irq_handler(lpa_if->dma_ch, lpa_if_irq, (void *)lpa_if);
-
-	mb();
-	pr_debug("lpa_if 0x%08x  buf_vir 0x%08x   buf_phys 0x%08x  "
-		"config %u\n", (u32)lpa_if, (u32) (lpa_if->buffer),
-		lpa_if->buffer_phys, lpa_if->config);
-
-	pr_debug("user_buf_cnt %u user_buf_size %u\n",
-			lpa_if->cfg.buffer_count, lpa_if->cfg.buffer_size);
-
-	lpa_if->config = 1;
-
-	lpa_if_start(lpa_if);
-
-	return 0;
-}
-
-
-static long lpa_if_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct lpa_if *lpa_if = file->private_data;
-	int rc = 0;
-	unsigned int i;
-	pr_debug("cmd %u\n", cmd);
-
-	mutex_lock(&lpa_if->lock);
-
-	switch (cmd) {
-	case AUDIO_START:
-		pr_debug("AUDIO_START\n");
-
-		if (dma_buf_index == 2) {
-			if (!lpa_if->config) {
-				rc = lpa_if_config(lpa_if);
-				if (rc)
-					pr_err("lpa_if_config failed\n");
-			}
-		} else {
-			pr_err("did not receved two buffer for "
-				"AUDIO_STAR\n");
-			rc =  -EPERM;
-		}
-		break;
-
-	case AUDIO_STOP:
-		pr_debug("AUDIO_STOP\n");
-		break;
-
-	case AUDIO_FLUSH:
-		pr_debug("AUDIO_FLUSH\n");
-		break;
-
-
-	case AUDIO_GET_CONFIG:
-		pr_debug("AUDIO_GET_CONFIG\n");
-		if (copy_to_user((void *)arg, &lpa_if->cfg,
-				 sizeof(struct msm_audio_config))) {
-			rc = -EFAULT;
-		}
-		break;
-	case AUDIO_SET_CONFIG: {
-		/*  Setting default rate as 48khz */
-		unsigned int cur_sample_rate =
-			HDMI_SAMPLE_RATE_48KHZ;
-		struct msm_audio_config config;
-
-		pr_debug("AUDIO_SET_CONFIG\n");
-		if (copy_from_user(&config, (void *)arg, sizeof(config))) {
-			rc = -EFAULT;
-			break;
-		}
-		lpa_if->dma_period_sz = config.buffer_size;
-		if ((lpa_if->dma_period_sz * lpa_if->num_periods) >
-			DMA_ALLOC_BUF_SZ) {
-			pr_err("Dma buffer size greater than allocated size\n");
-			return -EINVAL;
-		}
-		pr_debug("Dma_period_sz %d\n", lpa_if->dma_period_sz);
-		if (lpa_if->dma_period_sz < (2 * SZ_4K))
-			lpa_if->num_periods = 6;
-		pr_debug("No. of Periods %d\n", lpa_if->num_periods);
-
-		lpa_if->cfg.buffer_count = lpa_if->num_periods;
-		lpa_if->cfg.buffer_size = lpa_if->dma_period_sz *
-						lpa_if->num_periods;
-
-		for (i = 0; i < lpa_if->cfg.buffer_count; i++) {
-			lpa_if->audio_buf[i].phys =
-				lpa_if->buffer_phys + i * lpa_if->dma_period_sz;
-			lpa_if->audio_buf[i].data =
-				lpa_if->buffer + i * lpa_if->dma_period_sz;
-			lpa_if->audio_buf[i].size = lpa_if->dma_period_sz;
-			lpa_if->audio_buf[i].used = 0;
-		}
-
-		pr_debug("Sample rate %d\n", config.sample_rate);
-		switch (config.sample_rate) {
-		case 48000:
-			cur_sample_rate = HDMI_SAMPLE_RATE_48KHZ;
-			break;
-		case 44100:
-			cur_sample_rate = HDMI_SAMPLE_RATE_44_1KHZ;
-			break;
-		case 32000:
-			cur_sample_rate = HDMI_SAMPLE_RATE_32KHZ;
-			break;
-		case 88200:
-			cur_sample_rate = HDMI_SAMPLE_RATE_88_2KHZ;
-			break;
-		case 96000:
-			cur_sample_rate = HDMI_SAMPLE_RATE_96KHZ;
-			break;
-		case 176400:
-			cur_sample_rate = HDMI_SAMPLE_RATE_176_4KHZ;
-			break;
-		case 192000:
-			cur_sample_rate = HDMI_SAMPLE_RATE_192KHZ;
-			break;
-		default:
-			cur_sample_rate = HDMI_SAMPLE_RATE_48KHZ;
-		}
-		if (cur_sample_rate != hdmi_msm_audio_get_sample_rate())
-			hdmi_msm_audio_sample_rate_reset(cur_sample_rate);
-		else
-			pr_debug("Previous sample rate and current"
-				"sample rate are same\n");
-		break;
-	}
-	default:
-		pr_err("UnKnown Ioctl\n");
-		rc = -EINVAL;
-	}
-
-	mutex_unlock(&lpa_if->lock);
-
-	return rc;
-}
-
-
-static int lpa_if_open(struct inode *inode, struct file *file)
-{
-	pr_debug("\n");
-
-	file->private_data = lpa_if_ptr;
-	dma_buf_index = 0;
-	lpa_if_ptr->cpu_buf = 2;
-	lpa_if_ptr->dma_buf = 0;
-	lpa_if_ptr->num_periods = 4;
-
-	core_req_bus_bandwith(AUDIO_IF_BUS_ID, 100000, 0);
-	mb();
-
-	return 0;
-}
-
-static inline int rt_policy(int policy)
-{
-	if (unlikely(policy == SCHED_FIFO) || unlikely(policy == SCHED_RR))
-		return 1;
-	return 0;
-}
-
-static inline int task_has_rt_policy(struct task_struct *p)
-{
-	return rt_policy(p->policy);
-}
-static ssize_t lpa_if_write(struct file *file, const char __user *buf,
-		size_t count, loff_t *pos)
-{
-	struct lpa_if *lpa_if = file->private_data;
-	struct audio_buffer *ab;
-	const char __user *start = buf;
-	int xfer, rc;
-	struct sched_param s = { .sched_priority = 1 };
-	int old_prio = current->rt_priority;
-	int old_policy = current->policy;
-	int cap_nice = cap_raised(current_cap(), CAP_SYS_NICE);
-
-	 /* just for this write, set us real-time */
-	if (!task_has_rt_policy(current)) {
-		struct cred *new = prepare_creds();
-		cap_raise(new->cap_effective, CAP_SYS_NICE);
-		commit_creds(new);
-		if ((sched_setscheduler(current, SCHED_RR, &s)) < 0)
-			pr_err("sched_setscheduler failed\n");
-	}
-	mutex_lock(&lpa_if->lock);
-
-	if (dma_buf_index < 2) {
-
-		ab = lpa_if->audio_buf + dma_buf_index;
-
-		if (copy_from_user(ab->data, buf, count)) {
-			pr_err("copy from user failed\n");
-			rc = 0;
-			goto end;
-
-		}
-		mb();
-		pr_debug("prefill: count %u  audio_buf[%u].size %u\n",
-			 count, dma_buf_index, ab->size);
-
-		ab->used = 1;
-		dma_buf_index++;
-		rc =  count;
-		goto end;
-	}
-
-	if (lpa_if->config != 1) {
-		pr_err("AUDIO_START did not happen\n");
-		rc = 0;
-		goto end;
-	}
-
-	while (count > 0) {
-
-		ab = lpa_if->audio_buf + lpa_if->cpu_buf;
-
-		rc = wait_event_timeout(lpa_if->wait, (ab->used == 0), 10 * HZ);
-		if (!rc) {
-			pr_err("wait_event_timeout failed\n");
-			rc =  buf - start;
-			goto end;
-		}
-
-		xfer = count;
-
-		if (xfer > lpa_if->dma_period_sz)
-			xfer = lpa_if->dma_period_sz;
-
-		if (copy_from_user(ab->data, buf, xfer)) {
-			pr_err("copy from user failed\n");
-			rc = buf - start;
-			goto end;
-		}
-
-		mb();
-		buf += xfer;
-		count -= xfer;
-		ab->used = 1;
-
-		pr_debug("xfer %d, size %d, used %d cpu_buf %d\n",
-			xfer, ab->size, ab->used, lpa_if->cpu_buf);
-		lpa_if->cpu_buf++;
-		lpa_if->cpu_buf = lpa_if->cpu_buf % lpa_if->cfg.buffer_count;
-	}
-	rc = buf - start;
-end:
-	mutex_unlock(&lpa_if->lock);
-	/* restore old scheduling policy */
-	if (!rt_policy(old_policy)) {
-		struct sched_param v = { .sched_priority = old_prio };
-		if ((sched_setscheduler(current, old_policy, &v)) < 0)
-			pr_err("sched_setscheduler failed\n");
-		if (likely(!cap_nice)) {
-			struct cred *new = prepare_creds();
-			cap_lower(new->cap_effective, CAP_SYS_NICE);
-			commit_creds(new);
-		}
-	}
-	return rc;
-}
-
-static int lpa_if_release(struct inode *inode, struct file *file)
-{
-	struct lpa_if *lpa_if = file->private_data;
-
-	hdmi_audio_packet_enable(0);
-
-	wait_for_dma_cnt_stop(lpa_if->dma_ch);
-
-	hdmi_audio_enable(0, HDMI_AUDIO_FIFO_WATER_MARK);
-
-	if (lpa_if->config) {
-		unregister_dma_irq_handler(lpa_if->dma_ch);
-		dai_stop_hdmi(lpa_if->dma_ch);
-		lpa_if->config = 0;
-	}
-	core_req_bus_bandwith(AUDIO_IF_BUS_ID, 0, 0);
-
-	if (hdmi_msm_audio_get_sample_rate() != HDMI_SAMPLE_RATE_48KHZ)
-		hdmi_msm_audio_sample_rate_reset(HDMI_SAMPLE_RATE_48KHZ);
-
-	return 0;
-}
-
-static const struct file_operations lpa_if_fops = {
-	.owner = THIS_MODULE,
-	.open = lpa_if_open,
-	.write = lpa_if_write,
-	.release = lpa_if_release,
-	.unlocked_ioctl = lpa_if_ioctl,
-};
-
-struct miscdevice lpa_if_misc = {
-	.minor = MISC_DYNAMIC_MINOR,
-	.name = "msm_lpa_if_out",
-	.fops = &lpa_if_fops,
-};
-
-static int __init lpa_if_init(void)
-{
-	int rc;
-
-	lpa_if_ptr = kzalloc(sizeof(struct lpa_if), GFP_KERNEL);
-	if (!lpa_if_ptr) {
-		pr_info("No mem for lpa-if\n");
-		return -ENOMEM;
-	}
-
-	mutex_init(&lpa_if_ptr->lock);
-	init_waitqueue_head(&lpa_if_ptr->wait);
-
-	lpa_if_ptr->buffer = dma_alloc_coherent(NULL, DMA_ALLOC_BUF_SZ,
-				    &(lpa_if_ptr->buffer_phys), GFP_KERNEL);
-	if (!lpa_if_ptr->buffer) {
-		pr_err("dma_alloc_coherent failed\n");
-		kfree(lpa_if_ptr);
-		return -ENOMEM;
-	}
-
-	pr_info("lpa_if_ptr 0x%08x   buf_vir 0x%08x   buf_phy 0x%08x "
-		" buf_zise %u\n", (u32)lpa_if_ptr,
-		(u32)(lpa_if_ptr->buffer), lpa_if_ptr->buffer_phys,
-		DMA_ALLOC_BUF_SZ);
-
-	rc =  misc_register(&lpa_if_misc);
-	if (rc < 0) {
-		pr_err("misc_register failed\n");
-
-		dma_free_coherent(NULL, DMA_ALLOC_BUF_SZ, lpa_if_ptr->buffer,
-				lpa_if_ptr->buffer_phys);
-		kfree(lpa_if_ptr);
-	}
-	return rc;
-}
-
-device_initcall(lpa_if_init);
diff --git a/arch/arm/mach-msm/qdsp6v2/msm_audio_ion.c b/arch/arm/mach-msm/qdsp6v2/msm_audio_ion.c
index 0a50bcc..fc6de64 100644
--- a/arch/arm/mach-msm/qdsp6v2/msm_audio_ion.c
+++ b/arch/arm/mach-msm/qdsp6v2/msm_audio_ion.c
@@ -269,6 +269,7 @@
 	} else {
 		ion_phys_addr_t phys_addr;
 		size_t phys_len;
+		size_t va_len = 0;
 		pr_debug("%s: page is NULL\n", __func__);
 
 		ret = ion_phys(ab->client, ab->handle, &phys_addr, &phys_len);
@@ -282,6 +283,12 @@
 			vma, (unsigned int)vma->vm_start,
 			(unsigned int)vma->vm_end, vma->vm_pgoff,
 			(unsigned long int)vma->vm_page_prot);
+		va_len = vma->vm_end - vma->vm_start;
+		if ((offset > phys_len) || (va_len > phys_len-offset)) {
+			pr_err("wrong offset size %ld, lens= %d, va_len=%d\n",
+				offset, phys_len, va_len);
+			return -EINVAL;
+		}
 		ret =  remap_pfn_range(vma, vma->vm_start,
 				__phys_to_pfn(phys_addr) + vma->vm_pgoff,
 				vma->vm_end - vma->vm_start,
@@ -321,6 +328,11 @@
 			ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr)
 {
 	int rc = 0;
+	if (!name || !client || !handle || !paddr || !vaddr || !pa_len) {
+		pr_err("%s: Invalid params\n", __func__);
+		rc = -EINVAL;
+		goto err;
+	}
 	/* client is already created for legacy and given*/
 	/* name should be audio_acdb_client or Audio_Dec_Client,
 	bufsz should be 0 and fd shouldn't be 0 as of now
@@ -331,14 +343,16 @@
 	if (IS_ERR_OR_NULL((void *)(*handle))) {
 		pr_err("%s: ion import dma buffer failed\n",
 			__func__);
-		goto err_ion_handle;
-		}
+		rc = -EINVAL;
+		goto err_destroy_client;
+	}
 
 	if (ionflag != NULL) {
 		rc = ion_handle_get_flags(client, *handle, ionflag);
 		if (rc) {
 			pr_err("%s: could not get flags for the handle\n",
 							__func__);
+			rc = -EINVAL;
 			goto err_ion_handle;
 		}
 	}
@@ -347,6 +361,7 @@
 	if (rc) {
 		pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n",
 			__func__, rc);
+		rc = -EINVAL;
 		goto err_ion_handle;
 	}
 
@@ -354,6 +369,7 @@
 	*vaddr = ion_map_kernel(client, *handle);
 	if (IS_ERR_OR_NULL((void *)*vaddr)) {
 		pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
+		rc = -EINVAL;
 		goto err_ion_handle;
 	}
 
@@ -364,8 +380,12 @@
 
 err_ion_handle:
 	ion_free(client, *handle);
-	return -EINVAL;
-
+err_destroy_client:
+	msm_audio_ion_client_destroy(client);
+	client = NULL;
+	*handle = NULL;
+err:
+	return rc;
 }
 
 int msm_audio_ion_free_legacy(struct ion_client *client,
diff --git a/arch/arm/mach-msm/qdsp6v2/pcm_in.c b/arch/arm/mach-msm/qdsp6v2/pcm_in.c
index 0db4894..cf7548d 100644
--- a/arch/arm/mach-msm/qdsp6v2/pcm_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/pcm_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -256,6 +256,7 @@
 	}
 	case AUDIO_GET_CONFIG: {
 		struct msm_audio_config config;
+		memset(&config, 0, sizeof(config));
 		config.buffer_size = pcm->buffer_size;
 		config.buffer_count = pcm->buffer_count;
 		config.sample_rate = pcm->sample_rate;
diff --git a/arch/arm/mach-msm/qdsp6v2/pcm_in_proxy.c b/arch/arm/mach-msm/qdsp6v2/pcm_in_proxy.c
index 5faee21..f7bf1ae 100644
--- a/arch/arm/mach-msm/qdsp6v2/pcm_in_proxy.c
+++ b/arch/arm/mach-msm/qdsp6v2/pcm_in_proxy.c
@@ -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
@@ -475,6 +475,7 @@
 	}
 	case AUDIO_GET_CONFIG: {
 		struct msm_audio_config config;
+		memset(&config, 0, sizeof(config));
 		config.buffer_size = pcm->buffer_size;
 		config.buffer_count = pcm->buffer_count;
 		config.sample_rate = pcm->sample_rate;
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h b/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h
index bf47366..7ab4ec3 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h
@@ -26,6 +26,8 @@
 #define FORMAT_USPS_EPOS	0x00000000
 #define FORMAT_USRAW		0x00000001
 #define FORMAT_USPROX		0x00000002
+#define FORMAT_USGES_SYNC	0x00000003
+#define FORMAT_USRAW_SYNC	0x00000004
 #define INVALID_FORMAT		0xffffffff
 
 #define IN			0x000
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
index 1ea213a..e6b1324 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
@@ -27,8 +27,8 @@
 #include "usfcdev.h"
 
 /* The driver version*/
-#define DRV_VERSION "1.4.2"
-#define USF_VERSION_ID 0x0142
+#define DRV_VERSION "1.5.1"
+#define USF_VERSION_ID 0x0151
 
 /* Standard timeout in the asynchronous ops */
 #define USF_TIMEOUT_JIFFIES (1*HZ) /* 1 sec */
@@ -57,6 +57,8 @@
 /* Place for US detection result, received from QDSP6 */
 #define APR_US_DETECT_RESULT_IND 0
 
+#define BITS_IN_BYTE 8
+
 /* The driver states */
 enum usf_state_type {
 	USF_IDLE_STATE,
@@ -117,6 +119,8 @@
 	uint16_t conflicting_event_types;
 	/* Bitmap of types of events from devs, conflicting with USF */
 	uint16_t conflicting_event_filters;
+	/* The requested side buttons bitmap */
+	uint16_t req_side_buttons_bitmap;
 };
 
 struct usf_input_dev_type {
@@ -146,6 +150,12 @@
 	0,            /* US_INPUT_SRC_UNDEF */
 };
 
+/* Supported buttons container */
+static const int s_button_map[] = {
+	BTN_STYLUS,
+	BTN_STYLUS2
+};
+
 /* The opened devices container */
 static int s_opened_devs[MAX_DEVS_NUMBER];
 
@@ -176,14 +186,35 @@
 				struct us_input_info_type *input_info,
 				const char *name)
 {
+	int i = 0;
+	int num_side_buttons = min(ARRAY_SIZE(s_button_map),
+		sizeof(input_info->req_side_buttons_bitmap) *
+		BITS_IN_BYTE);
+	uint16_t max_side_button_bitmap = ((1 << ARRAY_SIZE(s_button_map)) - 1);
 	struct input_dev *in_dev = allocate_dev(ind, name);
-
 	if (in_dev == NULL)
 		return -ENOMEM;
 
+	if (input_info->req_side_buttons_bitmap > max_side_button_bitmap) {
+		pr_err("%s: Requested side buttons[%d] exceeds max side buttons available[%d]\n",
+		__func__,
+		input_info->req_side_buttons_bitmap,
+		max_side_button_bitmap);
+		return -EINVAL;
+	}
+
 	usf_info->input_ifs[ind] = in_dev;
+	usf_info->req_side_buttons_bitmap =
+		input_info->req_side_buttons_bitmap;
 	in_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 	in_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+
+
+	for (i = 0; i < num_side_buttons; i++)
+		if (input_info->req_side_buttons_bitmap & (1 << i))
+			in_dev->keybit[BIT_WORD(s_button_map[i])] |=
+			BIT_MASK(s_button_map[i]);
+
 	input_set_abs_params(in_dev, ABS_X,
 			     input_info->tsc_x_dim[MIN_IND],
 			     input_info->tsc_x_dim[MAX_IND],
@@ -260,6 +291,11 @@
 			     struct usf_event_type *event)
 
 {
+	int i = 0;
+	int num_side_buttons = min(ARRAY_SIZE(s_button_map),
+		sizeof(usf_info->req_side_buttons_bitmap) *
+		BITS_IN_BYTE);
+
 	struct input_dev *input_if = usf_info->input_ifs[if_ind];
 	struct point_event_type *pe = &(event->event_data.point_event);
 
@@ -273,19 +309,27 @@
 	input_report_abs(input_if, ABS_PRESSURE, pe->pressure);
 	input_report_key(input_if, BTN_TOUCH, !!(pe->pressure));
 
+	for (i = 0; i < num_side_buttons; i++) {
+		uint16_t mask = (1 << i),
+		btn_state = !!(pe->side_buttons_state_bitmap & mask);
+		if (usf_info->req_side_buttons_bitmap & mask)
+			input_report_key(input_if, s_button_map[i], btn_state);
+	}
+
 	if (usf_info->event_src)
 		input_report_key(input_if, usf_info->event_src, 1);
 
 	input_sync(input_if);
 
-	pr_debug("%s: TSC event: xyz[%d;%d;%d], incl[%d;%d], pressure[%d]\n",
+	pr_debug("%s: TSC event: xyz[%d;%d;%d], incl[%d;%d], pressure[%d], side_buttons[%d]\n",
 		 __func__,
 		 pe->coordinates[X_IND],
 		 pe->coordinates[Y_IND],
 		 pe->coordinates[Z_IND],
 		 pe->inclinations[X_IND],
 		 pe->inclinations[Y_IND],
-		 pe->pressure);
+		 pe->pressure,
+		 pe->side_buttons_state_bitmap);
 }
 
 static void notify_mouse_event(struct usf_type *usf_info,
@@ -338,6 +382,8 @@
 		prepare_mouse_input_device, notify_mouse_event},
 	{USF_KEYBOARD_EVENT, "usf_kb",
 		prepare_keyboard_input_device, notify_key_event},
+	{USF_TSC_EXT_EVENT, "usf_tsc_ext",
+		prepare_tsc_input_device, notify_tsc_event},
 };
 
 static void usf_rx_cb(uint32_t opcode, uint32_t token,
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c
index 1299b96..578a6e5 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c
@@ -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
@@ -24,8 +24,6 @@
 #define SLOT_CMD_ID 0
 #define MAX_RETRIES 10
 
-
-
 enum usdev_event_status {
 	USFCDEV_EVENT_ENABLED,
 	USFCDEV_EVENT_DISABLING,
@@ -98,8 +96,14 @@
 	},
 };
 
-/* For each event type, one conflicting device (and handle) is supported */
-static struct input_handle s_usfc_handles[MAX_EVENT_TYPE_NUM] = {
+/*
+ * For each event type, there are a number conflicting devices (handles)
+ * The first registered device (primary) is real TSC device; it's mandatory
+ * Optionally, later registered devices are simulated ones.
+ * They are dynamically managed
+ * The primary device's handles are stored in the below static array
+ */
+static struct input_handle s_usfc_primary_handles[MAX_EVENT_TYPE_NUM] = {
 	{ /* TSC handle */
 		.handler	= &s_usfc_handlers[TSC_EVENT_TYPE_IND],
 		.name		= "usfc_tsc_handle",
@@ -142,22 +146,48 @@
 {
 	int ret = 0;
 	uint16_t ind = handler->minor;
+	struct input_handle *usfc_handle = NULL;
 
-	s_usfc_handles[ind].dev = dev;
-	ret = input_register_handle(&s_usfc_handles[ind]);
-	if (ret) {
+	if (s_usfc_primary_handles[ind].dev == NULL) {
+		pr_debug("%s: primary device; ind=%d\n",
+			__func__,
+			ind);
+		usfc_handle = &s_usfc_primary_handles[ind];
+	} else {
+		pr_debug("%s: secondary device; ind=%d\n",
+			__func__,
+			ind);
+		usfc_handle = kzalloc(sizeof(struct input_handle),
+					GFP_KERNEL);
+		if (!usfc_handle) {
+			pr_err("%s: memory allocation failed; ind=%d\n",
+				__func__,
+				ind);
+			return -ENOMEM;
+		}
+		usfc_handle->handler = &s_usfc_handlers[ind];
+		usfc_handle->name = s_usfc_primary_handles[ind].name;
+	}
+	usfc_handle->dev = dev;
+	ret = input_register_handle(usfc_handle);
+	pr_debug("%s: name=[%s]; ind=%d; dev=0x%p\n",
+		 __func__,
+		dev->name,
+		ind,
+		usfc_handle->dev);
+	if (ret)
 		pr_err("%s: input_register_handle[%d] failed: ret=%d\n",
 			__func__,
 			ind,
 			ret);
-	} else {
-		ret = input_open_device(&s_usfc_handles[ind]);
+	else {
+		ret = input_open_device(usfc_handle);
 		if (ret) {
 			pr_err("%s: input_open_device[%d] failed: ret=%d\n",
 				__func__,
 				ind,
 				ret);
-			input_unregister_handle(&s_usfc_handles[ind]);
+			input_unregister_handle(usfc_handle);
 		} else
 			pr_debug("%s: device[%d] is opened\n",
 				__func__,
@@ -169,10 +199,18 @@
 
 static void usfcdev_disconnect(struct input_handle *handle)
 {
+	int ind = handle->handler->minor;
+
+	input_close_device(handle);
 	input_unregister_handle(handle);
-	pr_debug("%s: handle[%d] is disconnect\n",
+	pr_debug("%s: handle[%d], name=[%s] is disconnected\n",
 		__func__,
-		handle->handler->minor);
+		ind,
+		handle->dev->name);
+	if (s_usfc_primary_handles[ind].dev == handle->dev)
+		s_usfc_primary_handles[ind].dev = NULL;
+	else
+		kfree(handle);
 }
 
 static bool usfcdev_filter(struct input_handle *handle,
@@ -297,8 +335,13 @@
 			event_type_ind);
 		return;
 	}
-
-	dev = s_usfc_handles[event_type_ind].dev;
+	/* Only primary device must exist */
+	dev = s_usfc_primary_handles[event_type_ind].dev;
+	if (dev == NULL) {
+		pr_err("%s: NULL primary device\n",
+		__func__);
+		return;
+	}
 
 	for (i = 0; i < ARRAY_SIZE(initial_clear_cmds); i++)
 		usfcdev_send_cmd(dev, initial_clear_cmds[i]);
@@ -307,7 +350,7 @@
 	/* Send commands to free all slots */
 	for (i = 0; i < dev->mtsize; i++) {
 		s_usfcdev_events[event_type_ind].interleaved = false;
-		if (input_mt_get_value(&(dev->mt[i]), ABS_MT_TRACKING_ID) < 0) {
+		if (input_mt_get_value(&dev->mt[i], ABS_MT_TRACKING_ID) < 0) {
 			pr_debug("%s: skipping slot %d",
 				__func__, i);
 			continue;
@@ -323,7 +366,7 @@
 				--i;
 				continue;
 			}
-			pr_warning("%s: index(%d) reached max retires",
+			pr_warn("%s: index(%d) reached max retires",
 				__func__, i);
 		}
 
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/version_b/q6usm_b.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_b/q6usm_b.c
index fe7c8c2..51a51c5 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/version_b/q6usm_b.c
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_b/q6usm_b.c
@@ -628,6 +628,12 @@
 	case FORMAT_USPROX:
 		int_format = US_PROX_FORMAT_V2;
 		break;
+	case FORMAT_USGES_SYNC:
+		int_format = US_GES_SYNC_FORMAT;
+		break;
+	case FORMAT_USRAW_SYNC:
+		int_format = US_RAW_SYNC_FORMAT;
+		break;
 	default:
 		pr_err("%s: Invalid format[%d]\n", __func__, ext_format);
 		break;
diff --git a/arch/arm/mach-msm/rpm_stats.c b/arch/arm/mach-msm/rpm_stats.c
index cb8ed19..1447854 100644
--- a/arch/arm/mach-msm/rpm_stats.c
+++ b/arch/arm/mach-msm/rpm_stats.c
@@ -54,7 +54,7 @@
 	u32 num_records;
 	u32 read_idx;
 	u32 len;
-	char buf[256];
+	char buf[320];
 	struct msm_rpmstats_platform_data *platform_data;
 };
 
@@ -64,7 +64,8 @@
 	u64 last_entered_at;
 	u64 last_exited_at;
 	u64 accumulated;
-	u32 reserved[4];
+	u32 client_votes;
+	u32 reserved[3];
 };
 
 static inline u64 get_time_in_sec(u64 counter)
@@ -98,10 +99,12 @@
 	actual_last_sleep = get_time_in_msec(data->accumulated);
 
 	return  snprintf(buf , buflength,
-		"RPM Mode:%s\n\t count:%d\n time in last mode(msec):%llu\n"
-		"time since last mode(sec):%llu\n actual last sleep(msec):%llu\n",
+		"RPM Mode:%s\n\t count:%d\ntime in last mode(msec):%llu\n"
+		"time since last mode(sec):%llu\nactual last sleep(msec):%llu\n"
+		"client votes: %#010x\n\n",
 		stat_type, data->count, time_in_last_mode,
-		time_since_last_mode, actual_last_sleep);
+		time_since_last_mode, actual_last_sleep,
+		data->client_votes);
 }
 
 static inline u32 msm_rpmstats_read_long_register_v2(void __iomem *regbase,
@@ -147,6 +150,9 @@
 		data.accumulated = msm_rpmstats_read_quad_register_v2(reg,
 				i, offsetof(struct msm_rpm_stats_data_v2,
 					accumulated));
+		data.client_votes = msm_rpmstats_read_long_register_v2(reg,
+				i, offsetof(struct msm_rpm_stats_data_v2,
+					client_votes));
 		length += msm_rpmstats_append_data_to_buf(prvdata->buf + length,
 				&data, sizeof(prvdata->buf) - length);
 		prvdata->read_idx++;
diff --git a/arch/arm/mach-msm/sensors_adsp.c b/arch/arm/mach-msm/sensors_adsp.c
index fab10b8..ad19e16 100644
--- a/arch/arm/mach-msm/sensors_adsp.c
+++ b/arch/arm/mach-msm/sensors_adsp.c
@@ -38,6 +38,7 @@
 #include <mach/msm_bus.h>
 #include <mach/msm_bus_board.h>
 
+#define CLASS_NAME	"ssc"
 #define DRV_NAME	"sensors"
 #define DRV_VERSION	"1.00"
 
@@ -1079,7 +1080,7 @@
 static int sensors_adsp_probe(struct platform_device *pdev)
 {
 	int ret = 0;
-	sns_ctl.dev_class = class_create(THIS_MODULE, DRV_NAME);
+	sns_ctl.dev_class = class_create(THIS_MODULE, CLASS_NAME);
 	if (sns_ctl.dev_class == NULL) {
 		pr_err("%s: class_create fail.\n", __func__);
 		goto res_err;
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index 4b68e66..e7cec58 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -36,7 +36,6 @@
 #define SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE 128
 #define SMEM_IMAGE_VERSION_SIZE 4096
 #define SMEM_IMAGE_VERSION_NAME_SIZE 75
-#define SMEM_IMAGE_VERSION_NAME_OFFSET 3
 #define SMEM_IMAGE_VERSION_VARIANT_SIZE 20
 #define SMEM_IMAGE_VERSION_VARIANT_OFFSET 75
 #define SMEM_IMAGE_VERSION_OEM_SIZE 32
@@ -859,8 +858,7 @@
 		return snprintf(buf, SMEM_IMAGE_VERSION_NAME_SIZE, "Unknown");
 	}
 	string_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
-	string_address += SMEM_IMAGE_VERSION_NAME_OFFSET;
-	return snprintf(buf, SMEM_IMAGE_VERSION_NAME_SIZE, "%-.72s\n",
+	return snprintf(buf, SMEM_IMAGE_VERSION_NAME_SIZE, "%-.75s\n",
 			string_address);
 }
 
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 97b1f39..a5748fb 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -658,13 +658,6 @@
 	  applications DSP processor. Say M if you want to enable this
 	  module.
 
-config MMC_GENERIC_CSDIO
-	tristate "Generic sdio driver"
-	default n
-	help
-	  SDIO function driver that extends SDIO card as character device
-	  in user space.
-
 config CSDIO_VENDOR_ID
 	hex "Card VendorId"
 	depends on MMC_GENERIC_CSDIO
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 7589946..292cc99 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -65,7 +65,6 @@
 
 obj-$(CONFIG_TILE_SROM)		+= tile-srom.o
 obj-$(CONFIG_MSM_ROTATOR)	+= msm_rotator.o
-obj-$(CONFIG_MMC_GENERIC_CSDIO)	+= csdio.o
 obj-$(CONFIG_DIAG_CHAR)		+= diag/
 obj-$(CONFIG_MSM_ADSPRPC)       += adsprpc.o
 obj-$(CONFIG_MSM_RDBG)       += rdbg.o
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 9a9654f..cc8cf47 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -125,16 +125,38 @@
 	return n;
 }
 
+struct fastrpc_buf {
+	struct ion_handle *handle;
+	void *virt;
+	ion_phys_addr_t phys;
+	int size;
+	int used;
+};
+
+struct smq_context_list;
+
 struct smq_invoke_ctx {
+	struct hlist_node hn;
 	struct completion work;
 	int retval;
-	atomic_t free;
+	int pid;
+	remote_arg_t *pra;
+	remote_arg_t *rpra;
+	struct fastrpc_buf obuf;
+	struct fastrpc_buf *abufs;
+	struct fastrpc_device *dev;
+	struct fastrpc_apps *apps;
+	int *fds;
+	struct ion_handle **handles;
+	int nbufs;
+	bool smmu;
+	uint32_t sc;
 };
 
 struct smq_context_list {
-	struct smq_invoke_ctx *ls;
-	int size;
-	int last;
+	struct hlist_head pending;
+	struct hlist_head interrupted;
+	spinlock_t hlock;
 };
 
 struct fastrpc_smmu {
@@ -165,22 +187,16 @@
 	struct hlist_node hn;
 	struct ion_handle *handle;
 	void *virt;
+	ion_phys_addr_t phys;
 	uint32_t vaddrin;
 	uint32_t vaddrout;
 	int size;
 };
 
-struct fastrpc_buf {
-	struct ion_handle *handle;
-	void *virt;
-	ion_phys_addr_t phys;
-	int size;
-	int used;
-};
-
 struct file_data {
 	spinlock_t hlock;
 	struct hlist_head hlst;
+	uint32_t mode;
 };
 
 struct fastrpc_device {
@@ -214,6 +230,11 @@
 {
 	struct fastrpc_apps *me = &gfa;
 	if (!IS_ERR_OR_NULL(map->handle)) {
+		if (me->smmu.enabled && map->phys) {
+			ion_unmap_iommu(me->iclient, map->handle,
+					me->smmu.domain_id, 0);
+			map->phys = 0;
+		}
 		if (!IS_ERR_OR_NULL(map->virt)) {
 			ion_unmap_kernel(me->iclient, map->handle);
 			map->virt = 0;
@@ -263,65 +284,186 @@
 	return err;
 }
 
-static int context_list_ctor(struct smq_context_list *me, int size)
+static int context_restore_interrupted(struct fastrpc_apps *me,
+				struct fastrpc_ioctl_invoke_fd *invokefd,
+				struct smq_invoke_ctx **po)
 {
 	int err = 0;
-	VERIFY(err, 0 != (me->ls = kzalloc(size, GFP_KERNEL)));
-	if (err)
-		goto bail;
-	me->size = size / sizeof(*me->ls);
-	me->last = 0;
- bail:
+	struct smq_invoke_ctx *ctx = 0, *ictx = 0;
+	struct hlist_node *pos, *n;
+	struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
+	spin_lock(&me->clst.hlock);
+	hlist_for_each_entry_safe(ictx, pos, n, &me->clst.interrupted, hn) {
+		if (ictx->pid == current->pid) {
+			if (invoke->sc != ictx->sc)
+				err = -1;
+			else {
+				ctx = ictx;
+				hlist_del(&ctx->hn);
+				hlist_add_head(&ctx->hn, &me->clst.pending);
+			}
+			break;
+		}
+	}
+	spin_unlock(&me->clst.hlock);
+	if (ctx)
+		*po = ctx;
 	return err;
 }
 
-static void context_list_dtor(struct smq_context_list *me)
+static int context_alloc(struct fastrpc_apps *me, uint32_t kernel,
+				struct fastrpc_ioctl_invoke_fd *invokefd,
+				struct smq_invoke_ctx **po)
 {
-	kfree(me->ls);
-}
+	int err = 0, bufs, size = 0;
+	struct smq_invoke_ctx *ctx = 0;
+	struct smq_context_list *clst = &me->clst;
+	struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
 
-static void context_list_alloc_ctx(struct smq_context_list *me,
-					struct smq_invoke_ctx **po)
-{
-	int i = me->last;
-	struct smq_invoke_ctx *ctx;
-
-	for (;;) {
-		i = i % me->size;
-		ctx = &me->ls[i];
-		if (atomic_read(&ctx->free) == 0)
-			if (atomic_cmpxchg(&ctx->free, 0, 1) == 0)
-				break;
-		i++;
+	bufs = REMOTE_SCALARS_INBUFS(invoke->sc) +
+			REMOTE_SCALARS_OUTBUFS(invoke->sc);
+	if (bufs) {
+		size = bufs * sizeof(*ctx->pra);
+		if (invokefd->fds)
+			size = size + bufs * sizeof(*ctx->fds) +
+				bufs * sizeof(*ctx->handles);
 	}
-	me->last = i;
+
+	VERIFY(err, 0 != (ctx = kzalloc(sizeof(*ctx) + size, GFP_KERNEL)));
+	if (err)
+		goto bail;
+
+	INIT_HLIST_NODE(&ctx->hn);
+	ctx->pra = (remote_arg_t *)(&ctx[1]);
+	ctx->fds = invokefd->fds == 0 ? 0 : (int *)(&ctx->pra[bufs]);
+	ctx->handles = invokefd->fds == 0 ? 0 :
+					(struct ion_handle **)(&ctx->fds[bufs]);
+	if (!kernel) {
+		VERIFY(err, 0 == copy_from_user(ctx->pra, invoke->pra,
+					bufs * sizeof(*ctx->pra)));
+		if (err)
+			goto bail;
+	} else {
+		memmove(ctx->pra, invoke->pra, bufs * sizeof(*ctx->pra));
+	}
+
+	if (invokefd->fds) {
+		if (!kernel) {
+			VERIFY(err, 0 == copy_from_user(ctx->fds, invokefd->fds,
+						bufs * sizeof(*ctx->fds)));
+			if (err)
+				goto bail;
+		} else {
+			memmove(ctx->fds, invokefd->fds,
+						bufs * sizeof(*ctx->fds));
+		}
+	}
+	ctx->sc = invoke->sc;
 	ctx->retval = -1;
+	ctx->pid = current->pid;
+	ctx->apps = me;
 	init_completion(&ctx->work);
+	spin_lock(&clst->hlock);
+	hlist_add_head(&ctx->hn, &clst->pending);
+	spin_unlock(&clst->hlock);
+
 	*po = ctx;
+bail:
+	if (ctx && err)
+		kfree(ctx);
+	return err;
 }
 
-static void context_free(struct smq_invoke_ctx *me)
+static void context_save_interrupted(struct smq_invoke_ctx *ctx)
 {
-	if (me)
-		atomic_set(&me->free, 0);
+	struct smq_context_list *clst = &ctx->apps->clst;
+	spin_lock(&clst->hlock);
+	hlist_del(&ctx->hn);
+	hlist_add_head(&ctx->hn, &clst->interrupted);
+	spin_unlock(&clst->hlock);
 }
 
-static void context_notify_user(struct smq_invoke_ctx *me, int retval)
+static void add_dev(struct fastrpc_apps *me, struct fastrpc_device *dev);
+
+static void context_free(struct smq_invoke_ctx *ctx, bool lock)
 {
-	me->retval = retval;
-	complete(&me->work);
+	struct smq_context_list *clst = &ctx->apps->clst;
+	struct fastrpc_apps *apps = ctx->apps;
+	struct ion_client *clnt = apps->iclient;
+	struct fastrpc_smmu *smmu = &apps->smmu;
+	struct fastrpc_buf *b;
+	int i, bufs;
+	if (ctx->smmu) {
+		bufs = REMOTE_SCALARS_INBUFS(ctx->sc) +
+			REMOTE_SCALARS_OUTBUFS(ctx->sc);
+		if (ctx->fds) {
+			for (i = 0; i < bufs; i++)
+				if (!IS_ERR_OR_NULL(ctx->handles[i])) {
+					ion_unmap_iommu(clnt, ctx->handles[i],
+						smmu->domain_id, 0);
+					ion_free(clnt, ctx->handles[i]);
+				}
+		}
+		iommu_detach_group(smmu->domain, smmu->group);
+	}
+	for (i = 0, b = ctx->abufs; i < ctx->nbufs; ++i, ++b)
+		free_mem(b);
+
+	kfree(ctx->abufs);
+	if (ctx->dev) {
+		add_dev(apps, ctx->dev);
+		if (ctx->obuf.handle != ctx->dev->buf.handle)
+			free_mem(&ctx->obuf);
+	}
+	if (lock)
+		spin_lock(&clst->hlock);
+	hlist_del(&ctx->hn);
+	if (lock)
+		spin_unlock(&clst->hlock);
+	kfree(ctx);
+}
+
+static void context_notify_user(struct smq_invoke_ctx *ctx, int retval)
+{
+	ctx->retval = retval;
+	complete(&ctx->work);
 }
 
 static void context_notify_all_users(struct smq_context_list *me)
 {
-	int i;
-
-	if (!me->ls)
-		return;
-	for (i = 0; i < me->size; ++i) {
-		if (atomic_read(&me->ls[i].free) != 0)
-			complete(&me->ls[i].work);
+	struct smq_invoke_ctx *ictx = 0;
+	struct hlist_node *pos, *n;
+	spin_lock(&me->hlock);
+	hlist_for_each_entry_safe(ictx, pos, n, &me->pending, hn) {
+		complete(&ictx->work);
 	}
+	hlist_for_each_entry_safe(ictx, pos, n, &me->interrupted, hn) {
+		complete(&ictx->work);
+	}
+	spin_unlock(&me->hlock);
+
+}
+
+static void context_list_ctor(struct smq_context_list *me)
+{
+	INIT_HLIST_HEAD(&me->interrupted);
+	INIT_HLIST_HEAD(&me->pending);
+	spin_lock_init(&me->hlock);
+}
+
+static void context_list_dtor(struct fastrpc_apps *me,
+				struct smq_context_list *clst)
+{
+	struct smq_invoke_ctx *ictx = 0;
+	struct hlist_node *pos, *n;
+	spin_lock(&clst->hlock);
+	hlist_for_each_entry_safe(ictx, pos, n, &clst->interrupted, hn) {
+		context_free(ictx, 0);
+	}
+	hlist_for_each_entry_safe(ictx, pos, n, &clst->pending, hn) {
+		context_free(ictx, 0);
+	}
+	spin_unlock(&clst->hlock);
 }
 
 static int get_page_list(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
@@ -400,13 +542,12 @@
 static int get_args(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
 			remote_arg_t *rpra, remote_arg_t *upra,
 			struct fastrpc_buf *ibuf, struct fastrpc_buf **abufs,
-			int *nbufs, int *fds)
+			int *nbufs, int *fds, struct ion_handle **handles)
 {
 	struct fastrpc_apps *me = &gfa;
 	struct smq_invoke_buf *list;
 	struct fastrpc_buf *pbuf = ibuf, *obufs = 0;
 	struct smq_phy_page *pages;
-	struct ion_handle **handles = NULL;
 	void *args;
 	int i, rlen, size, used, inh, bufs = 0, err = 0;
 	int inbufs = REMOTE_SCALARS_INBUFS(sc);
@@ -418,8 +559,6 @@
 	used = ALIGN(pbuf->used, BALIGN);
 	args = (void *)((char *)pbuf->virt + used);
 	rlen = pbuf->size - used;
-	if (fds)
-		handles = (struct ion_handle **)(fds + inbufs + outbufs);
 	for (i = 0; i < inbufs + outbufs; ++i) {
 
 		rpra[i].buf.len = pra[i].buf.len;
@@ -614,7 +753,6 @@
 	struct fastrpc_apps *me = &gfa;
 
 	smd_close(me->chan);
-	context_list_dtor(&me->clst);
 	ion_client_destroy(me->iclient);
 	me->iclient = 0;
 	me->chan = 0;
@@ -667,16 +805,14 @@
 		spin_lock_init(&me->wrlock);
 		init_completion(&me->work);
 		mutex_init(&me->smd_mutex);
+		context_list_ctor(&me->clst);
 		for (i = 0; i < RPC_HASH_SZ; ++i)
 			INIT_HLIST_HEAD(&me->htbl[i]);
-		VERIFY(err, 0 == context_list_ctor(&me->clst, SZ_4K));
-		if (err)
-			goto context_list_bail;
 		me->iclient = msm_ion_client_create(ION_HEAP_CARVEOUT_MASK,
 							DEVICE_NAME);
 		VERIFY(err, 0 == IS_ERR_OR_NULL(me->iclient));
 		if (err)
-			goto ion_bail;
+			goto bail;
 		node = of_find_compatible_node(NULL, NULL,
 						"qcom,msm-audio-ion");
 		if (node)
@@ -697,9 +833,7 @@
 
 	return 0;
 
-ion_bail:
-	context_list_dtor(&me->clst);
-context_list_bail:
+bail:
 	return err;
 }
 
@@ -783,96 +917,88 @@
 
 static int fastrpc_release_current_dsp_process(void);
 
-static int fastrpc_internal_invoke(struct fastrpc_apps *me, uint32_t kernel,
-			struct fastrpc_ioctl_invoke *invoke, remote_arg_t *pra,
-			int *fds)
+static int fastrpc_internal_invoke(struct fastrpc_apps *me, uint32_t mode,
+			uint32_t kernel,
+			struct fastrpc_ioctl_invoke_fd *invokefd)
 {
-	remote_arg_t *rpra = 0;
-	struct fastrpc_device *dev = 0;
 	struct smq_invoke_ctx *ctx = 0;
-	struct fastrpc_buf obuf, *abufs = 0, *b;
-	struct ion_handle **handles = NULL;
+	struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
 	int interrupted = 0;
-	uint32_t sc;
-	int i, bufs, nbufs = 0, err = 0;
+	int err = 0;
 
-	sc = invoke->sc;
-	obuf.handle = 0;
+	if (!kernel) {
+		VERIFY(err, 0 == context_restore_interrupted(me, invokefd,
+								&ctx));
+		if (err)
+			goto bail;
+		if (ctx)
+			goto wait;
+	}
+
+	VERIFY(err, 0 == context_alloc(me, kernel, invokefd, &ctx));
+	if (err)
+		goto bail;
+
 	if (me->smmu.enabled) {
 		VERIFY(err, 0 == iommu_attach_group(me->smmu.domain,
 							me->smmu.group));
 		if (err)
-			return err;
+			goto bail;
+		ctx->smmu = 1;
 	}
-	if (REMOTE_SCALARS_LENGTH(sc)) {
-		VERIFY(err, 0 == get_dev(me, &dev));
+	if (REMOTE_SCALARS_LENGTH(ctx->sc)) {
+		VERIFY(err, 0 == get_dev(me, &ctx->dev));
 		if (err)
 			goto bail;
-		VERIFY(err, 0 == get_page_list(kernel, sc, pra, &dev->buf,
-						&obuf));
+		VERIFY(err, 0 == get_page_list(kernel, ctx->sc, ctx->pra,
+					&ctx->dev->buf, &ctx->obuf));
 		if (err)
 			goto bail;
-		rpra = (remote_arg_t *)obuf.virt;
-		VERIFY(err, 0 == get_args(kernel, sc, pra, rpra, invoke->pra,
-					&obuf, &abufs, &nbufs, fds));
+		ctx->rpra = (remote_arg_t *)ctx->obuf.virt;
+		VERIFY(err, 0 == get_args(kernel, ctx->sc, ctx->pra, ctx->rpra,
+				invoke->pra, &ctx->obuf, &ctx->abufs,
+				&ctx->nbufs, ctx->fds, ctx->handles));
 		if (err)
 			goto bail;
 	}
 
-	context_list_alloc_ctx(&me->clst, &ctx);
-	inv_args_pre(sc, rpra);
-	VERIFY(err, 0 == fastrpc_invoke_send(me, kernel, invoke->handle, sc,
-						ctx, &obuf));
+	inv_args_pre(ctx->sc, ctx->rpra);
+	if (FASTRPC_MODE_SERIAL == mode)
+		inv_args(ctx->sc, ctx->rpra, ctx->obuf.used);
+	VERIFY(err, 0 == fastrpc_invoke_send(me, kernel, invoke->handle,
+						ctx->sc, ctx, &ctx->obuf));
 	if (err)
 		goto bail;
-	inv_args(sc, rpra, obuf.used);
-	VERIFY(err, 0 == (interrupted =
-			wait_for_completion_interruptible(&ctx->work)));
-	if (err)
-		goto bail;
+	if (FASTRPC_MODE_PARALLEL == mode)
+		inv_args(ctx->sc, ctx->rpra, ctx->obuf.used);
+ wait:
+	if (kernel)
+		wait_for_completion(&ctx->work);
+	else {
+		interrupted = wait_for_completion_interruptible(&ctx->work);
+		VERIFY(err, 0 == (err = interrupted));
+		if (err)
+			goto bail;
+	}
 	VERIFY(err, 0 == (err = ctx->retval));
 	if (err)
 		goto bail;
-	VERIFY(err, 0 == put_args(kernel, sc, pra, rpra, invoke->pra));
+	VERIFY(err, 0 == put_args(kernel, ctx->sc, ctx->pra, ctx->rpra,
+					invoke->pra));
 	if (err)
 		goto bail;
  bail:
-	if (interrupted) {
-		if (!kernel)
-			(void)fastrpc_release_current_dsp_process();
-		wait_for_completion(&ctx->work);
-	}
-	context_free(ctx);
-
-	if (me->smmu.enabled) {
-		bufs = REMOTE_SCALARS_INBUFS(sc) + REMOTE_SCALARS_OUTBUFS(sc);
-		if (fds) {
-			handles = (struct ion_handle **)(fds + bufs);
-			for (i = 0; i < bufs; i++)
-				if (!IS_ERR_OR_NULL(handles[i])) {
-					ion_unmap_iommu(me->iclient, handles[i],
-							me->smmu.domain_id, 0);
-					ion_free(me->iclient, handles[i]);
-				}
-		}
-		iommu_detach_group(me->smmu.domain, me->smmu.group);
-	}
-	for (i = 0, b = abufs; i < nbufs; ++i, ++b)
-		free_mem(b);
-
-	kfree(abufs);
-	if (dev) {
-		add_dev(me, dev);
-		if (obuf.handle != dev->buf.handle)
-			free_mem(&obuf);
-	}
+	if (ctx && interrupted == -ERESTARTSYS)
+		context_save_interrupted(ctx);
+	else if (ctx)
+		context_free(ctx, 1);
 	return err;
 }
 
 static int fastrpc_create_current_dsp_process(void)
 {
 	int err = 0;
-	struct fastrpc_ioctl_invoke ioctl;
+	struct fastrpc_ioctl_invoke_fd ioctl;
 	struct fastrpc_apps *me = &gfa;
 	remote_arg_t ra[1];
 	int tgid = 0;
@@ -880,10 +1006,12 @@
 	tgid = current->tgid;
 	ra[0].buf.pv = &tgid;
 	ra[0].buf.len = sizeof(tgid);
-	ioctl.handle = 1;
-	ioctl.sc = REMOTE_SCALARS_MAKE(0, 1, 0);
-	ioctl.pra = ra;
-	VERIFY(err, 0 == (err = fastrpc_internal_invoke(me, 1, &ioctl, ra, 0)));
+	ioctl.inv.handle = 1;
+	ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 0);
+	ioctl.inv.pra = ra;
+	ioctl.fds = 0;
+	VERIFY(err, 0 == (err = fastrpc_internal_invoke(me,
+		FASTRPC_MODE_PARALLEL, 1, &ioctl)));
 	return err;
 }
 
@@ -891,17 +1019,19 @@
 {
 	int err = 0;
 	struct fastrpc_apps *me = &gfa;
-	struct fastrpc_ioctl_invoke ioctl;
+	struct fastrpc_ioctl_invoke_fd ioctl;
 	remote_arg_t ra[1];
 	int tgid = 0;
 
 	tgid = current->tgid;
 	ra[0].buf.pv = &tgid;
 	ra[0].buf.len = sizeof(tgid);
-	ioctl.handle = 1;
-	ioctl.sc = REMOTE_SCALARS_MAKE(1, 1, 0);
-	ioctl.pra = ra;
-	VERIFY(err, 0 == (err = fastrpc_internal_invoke(me, 1, &ioctl, ra, 0)));
+	ioctl.inv.handle = 1;
+	ioctl.inv.sc = REMOTE_SCALARS_MAKE(1, 1, 0);
+	ioctl.inv.pra = ra;
+	ioctl.fds = 0;
+	VERIFY(err, 0 == (err = fastrpc_internal_invoke(me,
+		FASTRPC_MODE_PARALLEL, 1, &ioctl)));
 	return err;
 }
 
@@ -910,7 +1040,7 @@
 					 struct smq_phy_page *pages,
 					 int num)
 {
-	struct fastrpc_ioctl_invoke ioctl;
+	struct fastrpc_ioctl_invoke_fd ioctl;
 	remote_arg_t ra[3];
 	int err = 0;
 	struct {
@@ -936,10 +1066,12 @@
 	ra[2].buf.pv = &routargs;
 	ra[2].buf.len = sizeof(routargs);
 
-	ioctl.handle = 1;
-	ioctl.sc = REMOTE_SCALARS_MAKE(2, 2, 1);
-	ioctl.pra = ra;
-	VERIFY(err, 0 == (err = fastrpc_internal_invoke(me, 1, &ioctl, ra, 0)));
+	ioctl.inv.handle = 1;
+	ioctl.inv.sc = REMOTE_SCALARS_MAKE(2, 2, 1);
+	ioctl.inv.pra = ra;
+	ioctl.fds = 0;
+	VERIFY(err, 0 == (err = fastrpc_internal_invoke(me,
+		FASTRPC_MODE_PARALLEL, 1, &ioctl)));
 	mmap->vaddrout = routargs.vaddrout;
 	if (err)
 		goto bail;
@@ -950,7 +1082,7 @@
 static int fastrpc_munmap_on_dsp(struct fastrpc_apps *me,
 				 struct fastrpc_ioctl_munmap *munmap)
 {
-	struct fastrpc_ioctl_invoke ioctl;
+	struct fastrpc_ioctl_invoke_fd ioctl;
 	remote_arg_t ra[1];
 	int err = 0;
 	struct {
@@ -965,10 +1097,12 @@
 	ra[0].buf.pv = &inargs;
 	ra[0].buf.len = sizeof(inargs);
 
-	ioctl.handle = 1;
-	ioctl.sc = REMOTE_SCALARS_MAKE(3, 1, 0);
-	ioctl.pra = ra;
-	VERIFY(err, 0 == (err = fastrpc_internal_invoke(me, 1, &ioctl, ra, 0)));
+	ioctl.inv.handle = 1;
+	ioctl.inv.sc = REMOTE_SCALARS_MAKE(3, 1, 0);
+	ioctl.inv.pra = ra;
+	ioctl.fds = 0;
+	VERIFY(err, 0 == (err = fastrpc_internal_invoke(me,
+		FASTRPC_MODE_PARALLEL, 1, &ioctl)));
 	return err;
 }
 
@@ -1010,7 +1144,7 @@
 	struct fastrpc_mmap *map = 0;
 	struct smq_phy_page *pages = 0;
 	void *buf;
-	int len;
+	unsigned long len;
 	int num;
 	int err = 0;
 
@@ -1031,9 +1165,22 @@
 	VERIFY(err, 0 != (pages = kzalloc(num * sizeof(*pages), GFP_KERNEL)));
 	if (err)
 		goto bail;
-	VERIFY(err, 0 < (num = buf_get_pages(buf, len, num, 1, pages, num)));
-	if (err)
-		goto bail;
+
+	if (me->smmu.enabled) {
+		VERIFY(err, 0 == ion_map_iommu(clnt, map->handle,
+				me->smmu.domain_id, 0,
+				SZ_4K, 0, &map->phys, &len, 0, 0));
+		if (err)
+			goto bail;
+		pages->addr = map->phys;
+		pages->size = len;
+		num = 1;
+	} else {
+		VERIFY(err, 0 < (num = buf_get_pages(buf, len, num, 1,
+							pages, num)));
+		if (err)
+			goto bail;
+	}
 
 	VERIFY(err, 0 == fastrpc_mmap_on_dsp(me, mmap, pages, num));
 	if (err)
@@ -1100,7 +1247,7 @@
 	(void)fastrpc_release_current_dsp_process();
 	cleanup_current_dev();
 	if (fdata) {
-		struct fastrpc_mmap *map;
+		struct fastrpc_mmap *map = 0;
 		struct hlist_node *n, *pos;
 		file->private_data = 0;
 		hlist_for_each_entry_safe(map, pos, n, &fdata->hlst, hn) {
@@ -1179,48 +1326,23 @@
 {
 	struct fastrpc_apps *me = &gfa;
 	struct fastrpc_ioctl_invoke_fd invokefd;
-	struct fastrpc_ioctl_invoke *invoke = &invokefd.inv;
 	struct fastrpc_ioctl_mmap mmap;
 	struct fastrpc_ioctl_munmap munmap;
-	remote_arg_t *pra = 0;
 	void *param = (char *)ioctl_param;
 	struct file_data *fdata = (struct file_data *)file->private_data;
-	int *fds = 0;
-	int bufs, size = 0, err = 0;
+	int size = 0, err = 0;
 
 	switch (ioctl_num) {
 	case FASTRPC_IOCTL_INVOKE_FD:
 	case FASTRPC_IOCTL_INVOKE:
 		invokefd.fds = 0;
 		size = (ioctl_num == FASTRPC_IOCTL_INVOKE) ?
-				sizeof(*invoke) : sizeof(invokefd);
+				sizeof(invokefd.inv) : sizeof(invokefd);
 		VERIFY(err, 0 == copy_from_user(&invokefd, param, size));
 		if (err)
 			goto bail;
-		bufs = REMOTE_SCALARS_INBUFS(invoke->sc) +
-			REMOTE_SCALARS_OUTBUFS(invoke->sc);
-		if (bufs) {
-			size = bufs * sizeof(*pra);
-			if (invokefd.fds)
-				size = size + bufs * sizeof(*fds) +
-					bufs * sizeof(struct ion_handle *);
-			VERIFY(err, 0 != (pra = kzalloc(size, GFP_KERNEL)));
-			if (err)
-				goto bail;
-		}
-		VERIFY(err, 0 == copy_from_user(pra, invoke->pra,
-						bufs * sizeof(*pra)));
-		if (err)
-			goto bail;
-		if (invokefd.fds) {
-			fds = (int *)(pra + bufs);
-			VERIFY(err, 0 == copy_from_user(fds, invokefd.fds,
-							bufs * sizeof(*fds)));
-		if (err)
-			goto bail;
-		}
-		VERIFY(err, 0 == (err = fastrpc_internal_invoke(me, 0, invoke,
-								pra, fds)));
+		VERIFY(err, 0 == (err = fastrpc_internal_invoke(me, fdata->mode,
+						0, &invokefd)));
 		if (err)
 			goto bail;
 		break;
@@ -1247,12 +1369,22 @@
 		if (err)
 			goto bail;
 		break;
+	case FASTRPC_IOCTL_SETMODE:
+		switch ((uint32_t)ioctl_param) {
+		case FASTRPC_MODE_PARALLEL:
+		case FASTRPC_MODE_SERIAL:
+			fdata->mode = (uint32_t)ioctl_param;
+			break;
+		default:
+			err = -ENOTTY;
+			break;
+		}
+		break;
 	default:
 		err = -ENOTTY;
 		break;
 	}
  bail:
-	kfree(pra);
 	return err;
 }
 
@@ -1279,7 +1411,7 @@
 	VERIFY(err, 0 == cdev_add(&me->cdev, MKDEV(MAJOR(me->dev_no), 0), 1));
 	if (err)
 		goto cdev_init_bail;
-	me->class = class_create(THIS_MODULE, "chardrv");
+	me->class = class_create(THIS_MODULE, "fastrpc");
 	VERIFY(err, !IS_ERR(me->class));
 	if (err)
 		goto class_create_bail;
@@ -1307,7 +1439,9 @@
 {
 	struct fastrpc_apps *me = &gfa;
 
+	context_list_dtor(me, &me->clst);
 	fastrpc_deinit();
+	cleanup_current_dev();
 	device_destroy(me->class, MKDEV(MAJOR(me->dev_no), 0));
 	class_destroy(me->class);
 	cdev_del(&me->cdev);
diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h
index da70eb5..f5d7450 100644
--- a/drivers/char/adsprpc_shared.h
+++ b/drivers/char/adsprpc_shared.h
@@ -20,9 +20,16 @@
 #define FASTRPC_IOCTL_MMAP    _IOWR('R', 2, struct fastrpc_ioctl_mmap)
 #define FASTRPC_IOCTL_MUNMAP  _IOWR('R', 3, struct fastrpc_ioctl_munmap)
 #define FASTRPC_IOCTL_INVOKE_FD  _IOWR('R', 4, struct fastrpc_ioctl_invoke_fd)
+#define FASTRPC_IOCTL_SETMODE    _IOWR('R', 5, uint32_t)
 #define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp"
 #define DEVICE_NAME      "adsprpc-smd"
 
+/* Driver should operate in parallel with the co-processor */
+#define FASTRPC_MODE_PARALLEL    0
+
+/* Driver should operate in serial mode with the co-processor */
+#define FASTRPC_MODE_SERIAL      1
+
 /* Retrives number of input buffers from the scalars parameter */
 #define REMOTE_SCALARS_INBUFS(sc)        (((sc) >> 16) & 0x0ff)
 
diff --git a/drivers/char/csdio.c b/drivers/char/csdio.c
deleted file mode 100644
index 85306d3..0000000
--- a/drivers/char/csdio.c
+++ /dev/null
@@ -1,1074 +0,0 @@
-/*
- * Copyright (c) 2010, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/mutex.h>
-#include <linux/serial_reg.h>
-#include <linux/circ_buf.h>
-#include <linux/gfp.h>
-#include <linux/uaccess.h>
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-
-/* Char device */
-#include <linux/cdev.h>
-#include <linux/fs.h>
-
-/* Sdio device */
-#include <linux/mmc/core.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/card.h>
-#include <linux/mmc/sdio.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio_ids.h>
-
-#include <linux/csdio.h>
-
-#define FALSE   0
-#define TRUE    1
-
-#define VERSION                     "0.5"
-#define CSDIO_NUM_OF_SDIO_FUNCTIONS 7
-#define CSDIO_DEV_NAME              "csdio"
-#define TP_DEV_NAME                 CSDIO_DEV_NAME"f"
-#define CSDIO_DEV_PERMISSIONS       0666
-
-#define CSDIO_SDIO_BUFFER_SIZE      (64*512)
-
-int csdio_major;
-int csdio_minor;
-int csdio_transport_nr_devs = CSDIO_NUM_OF_SDIO_FUNCTIONS;
-static uint csdio_vendor_id;
-static uint csdio_device_id;
-static char *host_name;
-
-static struct csdio_func_t {
-	struct sdio_func   *m_func;
-	int                 m_enabled;
-	struct cdev         m_cdev;      /* char device structure */
-	struct device      *m_device;
-	u32                 m_block_size;
-} *g_csdio_func_table[CSDIO_NUM_OF_SDIO_FUNCTIONS] = {0};
-
-struct csdio_t {
-	struct cdev             m_cdev;
-	struct device          *m_device;
-	struct class           *m_driver_class;
-	struct fasync_struct   *m_async_queue;
-	unsigned char           m_current_irq_mask; /* currently enabled irqs */
-	struct mmc_host        *m_host;
-	unsigned int            m_num_of_func;
-} g_csdio;
-
-struct csdio_file_descriptor {
-	struct csdio_func_t    *m_port;
-	u32                     m_block_mode;/* data tran. byte(0)/block(1) */
-	u32                     m_op_code;   /* address auto increment flag */
-	u32                     m_address;
-};
-
-static void *g_sdio_buffer;
-
-/*
- * Open and release
- */
-static int csdio_transport_open(struct inode *inode, struct file *filp)
-{
-	int ret = 0;
-	struct csdio_func_t *port = NULL; /*  device information */
-	struct sdio_func *func = NULL;
-	struct csdio_file_descriptor *descriptor = NULL;
-
-	port = container_of(inode->i_cdev, struct csdio_func_t, m_cdev);
-	func = port->m_func;
-	descriptor = kzalloc(sizeof(struct csdio_file_descriptor), GFP_KERNEL);
-	if (!descriptor) {
-		ret = -ENOMEM;
-		goto exit;
-	}
-
-	pr_info(TP_DEV_NAME"%d: open: func=%p, port=%p\n",
-			func->num, func, port);
-	sdio_claim_host(func);
-	ret = sdio_enable_func(func);
-	if (ret) {
-		pr_err(TP_DEV_NAME"%d:Enable func failed (%d)\n",
-				func->num, ret);
-		ret = -EIO;
-		goto free_descriptor;
-	}
-	descriptor->m_port = port;
-	filp->private_data = descriptor;
-	goto release_host;
-
-free_descriptor:
-	kfree(descriptor);
-release_host:
-	sdio_release_host(func);
-exit:
-	return ret;
-}
-
-static int csdio_transport_release(struct inode *inode, struct file *filp)
-{
-	int ret = 0;
-	struct csdio_file_descriptor *descriptor = filp->private_data;
-	struct csdio_func_t *port = descriptor->m_port;
-	struct sdio_func *func = port->m_func;
-
-	pr_info(TP_DEV_NAME"%d: release\n", func->num);
-	sdio_claim_host(func);
-	ret = sdio_disable_func(func);
-	if (ret) {
-		pr_err(TP_DEV_NAME"%d:Disable func failed(%d)\n",
-				func->num, ret);
-		ret = -EIO;
-	}
-	sdio_release_host(func);
-	kfree(descriptor);
-	return ret;
-}
-
-/*
- * Data management: read and write
- */
-static ssize_t csdio_transport_read(struct file *filp,
-		char __user *buf,
-		size_t count,
-		loff_t *f_pos)
-{
-	ssize_t ret = 0;
-	struct csdio_file_descriptor *descriptor = filp->private_data;
-	struct csdio_func_t *port = descriptor->m_port;
-	struct sdio_func *func = port->m_func;
-	size_t t_count = count;
-
-	if (descriptor->m_block_mode) {
-		pr_info(TP_DEV_NAME "%d: CMD53 read, Md:%d, Addr:0x%04X,"
-				" Un:%d (Bl:%d, BlSz:%d)\n", func->num,
-				descriptor->m_block_mode,
-				descriptor->m_address,
-				count*port->m_block_size,
-				count, port->m_block_size);
-		/* recalculate size */
-		count *= port->m_block_size;
-	}
-	sdio_claim_host(func);
-	if (descriptor->m_op_code) {
-		/* auto increment */
-		ret = sdio_memcpy_fromio(func, g_sdio_buffer,
-				descriptor->m_address, count);
-	} else { /* FIFO */
-		ret = sdio_readsb(func, g_sdio_buffer,
-				descriptor->m_address, count);
-	}
-	sdio_release_host(func);
-	if (!ret) {
-		if (copy_to_user(buf, g_sdio_buffer, count))
-			ret = -EFAULT;
-		else
-			ret = t_count;
-	}
-	if (ret < 0) {
-		pr_err(TP_DEV_NAME "%d: CMD53 read failed (%d)"
-				"(Md:%d, Addr:0x%04X, Sz:%d)\n",
-				func->num, ret,
-				descriptor->m_block_mode,
-				descriptor->m_address, count);
-	}
-	return ret;
-}
-
-static ssize_t csdio_transport_write(struct file *filp,
-		const char __user *buf,
-		size_t count,
-		loff_t *f_pos)
-{
-	ssize_t ret = 0;
-	struct csdio_file_descriptor *descriptor = filp->private_data;
-	struct csdio_func_t *port = descriptor->m_port;
-	struct sdio_func *func = port->m_func;
-	size_t t_count = count;
-
-	if (descriptor->m_block_mode)
-		count *= port->m_block_size;
-
-	if (copy_from_user(g_sdio_buffer, buf, count)) {
-		pr_err(TP_DEV_NAME"%d:copy_from_user failed\n", func->num);
-		ret = -EFAULT;
-	} else {
-		sdio_claim_host(func);
-		if (descriptor->m_op_code) {
-			/* auto increment */
-			ret = sdio_memcpy_toio(func, descriptor->m_address,
-					g_sdio_buffer, count);
-		} else {
-			/* FIFO */
-			ret = sdio_writesb(func, descriptor->m_address,
-					g_sdio_buffer, count);
-		}
-		sdio_release_host(func);
-		if (!ret) {
-			ret = t_count;
-		} else {
-			pr_err(TP_DEV_NAME "%d: CMD53 write failed (%d)"
-				"(Md:%d, Addr:0x%04X, Sz:%d)\n",
-				func->num, ret, descriptor->m_block_mode,
-				descriptor->m_address, count);
-		}
-	}
-	return ret;
-}
-
-/* disable interrupt for sdio client */
-static int disable_sdio_client_isr(struct sdio_func *func)
-{
-	int ret;
-
-	/* disable for all functions, to restore interrupts
-	 * use g_csdio.m_current_irq_mask */
-	sdio_f0_writeb(func, 0, SDIO_CCCR_IENx, &ret);
-	if (ret)
-		pr_err(CSDIO_DEV_NAME" Can't sdio_f0_writeb (%d)\n", ret);
-
-	return ret;
-}
-
-/*
- * This handles the interrupt from SDIO.
- */
-static void csdio_sdio_irq(struct sdio_func *func)
-{
-	int ret;
-
-	pr_info(CSDIO_DEV_NAME" csdio_sdio_irq: func=%d\n", func->num);
-	ret = disable_sdio_client_isr(func);
-	if (ret) {
-		pr_err(CSDIO_DEV_NAME" Can't disable client isr(%d)\n", ret);
-		return;
-	}
-	/*  signal asynchronous readers */
-	if (g_csdio.m_async_queue)
-		kill_fasync(&g_csdio.m_async_queue, SIGIO, POLL_IN);
-}
-
-/*
- * The ioctl() implementation
- */
-static int csdio_transport_ioctl(struct inode *inode,
-		struct file *filp,
-		unsigned int cmd,
-		unsigned long arg)
-{
-	int err = 0;
-	int ret = 0;
-	struct csdio_file_descriptor *descriptor = filp->private_data;
-	struct csdio_func_t *port = descriptor->m_port;
-	struct sdio_func *func = port->m_func;
-
-	/*  extract the type and number bitfields
-	    sanity check: return ENOTTY (inappropriate ioctl) before
-	    access_ok()
-	*/
-	if ((_IOC_TYPE(cmd) != CSDIO_IOC_MAGIC) ||
-			(_IOC_NR(cmd) > CSDIO_IOC_MAXNR)) {
-		pr_err(TP_DEV_NAME "Wrong ioctl command parameters\n");
-		ret = -ENOTTY;
-		goto exit;
-	}
-
-	/*  the direction is a bitmask, and VERIFY_WRITE catches R/W
-	 *  transfers. `Type' is user-oriented, while access_ok is
-	    kernel-oriented, so the concept of "read" and "write" is reversed
-	*/
-	if (_IOC_DIR(cmd) & _IOC_READ) {
-		err = !access_ok(VERIFY_WRITE, (void __user *)arg,
-				_IOC_SIZE(cmd));
-	} else {
-		if (_IOC_DIR(cmd) & _IOC_WRITE) {
-			err =  !access_ok(VERIFY_READ, (void __user *)arg,
-					_IOC_SIZE(cmd));
-		}
-	}
-	if (err) {
-		pr_err(TP_DEV_NAME "Wrong ioctl access direction\n");
-		ret = -EFAULT;
-		goto exit;
-	}
-
-	switch (cmd) {
-	case CSDIO_IOC_SET_OP_CODE:
-		{
-			pr_info(TP_DEV_NAME"%d:SET_OP_CODE=%d\n",
-					func->num, descriptor->m_op_code);
-			ret = get_user(descriptor->m_op_code,
-					(unsigned char __user *)arg);
-			if (ret) {
-				pr_err(TP_DEV_NAME"%d:SET_OP_CODE get data"
-						" from user space failed(%d)\n",
-						func->num, ret);
-				ret = -ENOTTY;
-				break;
-			}
-		}
-		break;
-	case CSDIO_IOC_FUNCTION_SET_BLOCK_SIZE:
-		{
-			unsigned block_size;
-
-			ret = get_user(block_size, (unsigned __user *)arg);
-			if (ret) {
-				pr_err(TP_DEV_NAME"%d:SET_BLOCK_SIZE get data"
-						" from user space failed(%d)\n",
-						func->num, ret);
-				ret = -ENOTTY;
-				break;
-			}
-			pr_info(TP_DEV_NAME"%d:SET_BLOCK_SIZE=%d\n",
-					func->num, block_size);
-			sdio_claim_host(func);
-			ret = sdio_set_block_size(func, block_size);
-			if (!ret) {
-				port->m_block_size = block_size;
-			} else {
-				pr_err(TP_DEV_NAME"%d:SET_BLOCK_SIZE set block"
-						" size to %d failed (%d)\n",
-						func->num, block_size, ret);
-				ret = -ENOTTY;
-				break;
-			}
-			sdio_release_host(func);
-		}
-		break;
-	case CSDIO_IOC_SET_BLOCK_MODE:
-		{
-			pr_info(TP_DEV_NAME"%d:SET_BLOCK_MODE=%d\n",
-					func->num, descriptor->m_block_mode);
-			ret = get_user(descriptor->m_block_mode,
-					(unsigned char __user *)arg);
-			if (ret) {
-				pr_err(TP_DEV_NAME"%d:SET_BLOCK_MODE get data"
-						" from user space failed\n",
-						func->num);
-				ret = -ENOTTY;
-				break;
-			}
-		}
-		break;
-	case CSDIO_IOC_CMD52:
-		{
-			struct csdio_cmd52_ctrl_t cmd52ctrl;
-			int cmd52ret;
-
-			if (copy_from_user(&cmd52ctrl,
-					(const unsigned char __user *)arg,
-					sizeof(cmd52ctrl))) {
-				pr_err(TP_DEV_NAME"%d:IOC_CMD52 get data"
-						" from user space failed\n",
-						func->num);
-				ret = -ENOTTY;
-				break;
-			}
-			sdio_claim_host(func);
-			if (cmd52ctrl.m_write)
-				sdio_writeb(func, cmd52ctrl.m_data,
-						cmd52ctrl.m_address, &cmd52ret);
-			else
-				cmd52ctrl.m_data = sdio_readb(func,
-						cmd52ctrl.m_address, &cmd52ret);
-
-			cmd52ctrl.m_ret = cmd52ret;
-			sdio_release_host(func);
-			if (cmd52ctrl.m_ret)
-				pr_err(TP_DEV_NAME"%d:IOC_CMD52 failed (%d)\n",
-						func->num, cmd52ctrl.m_ret);
-
-			if (copy_to_user((unsigned char __user *)arg,
-						&cmd52ctrl,
-						sizeof(cmd52ctrl))) {
-				pr_err(TP_DEV_NAME"%d:IOC_CMD52 put data"
-						" to user space failed\n",
-						func->num);
-				ret = -ENOTTY;
-				break;
-			}
-		}
-		break;
-	case CSDIO_IOC_CMD53:
-		{
-			struct csdio_cmd53_ctrl_t csdio_cmd53_ctrl;
-
-			if (copy_from_user(&csdio_cmd53_ctrl,
-						(const char __user *)arg,
-						sizeof(csdio_cmd53_ctrl))) {
-				ret = -EPERM;
-				pr_err(TP_DEV_NAME"%d:"
-					"Get data from user space failed\n",
-					func->num);
-				break;
-			}
-			descriptor->m_block_mode =
-				csdio_cmd53_ctrl.m_block_mode;
-			descriptor->m_op_code = csdio_cmd53_ctrl.m_op_code;
-			descriptor->m_address = csdio_cmd53_ctrl.m_address;
-		}
-		break;
-	case CSDIO_IOC_CONNECT_ISR:
-		{
-			pr_info(CSDIO_DEV_NAME" SDIO_CONNECT_ISR"
-				" func=%d, csdio_sdio_irq=%x\n",
-				func->num, (unsigned int)csdio_sdio_irq);
-			sdio_claim_host(func);
-			ret = sdio_claim_irq(func, csdio_sdio_irq);
-			sdio_release_host(func);
-			if (ret) {
-				pr_err(CSDIO_DEV_NAME" SDIO_CONNECT_ISR"
-						" claim irq failed(%d)\n", ret);
-			} else {
-				/* update current irq mask for disable/enable */
-				g_csdio.m_current_irq_mask |= (1 << func->num);
-			}
-		}
-		break;
-	case CSDIO_IOC_DISCONNECT_ISR:
-		{
-			pr_info(CSDIO_DEV_NAME " SDIO_DISCONNECT_ISR func=%d\n",
-					func->num);
-			sdio_claim_host(func);
-			sdio_release_irq(func);
-			sdio_release_host(func);
-			/* update current irq mask for disable/enable */
-			g_csdio.m_current_irq_mask &= ~(1 << func->num);
-		}
-		break;
-	default:  /*  redundant, as cmd was checked against MAXNR */
-		pr_warning(TP_DEV_NAME"%d: Redundant IOCTL\n",
-				func->num);
-		ret = -ENOTTY;
-	}
-exit:
-	return ret;
-}
-
-static const struct file_operations csdio_transport_fops = {
-	.owner =    THIS_MODULE,
-	.read =     csdio_transport_read,
-	.write =    csdio_transport_write,
-	.ioctl =    csdio_transport_ioctl,
-	.open =     csdio_transport_open,
-	.release =  csdio_transport_release,
-};
-
-static void csdio_transport_cleanup(struct csdio_func_t *port)
-{
-	int devno = MKDEV(csdio_major, csdio_minor + port->m_func->num);
-	device_destroy(g_csdio.m_driver_class, devno);
-	port->m_device = NULL;
-	cdev_del(&port->m_cdev);
-}
-
-#if defined(CONFIG_DEVTMPFS)
-static inline int csdio_cdev_update_permissions(
-    const char *devname, int dev_minor)
-{
-	return 0;
-}
-#else
-static int csdio_cdev_update_permissions(
-    const char *devname, int dev_minor)
-{
-	int ret = 0;
-	mm_segment_t fs;
-	struct file *file;
-	struct inode *inode;
-	struct iattr newattrs;
-	int mode = CSDIO_DEV_PERMISSIONS;
-	char dev_file[64];
-
-	fs = get_fs();
-	set_fs(get_ds());
-
-	snprintf(dev_file, sizeof(dev_file), "/dev/%s%d",
-		devname, dev_minor);
-	file = filp_open(dev_file, O_RDWR, 0);
-	if (IS_ERR(file)) {
-		ret = -EFAULT;
-		goto exit;
-	}
-
-	inode = file->f_path.dentry->d_inode;
-
-	mutex_lock(&inode->i_mutex);
-	newattrs.ia_mode =
-		(mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
-	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
-	ret = notify_change(file->f_path.dentry, &newattrs);
-	mutex_unlock(&inode->i_mutex);
-
-	filp_close(file, NULL);
-
-exit:
-	set_fs(fs);
-	return ret;
-}
-#endif
-
-static struct device *csdio_cdev_init(struct cdev *char_dev,
-		const struct file_operations *file_op, int dev_minor,
-		const char *devname, struct device *parent)
-{
-	int ret = 0;
-	struct device *new_device = NULL;
-	dev_t devno = MKDEV(csdio_major, dev_minor);
-
-	/*  Initialize transport device */
-	cdev_init(char_dev, file_op);
-	char_dev->owner = THIS_MODULE;
-	char_dev->ops = file_op;
-	ret = cdev_add(char_dev, devno, 1);
-
-	/*  Fail gracefully if need be */
-	if (ret) {
-		pr_warning("Error %d adding CSDIO char device '%s%d'",
-				ret, devname, dev_minor);
-		goto exit;
-	}
-	pr_info("'%s%d' char driver registered\n", devname, dev_minor);
-
-	/*  create a /dev entry for transport drivers */
-	new_device = device_create(g_csdio.m_driver_class, parent, devno, NULL,
-			"%s%d", devname, dev_minor);
-	if (!new_device) {
-		pr_err("Can't create device node '/dev/%s%d'\n",
-				devname, dev_minor);
-		goto cleanup;
-	}
-	/* no irq attached */
-	g_csdio.m_current_irq_mask = 0;
-
-	if (csdio_cdev_update_permissions(devname, dev_minor)) {
-		pr_warning("%s%d: Unable to update access permissions of the"
-			" '/dev/%s%d'\n",
-			devname, dev_minor, devname, dev_minor);
-	}
-
-	pr_info("%s%d: Device node '/dev/%s%d' created successfully\n",
-			devname, dev_minor, devname, dev_minor);
-	goto exit;
-cleanup:
-	cdev_del(char_dev);
-exit:
-	return new_device;
-}
-
-/* Looks for first non empty function, returns NULL otherwise */
-static struct sdio_func *get_active_func(void)
-{
-	int i;
-
-	for (i = 0; i < CSDIO_NUM_OF_SDIO_FUNCTIONS; i++) {
-		if (g_csdio_func_table[i])
-			return g_csdio_func_table[i]->m_func;
-	}
-	return NULL;
-}
-
-static ssize_t
-show_vdd(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	if (NULL == g_csdio.m_host)
-		return snprintf(buf, PAGE_SIZE, "N/A\n");
-	return snprintf(buf, PAGE_SIZE, "%d\n",
-		g_csdio.m_host->ios.vdd);
-}
-
-static int
-set_vdd_helper(int value)
-{
-	struct mmc_ios *ios = NULL;
-
-	if (NULL == g_csdio.m_host) {
-		pr_err("%s0: Set VDD, no MMC host assigned\n", CSDIO_DEV_NAME);
-		return -ENXIO;
-	}
-
-	mmc_claim_host(g_csdio.m_host);
-	ios = &g_csdio.m_host->ios;
-	ios->vdd = value;
-	g_csdio.m_host->ops->set_ios(g_csdio.m_host, ios);
-	mmc_release_host(g_csdio.m_host);
-	return 0;
-}
-
-static ssize_t
-set_vdd(struct device *dev, struct device_attribute *att,
-	const char *buf, size_t count)
-{
-	int value = 0;
-
-	sscanf(buf, "%d", &value);
-	if (set_vdd_helper(value))
-		return -ENXIO;
-	return count;
-}
-
-static DEVICE_ATTR(vdd, S_IRUGO | S_IWUSR,
-	show_vdd, set_vdd);
-
-static struct attribute *dev_attrs[] = {
-	&dev_attr_vdd.attr,
-	NULL,
-};
-
-static struct attribute_group dev_attr_grp = {
-	.attrs = dev_attrs,
-};
-
-/*
- * The ioctl() implementation for control device
- */
-static int csdio_ctrl_ioctl(struct inode *inode, struct file *filp,
-		unsigned int cmd, unsigned long arg)
-{
-	int err = 0;
-	int ret = 0;
-
-	pr_info("CSDIO ctrl ioctl.\n");
-
-	/*  extract the type and number bitfields
-	    sanity check: return ENOTTY (inappropriate ioctl) before
-	    access_ok()
-	*/
-	if ((_IOC_TYPE(cmd) != CSDIO_IOC_MAGIC) ||
-			(_IOC_NR(cmd) > CSDIO_IOC_MAXNR)) {
-		pr_err(CSDIO_DEV_NAME "Wrong ioctl command parameters\n");
-		ret = -ENOTTY;
-		goto exit;
-	}
-
-	/*  the direction is a bitmask, and VERIFY_WRITE catches R/W
-	  transfers. `Type' is user-oriented, while access_ok is
-	  kernel-oriented, so the concept of "read" and "write" is reversed
-	  */
-	if (_IOC_DIR(cmd) & _IOC_READ) {
-		err = !access_ok(VERIFY_WRITE, (void __user *)arg,
-				_IOC_SIZE(cmd));
-	} else {
-		if (_IOC_DIR(cmd) & _IOC_WRITE)
-			err =  !access_ok(VERIFY_READ, (void __user *)arg,
-					_IOC_SIZE(cmd));
-	}
-	if (err) {
-		pr_err(CSDIO_DEV_NAME "Wrong ioctl access direction\n");
-		ret = -EFAULT;
-		goto exit;
-	}
-
-	switch (cmd) {
-	case CSDIO_IOC_ENABLE_HIGHSPEED_MODE:
-		pr_info(CSDIO_DEV_NAME" ENABLE_HIGHSPEED_MODE\n");
-		break;
-	case CSDIO_IOC_SET_DATA_TRANSFER_CLOCKS:
-		{
-			struct mmc_host *host = g_csdio.m_host;
-			struct mmc_ios *ios = NULL;
-
-			if (NULL == host) {
-				pr_err("%s0: "
-					"CSDIO_IOC_SET_DATA_TRANSFER_CLOCKS,"
-					" no MMC host assigned\n",
-					CSDIO_DEV_NAME);
-				ret = -EFAULT;
-				goto exit;
-			}
-			ios = &host->ios;
-
-			mmc_claim_host(host);
-			ret = get_user(host->ios.clock,
-					(unsigned int __user *)arg);
-			if (ret) {
-				pr_err(CSDIO_DEV_NAME
-					" get data from user space failed\n");
-			} else {
-				pr_err(CSDIO_DEV_NAME
-					"SET_DATA_TRANSFER_CLOCKS(%d-%d)(%d)\n",
-					host->f_min, host->f_max,
-					host->ios.clock);
-				host->ops->set_ios(host, ios);
-			}
-			mmc_release_host(host);
-		}
-		break;
-	case CSDIO_IOC_ENABLE_ISR:
-		{
-			int ret;
-			unsigned char reg;
-			struct sdio_func *func = get_active_func();
-
-			if (!func) {
-				pr_err(CSDIO_DEV_NAME " CSDIO_IOC_ENABLE_ISR"
-						" no active sdio function\n");
-				ret = -EFAULT;
-				goto exit;
-			}
-			pr_info(CSDIO_DEV_NAME
-					" CSDIO_IOC_ENABLE_ISR func=%d\n",
-					func->num);
-			reg = g_csdio.m_current_irq_mask | 1;
-
-			sdio_claim_host(func);
-			sdio_f0_writeb(func, reg, SDIO_CCCR_IENx, &ret);
-			sdio_release_host(func);
-			if (ret) {
-				pr_err(CSDIO_DEV_NAME
-						" Can't sdio_f0_writeb (%d)\n",
-						ret);
-				goto exit;
-			}
-		}
-		break;
-	case CSDIO_IOC_DISABLE_ISR:
-		{
-			int ret;
-			struct sdio_func *func = get_active_func();
-			if (!func) {
-				pr_err(CSDIO_DEV_NAME " CSDIO_IOC_ENABLE_ISR"
-						" no active sdio function\n");
-				ret = -EFAULT;
-				goto exit;
-			}
-			pr_info(CSDIO_DEV_NAME
-					" CSDIO_IOC_DISABLE_ISR func=%p\n",
-					func);
-
-			sdio_claim_host(func);
-			ret = disable_sdio_client_isr(func);
-			sdio_release_host(func);
-			if (ret) {
-				pr_err("%s0: Can't disable client isr (%d)\n",
-					CSDIO_DEV_NAME, ret);
-				goto exit;
-			}
-		}
-	break;
-	case CSDIO_IOC_SET_VDD:
-		{
-			unsigned int vdd = 0;
-
-			ret = get_user(vdd, (unsigned int __user *)arg);
-			if (ret) {
-				pr_err("%s0: CSDIO_IOC_SET_VDD,"
-					" get data from user space failed\n",
-					CSDIO_DEV_NAME);
-				goto exit;
-			}
-			pr_info(CSDIO_DEV_NAME" CSDIO_IOC_SET_VDD - %d\n", vdd);
-
-			ret = set_vdd_helper(vdd);
-			if (ret)
-				goto exit;
-		}
-	break;
-	case CSDIO_IOC_GET_VDD:
-		{
-			if (NULL == g_csdio.m_host) {
-				pr_err("%s0: CSDIO_IOC_GET_VDD,"
-					" no MMC host assigned\n",
-					CSDIO_DEV_NAME);
-				ret = -EFAULT;
-				goto exit;
-			}
-			ret = put_user(g_csdio.m_host->ios.vdd,
-				(unsigned short __user *)arg);
-			if (ret) {
-				pr_err("%s0: CSDIO_IOC_GET_VDD, put data"
-					" to user space failed\n",
-					CSDIO_DEV_NAME);
-				goto exit;
-			}
-		}
-	break;
-	default:  /*  redundant, as cmd was checked against MAXNR */
-		pr_warning(CSDIO_DEV_NAME" Redundant IOCTL\n");
-		ret = -ENOTTY;
-	}
-exit:
-	return ret;
-}
-
-static int csdio_ctrl_fasync(int fd, struct file *filp, int mode)
-{
-	pr_info(CSDIO_DEV_NAME
-			" csdio_ctrl_fasync: fd=%d, filp=%p, mode=%d\n",
-			fd, filp, mode);
-	return fasync_helper(fd, filp, mode, &g_csdio.m_async_queue);
-}
-
-/*
- * Open and close
- */
-static int csdio_ctrl_open(struct inode *inode, struct file *filp)
-{
-	int ret = 0;
-	struct csdio_t *csdio_ctrl_drv = NULL; /*  device information */
-
-	pr_info("CSDIO ctrl open.\n");
-	csdio_ctrl_drv = container_of(inode->i_cdev, struct csdio_t, m_cdev);
-	filp->private_data = csdio_ctrl_drv; /*  for other methods */
-	return ret;
-}
-
-static int csdio_ctrl_release(struct inode *inode, struct file *filp)
-{
-	pr_info("CSDIO ctrl release.\n");
-	/*  remove this filp from the asynchronously notified filp's */
-	csdio_ctrl_fasync(-1, filp, 0);
-	return 0;
-}
-
-static const struct file_operations csdio_ctrl_fops = {
-	.owner =	THIS_MODULE,
-	.ioctl =	csdio_ctrl_ioctl,
-	.open  =	csdio_ctrl_open,
-	.release =	csdio_ctrl_release,
-	.fasync =	csdio_ctrl_fasync,
-};
-
-static int csdio_probe(struct sdio_func *func,
-		const struct sdio_device_id *id)
-{
-	struct csdio_func_t *port;
-	int ret = 0;
-	struct mmc_host *host = func->card->host;
-
-	if (NULL != g_csdio.m_host && g_csdio.m_host != host) {
-		pr_info("%s: Device is on unexpected host\n",
-			CSDIO_DEV_NAME);
-		ret = -ENODEV;
-		goto exit;
-	}
-
-	/* enforce single instance policy */
-	if (g_csdio_func_table[func->num-1]) {
-		pr_err("%s - only single SDIO device supported",
-				sdio_func_id(func));
-		ret = -EEXIST;
-		goto exit;
-	}
-
-	port = kzalloc(sizeof(struct csdio_func_t), GFP_KERNEL);
-	if (!port) {
-		pr_err("Can't allocate memory\n");
-		ret = -ENOMEM;
-		goto exit;
-	}
-
-	/* initialize SDIO side */
-	port->m_func = func;
-	sdio_set_drvdata(func, port);
-
-	pr_info("%s - SDIO device found. Function %d\n",
-			sdio_func_id(func), func->num);
-
-	port->m_device = csdio_cdev_init(&port->m_cdev, &csdio_transport_fops,
-			csdio_minor + port->m_func->num,
-			TP_DEV_NAME, &port->m_func->dev);
-
-	/* create appropriate char device */
-	if (!port->m_device)
-		goto free;
-
-	if (0 == g_csdio.m_num_of_func && NULL == host_name)
-		g_csdio.m_host = host;
-	g_csdio.m_num_of_func++;
-	g_csdio_func_table[func->num-1] = port;
-	port->m_enabled = TRUE;
-	goto exit;
-free:
-	kfree(port);
-exit:
-	return ret;
-}
-
-static void csdio_remove(struct sdio_func *func)
-{
-	struct csdio_func_t *port = sdio_get_drvdata(func);
-
-	csdio_transport_cleanup(port);
-	sdio_claim_host(func);
-	sdio_release_irq(func);
-	sdio_disable_func(func);
-	sdio_release_host(func);
-	kfree(port);
-	g_csdio_func_table[func->num-1] = NULL;
-	g_csdio.m_num_of_func--;
-	if (0 == g_csdio.m_num_of_func && NULL == host_name)
-		g_csdio.m_host = NULL;
-	pr_info("%s%d: Device removed (%s). Function %d\n",
-		CSDIO_DEV_NAME, func->num, sdio_func_id(func), func->num);
-}
-
-/* CONFIG_CSDIO_VENDOR_ID and CONFIG_CSDIO_DEVICE_ID are defined in Kconfig.
- * Use kernel configuration to change the values or overwrite them through
- * module parameters */
-static struct sdio_device_id csdio_ids[] = {
-	{ SDIO_DEVICE(CONFIG_CSDIO_VENDOR_ID, CONFIG_CSDIO_DEVICE_ID) },
-	{ /* end: all zeroes */},
-};
-
-MODULE_DEVICE_TABLE(sdio, csdio_ids);
-
-static struct sdio_driver csdio_driver = {
-	.probe      = csdio_probe,
-	.remove     = csdio_remove,
-	.name       = "csdio",
-	.id_table   = csdio_ids,
-};
-
-static void __exit csdio_exit(void)
-{
-	dev_t devno = MKDEV(csdio_major, csdio_minor);
-
-	sdio_unregister_driver(&csdio_driver);
-	sysfs_remove_group(&g_csdio.m_device->kobj, &dev_attr_grp);
-	kfree(g_sdio_buffer);
-	device_destroy(g_csdio.m_driver_class, devno);
-	cdev_del(&g_csdio.m_cdev);
-	class_destroy(g_csdio.m_driver_class);
-	unregister_chrdev_region(devno, csdio_transport_nr_devs);
-	pr_info("%s: Exit driver module\n", CSDIO_DEV_NAME);
-}
-
-static char *csdio_devnode(struct device *dev, mode_t *mode)
-{
-	*mode = CSDIO_DEV_PERMISSIONS;
-	return NULL;
-}
-
-static int __init csdio_init(void)
-{
-	int ret = 0;
-	dev_t devno = 0;
-
-	pr_info("Init CSDIO driver module.\n");
-
-	/*  Get a range of minor numbers to work with, asking for a dynamic */
-	/*  major unless directed otherwise at load time. */
-	if (csdio_major) {
-		devno = MKDEV(csdio_major, csdio_minor);
-		ret = register_chrdev_region(devno, csdio_transport_nr_devs,
-				CSDIO_DEV_NAME);
-	} else {
-		ret = alloc_chrdev_region(&devno, csdio_minor,
-				csdio_transport_nr_devs, CSDIO_DEV_NAME);
-		csdio_major = MAJOR(devno);
-	}
-	if (ret < 0) {
-		pr_err("CSDIO: can't get major %d\n", csdio_major);
-		goto exit;
-	}
-	pr_info("CSDIO char driver major number is %d\n", csdio_major);
-
-	/* kernel module got parameters: overwrite vendor and device id's */
-	if ((csdio_vendor_id != 0) && (csdio_device_id != 0)) {
-		csdio_ids[0].vendor = (u16)csdio_vendor_id;
-		csdio_ids[0].device = (u16)csdio_device_id;
-	}
-
-	/*  prepare create /dev/... instance */
-	g_csdio.m_driver_class = class_create(THIS_MODULE, CSDIO_DEV_NAME);
-	if (IS_ERR(g_csdio.m_driver_class)) {
-		ret = -ENOMEM;
-		pr_err(CSDIO_DEV_NAME " class_create failed\n");
-		goto unregister_region;
-	}
-	g_csdio.m_driver_class->devnode = csdio_devnode;
-
-	/*  create CSDIO ctrl driver */
-	g_csdio.m_device = csdio_cdev_init(&g_csdio.m_cdev,
-		&csdio_ctrl_fops, csdio_minor, CSDIO_DEV_NAME, NULL);
-	if (!g_csdio.m_device) {
-		pr_err("%s: Unable to create ctrl driver\n",
-			CSDIO_DEV_NAME);
-		goto destroy_class;
-	}
-
-	g_sdio_buffer = kmalloc(CSDIO_SDIO_BUFFER_SIZE, GFP_KERNEL);
-	if (!g_sdio_buffer) {
-		pr_err("Unable to allocate %d bytes\n", CSDIO_SDIO_BUFFER_SIZE);
-		ret = -ENOMEM;
-		goto destroy_cdev;
-	}
-
-	ret = sysfs_create_group(&g_csdio.m_device->kobj, &dev_attr_grp);
-	if (ret) {
-		pr_err("%s: Unable to create device attribute\n",
-			CSDIO_DEV_NAME);
-		goto free_sdio_buff;
-	}
-
-	g_csdio.m_num_of_func = 0;
-	g_csdio.m_host = NULL;
-
-	if (NULL != host_name) {
-		struct device *dev = bus_find_device_by_name(&platform_bus_type,
-			NULL, host_name);
-		if (NULL != dev) {
-			g_csdio.m_host = dev_get_drvdata(dev);
-		} else {
-			pr_err("%s: Host '%s' doesn't exist!\n", CSDIO_DEV_NAME,
-				host_name);
-		}
-	}
-
-	pr_info("%s: Match with VendorId=0x%X, DeviceId=0x%X, Host = %s\n",
-		CSDIO_DEV_NAME, csdio_device_id, csdio_vendor_id,
-		(NULL == host_name) ? "Any" : host_name);
-
-	/* register sdio driver */
-	ret = sdio_register_driver(&csdio_driver);
-	if (ret) {
-		pr_err("%s: Unable to register as SDIO driver\n",
-			CSDIO_DEV_NAME);
-		goto remove_group;
-	}
-
-	goto exit;
-
-remove_group:
-	sysfs_remove_group(&g_csdio.m_device->kobj, &dev_attr_grp);
-free_sdio_buff:
-	kfree(g_sdio_buffer);
-destroy_cdev:
-	cdev_del(&g_csdio.m_cdev);
-destroy_class:
-	class_destroy(g_csdio.m_driver_class);
-unregister_region:
-	unregister_chrdev_region(devno, csdio_transport_nr_devs);
-exit:
-	return ret;
-}
-module_param(csdio_vendor_id, uint, S_IRUGO);
-module_param(csdio_device_id, uint, S_IRUGO);
-module_param(host_name, charp, S_IRUGO);
-
-module_init(csdio_init);
-module_exit(csdio_exit);
-
-MODULE_AUTHOR("The Linux Foundation");
-MODULE_DESCRIPTION("CSDIO device driver version " VERSION);
-MODULE_VERSION(VERSION);
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index 91b90a8..2dbb2f5 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -124,45 +124,131 @@
 	return 0;
 }
 
+static struct dci_pkt_req_entry_t *diag_register_dci_transaction(int uid)
+{
+	struct dci_pkt_req_entry_t *entry = NULL;
+	entry = kzalloc(sizeof(struct dci_pkt_req_entry_t), GFP_KERNEL);
+	if (!entry)
+		return NULL;
+
+	mutex_lock(&driver->dci_mutex);
+	driver->dci_tag++;
+	entry->pid = current->tgid;
+	entry->uid = uid;
+	entry->tag = driver->dci_tag;
+	list_add_tail(&entry->track, &driver->dci_req_list);
+	mutex_unlock(&driver->dci_mutex);
+
+	return entry;
+}
+
+static struct dci_pkt_req_entry_t *diag_dci_get_request_entry(int tag)
+{
+	struct list_head *start, *temp;
+	struct dci_pkt_req_entry_t *entry = NULL;
+	list_for_each_safe(start, temp, &driver->dci_req_list) {
+		entry = list_entry(start, struct dci_pkt_req_entry_t, track);
+		if (entry->tag == tag)
+			return entry;
+	}
+	return NULL;
+}
+
+static int diag_dci_remove_req_entry(unsigned char *buf, int len,
+				     struct dci_pkt_req_entry_t *entry)
+{
+	uint16_t rsp_count = 0, delayed_rsp_id = 0;
+	if (!buf || len <= 0 || !entry) {
+		pr_err("diag: In %s, invalid input buf: %p, len: %d, entry: %p\n",
+			__func__, buf, len, entry);
+		return -EIO;
+	}
+
+	/* It is an immediate response, delete it from the table */
+	if (*buf != 0x80) {
+		list_del(&entry->track);
+		kfree(entry);
+		return 1;
+	}
+
+	/* It is a delayed response. Check if the length is valid */
+	if (len < MIN_DELAYED_RSP_LEN) {
+		pr_err("diag: Invalid delayed rsp packet length %d\n", len);
+		return -EINVAL;
+	}
+
+	/*
+	 * If the delayed response id field (uint16_t at byte 8) is 0 then
+	 * there is only one response and we can remove the request entry.
+	 */
+	delayed_rsp_id = *(uint16_t *)(buf + 8);
+	if (delayed_rsp_id == 0) {
+		list_del(&entry->track);
+		kfree(entry);
+		return 1;
+	}
+
+	/*
+	 * Check the response count field (uint16 at byte 10). The request
+	 * entry can be deleted it it is the last response in the sequence.
+	 * It is the last response in the sequence if the response count
+	 * is 1 or if the signed bit gets dropped.
+	 */
+	rsp_count = *(uint16_t *)(buf + 10);
+	if (rsp_count > 0 && rsp_count < 0x1000) {
+		list_del(&entry->track);
+		kfree(entry);
+		return 1;
+	}
+
+	return 0;
+}
+
 void extract_dci_pkt_rsp(struct diag_smd_info *smd_info, unsigned char *buf)
 {
-	int i = 0, index = -1, cmd_code_len = 1;
-	int curr_client_pid = 0, write_len;
+	int i = 0, cmd_code_len = 1;
+	int curr_client_pid = 0, write_len, *tag = NULL;
 	struct diag_dci_client_tbl *entry;
 	void *temp_buf = NULL;
-	uint8_t recv_pkt_cmd_code;
-
+	uint8_t recv_pkt_cmd_code, delete_flag = 0;
+	struct dci_pkt_req_entry_t *req_entry = NULL;
 	recv_pkt_cmd_code = *(uint8_t *)(buf+4);
 	if (recv_pkt_cmd_code != DCI_PKT_RSP_CODE)
 		cmd_code_len = 4; /* delayed response */
 	write_len = (int)(*(uint16_t *)(buf+2)) - cmd_code_len;
 
 	pr_debug("diag: len = %d\n", write_len);
-	/* look up DCI client with tag */
-	for (i = 0; i < dci_max_reg; i++) {
-		if (driver->req_tracking_tbl[i].tag ==
-					 *(int *)(buf+(4+cmd_code_len))) {
-			*(int *)(buf+4+cmd_code_len) =
-					driver->req_tracking_tbl[i].uid;
-			curr_client_pid =
-					 driver->req_tracking_tbl[i].pid;
-			index = i;
-			break;
-		}
-	}
-	if (index == -1) {
+	tag = (int *)(buf + (4 + cmd_code_len)); /* Retrieve the Tag field */
+	req_entry = diag_dci_get_request_entry(*tag);
+	if (!req_entry) {
 		pr_alert("diag: No matching PID for DCI data\n");
 		return;
 	}
+	*tag = req_entry->uid;
+	curr_client_pid = req_entry->pid;
+
+	/* Remove the headers and send only the response to this function */
+	delete_flag = diag_dci_remove_req_entry(buf + 8 + cmd_code_len,
+						write_len - 4,
+						req_entry);
+	if (delete_flag < 0)
+		return;
+
 	/* Using PID of client process, find client buffer */
 	i = diag_dci_find_client_index(curr_client_pid);
 	if (i != DCI_CLIENT_INDEX_INVALID) {
 		/* copy pkt rsp in client buf */
 		entry = &(driver->dci_client_tbl[i]);
 		mutex_lock(&entry->data_mutex);
-		if (DCI_CHK_CAPACITY(entry, 8+write_len)) {
+		/*
+		 * Check if we can fit the data in the rsp buffer. The total
+		 * length of the rsp is the rsp length (write_len) +
+		 * DCI_PKT_RSP_TYPE header (int) + field for length (int) +
+		 * delete_flag (uint8_t)
+		 */
+		if (DCI_CHK_CAPACITY(entry, 9+write_len)) {
 			pr_alert("diag: create capacity for pkt rsp\n");
-			entry->total_capacity += 8+write_len;
+			entry->total_capacity += 9+write_len;
 			temp_buf = krealloc(entry->dci_data,
 			entry->total_capacity, GFP_KERNEL);
 			if (!temp_buf) {
@@ -179,13 +265,12 @@
 		*(int *)(entry->dci_data+entry->data_len)
 						= write_len;
 		entry->data_len += 4;
+		*(uint8_t *)(entry->dci_data + entry->data_len) = delete_flag;
+		entry->data_len += sizeof(uint8_t);
 		memcpy(entry->dci_data+entry->data_len,
 			buf+4+cmd_code_len, write_len);
 		entry->data_len += write_len;
 		mutex_unlock(&entry->data_mutex);
-		/* delete immediate response entry */
-		if (smd_info->buf_in_1[8+cmd_code_len] != 0x80)
-			driver->req_tracking_tbl[index].pid = 0;
 	}
 }
 
@@ -433,8 +518,8 @@
 	} /* end of loop for all DCI clients */
 }
 
-int diag_send_dci_pkt(struct diag_master_table entry, unsigned char *buf,
-					 int len, int index)
+static int diag_send_dci_pkt(struct diag_master_table entry, unsigned char *buf,
+					 int len, int tag)
 {
 	int i, status = 0;
 	unsigned int read_len = 0;
@@ -459,8 +544,7 @@
 	driver->apps_dci_buf[1] = 1; /* version */
 	*(uint16_t *)(driver->apps_dci_buf + 2) = len + 4 + 1; /* length */
 	driver->apps_dci_buf[4] = DCI_PKT_RSP_CODE;
-	*(int *)(driver->apps_dci_buf + 5) =
-		driver->req_tracking_tbl[index].tag;
+	*(int *)(driver->apps_dci_buf + 5) = tag;
 	for (i = 0; i < len; i++)
 		driver->apps_dci_buf[i+9] = *(buf+i);
 	read_len += len;
@@ -494,42 +578,17 @@
 	return status;
 }
 
-int diag_register_dci_transaction(int uid)
-{
-	int i, new_dci_client = 1, ret = -1;
-
-	for (i = 0; i < dci_max_reg; i++) {
-		if (driver->req_tracking_tbl[i].pid == current->tgid) {
-			new_dci_client = 0;
-			break;
-		}
-	}
-	mutex_lock(&driver->dci_mutex);
-	/* Make an entry in kernel DCI table */
-	driver->dci_tag++;
-	for (i = 0; i < dci_max_reg; i++) {
-		if (driver->req_tracking_tbl[i].pid == 0) {
-			driver->req_tracking_tbl[i].pid = current->tgid;
-			driver->req_tracking_tbl[i].uid = uid;
-			driver->req_tracking_tbl[i].tag = driver->dci_tag;
-			ret = i;
-			break;
-		}
-	}
-	mutex_unlock(&driver->dci_mutex);
-	return ret;
-}
-
 int diag_process_dci_transaction(unsigned char *buf, int len)
 {
 	unsigned char *temp = buf;
 	uint16_t subsys_cmd_code, log_code, item_num;
-	int subsys_id, cmd_code, ret = -1, index = -1, found = 0;
+	int subsys_id, cmd_code, ret = -1, found = 0;
 	struct diag_master_table entry;
 	int count, set_mask, num_codes, bit_index, event_id, offset = 0, i;
 	unsigned int byte_index, read_len = 0;
 	uint8_t equip_id, *log_mask_ptr, *head_log_mask_ptr, byte_mask;
 	uint8_t *event_mask_ptr;
+	struct dci_pkt_req_entry_t *req_entry = NULL;
 
 	if (!driver->smd_dci[MODEM_DATA].ch) {
 		pr_err("diag: DCI smd channel for peripheral %d not valid for dci updates\n",
@@ -550,8 +609,8 @@
 			return -EIO;
 		}
 		/* enter this UID into kernel table and return index */
-		index = diag_register_dci_transaction(*(int *)temp);
-		if (index < 0) {
+		req_entry = diag_register_dci_transaction(*(int *)temp);
+		if (!req_entry) {
 			pr_alert("diag: registering new DCI transaction failed\n");
 			return DIAG_DCI_NO_REG;
 		}
@@ -581,7 +640,8 @@
 					entry.cmd_code_lo <= subsys_cmd_code &&
 					entry.cmd_code_hi >= subsys_cmd_code) {
 					ret = diag_send_dci_pkt(entry, buf,
-								len, index);
+								len,
+								req_entry->tag);
 				} else if (entry.cmd_code == 255
 					  && cmd_code == 75) {
 					if (entry.subsys_id == subsys_id &&
@@ -590,7 +650,8 @@
 						entry.cmd_code_hi >=
 						subsys_cmd_code) {
 						ret = diag_send_dci_pkt(entry,
-							buf, len, index);
+							buf, len,
+							req_entry->tag);
 					}
 				} else if (entry.cmd_code == 255 &&
 					entry.subsys_id == 255) {
@@ -598,7 +659,8 @@
 						entry.cmd_code_hi >=
 							cmd_code) {
 						ret = diag_send_dci_pkt(entry,
-							buf, len, index);
+							buf, len,
+							req_entry->tag);
 					}
 				}
 			}
@@ -883,7 +945,7 @@
 	void *buf = driver->buf_event_mask_update;
 	int header_size = sizeof(struct diag_ctrl_event_mask);
 	int wr_size = -ENOMEM, retry_count = 0, timer;
-	int ret = DIAG_DCI_NO_ERROR;
+	int ret = DIAG_DCI_NO_ERROR, i;
 
 	mutex_lock(&driver->diag_cntl_mutex);
 	/* send event mask update */
@@ -891,8 +953,14 @@
 	driver->event_mask->data_len = 7 + DCI_EVENT_MASK_SIZE;
 	driver->event_mask->stream_id = DCI_MASK_STREAM;
 	driver->event_mask->status = 3; /* status for valid mask */
-	driver->event_mask->event_config = 1; /* event config */
+	driver->event_mask->event_config = 0; /* event config */
 	driver->event_mask->event_mask_size = DCI_EVENT_MASK_SIZE;
+	for (i = 0; i < DCI_EVENT_MASK_SIZE; i++) {
+		if (dci_cumulative_event_mask[i] != 0) {
+			driver->event_mask->event_config = 1;
+			break;
+		}
+	}
 	memcpy(buf, driver->event_mask, header_size);
 	memcpy(buf+header_size, dci_cumulative_event_mask, DCI_EVENT_MASK_SIZE);
 	if (ch) {
@@ -1227,13 +1295,6 @@
 				goto err;
 		}
 	}
-
-	if (driver->req_tracking_tbl == NULL) {
-		driver->req_tracking_tbl = kzalloc(dci_max_reg *
-			sizeof(struct dci_pkt_req_tracking_tbl), GFP_KERNEL);
-		if (driver->req_tracking_tbl == NULL)
-			goto err;
-	}
 	if (driver->apps_dci_buf == NULL) {
 		driver->apps_dci_buf = kzalloc(APPS_BUF_SIZE, GFP_KERNEL);
 		if (driver->apps_dci_buf == NULL)
@@ -1246,6 +1307,7 @@
 			goto err;
 	}
 	driver->diag_dci_wq = create_singlethread_workqueue("diag_dci_wq");
+	INIT_LIST_HEAD(&driver->dci_req_list);
 	success = platform_driver_register(&msm_diag_dci_driver);
 	if (success) {
 		pr_err("diag: Could not register DCI driver\n");
@@ -1261,7 +1323,6 @@
 	return DIAG_DCI_NO_ERROR;
 err:
 	pr_err("diag: Could not initialize diag DCI buffers");
-	kfree(driver->req_tracking_tbl);
 	kfree(driver->dci_client_tbl);
 	kfree(driver->apps_dci_buf);
 	for (i = 0; i < NUM_SMD_DCI_CHANNELS; i++)
@@ -1302,7 +1363,7 @@
 
 		platform_driver_unregister(&msm_diag_dci_cmd_driver);
 	}
-	kfree(driver->req_tracking_tbl);
+
 	kfree(driver->dci_client_tbl);
 	kfree(driver->apps_dci_buf);
 	mutex_destroy(&driver->dci_mutex);
diff --git a/drivers/char/diag/diag_dci.h b/drivers/char/diag/diag_dci.h
index e2c4158..c9be39a 100644
--- a/drivers/char/diag/diag_dci.h
+++ b/drivers/char/diag/diag_dci.h
@@ -24,7 +24,7 @@
 #define DISABLE_LOG_MASK	0
 #define MAX_EVENT_SIZE		512
 #define DCI_CLIENT_INDEX_INVALID -1
-#define DCI_PKT_REQ_MIN_LEN		8
+#define DCI_PKT_REQ_MIN_LEN		5
 #define DCI_LOG_CON_MIN_LEN		14
 #define DCI_EVENT_CON_MIN_LEN		16
 
@@ -42,15 +42,18 @@
 #define DCI_MAX_LOG_CODES		16
 #define DCI_MAX_ITEMS_PER_LOG_CODE	512
 
+#define MIN_DELAYED_RSP_LEN		12
+
 extern unsigned int dci_max_reg;
 extern unsigned int dci_max_clients;
 extern struct mutex dci_health_mutex;
 
-struct dci_pkt_req_tracking_tbl {
+struct dci_pkt_req_entry_t {
 	int pid;
 	int uid;
 	int tag;
-};
+	struct list_head track;
+} __packed;
 
 struct diag_dci_client_tbl {
 	struct task_struct *client;
@@ -115,8 +118,6 @@
 int diag_process_smd_dci_read_data(struct diag_smd_info *smd_info, void *buf,
 								int recd_bytes);
 int diag_process_dci_transaction(unsigned char *buf, int len);
-int diag_send_dci_pkt(struct diag_master_table entry, unsigned char *buf,
-							 int len, int index);
 void extract_dci_pkt_rsp(struct diag_smd_info *smd_info, unsigned char *buf);
 int diag_dci_find_client_index(int client_id);
 /* DCI Log streaming functions */
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 5be77c4..606953d 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -301,7 +301,7 @@
 	/* Whether or not the peripheral supports STM */
 	int peripheral_supports_stm[NUM_SMD_CONTROL_CHANNELS];
 	/* DCI related variables */
-	struct dci_pkt_req_tracking_tbl *req_tracking_tbl;
+	struct list_head dci_req_list;
 	struct diag_dci_client_tbl *dci_client_tbl;
 	int dci_tag;
 	int dci_client_id;
@@ -348,6 +348,7 @@
 	int separate_cmdrsp[NUM_SMD_CONTROL_CHANNELS];
 	unsigned char *usb_buf_out;
 	unsigned char *apps_rsp_buf;
+	unsigned char *user_space_data_buf;
 	/* buffer for updating mask to peripherals */
 	unsigned char *buf_msg_mask_update;
 	unsigned char *buf_log_mask_update;
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index f7c0d24..6ead0ad 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -878,6 +878,8 @@
 	struct diag_log_event_stats le_stats;
 	struct diagpkt_delay_params delay_params;
 	struct real_time_vote_t rt_vote;
+	struct list_head *start, *req_temp;
+	struct dci_pkt_req_entry_t *req_entry = NULL;
 
 	switch (iocmd) {
 	case DIAG_IOCTL_COMMAND_REG:
@@ -993,10 +995,16 @@
 			}
 			result = i;
 			/* Delete this process from DCI table */
-			for (i = 0; i < dci_max_reg; i++)
-				if (driver->req_tracking_tbl[i].pid ==
-					 current->tgid)
-					driver->req_tracking_tbl[i].pid = 0;
+			list_for_each_safe(start, req_temp,
+							&driver->dci_req_list) {
+				req_entry = list_entry(start,
+						struct dci_pkt_req_entry_t,
+						track);
+				if (req_entry->pid == current->tgid) {
+					list_del(&req_entry->track);
+					kfree(req_entry);
+				}
+			}
 			driver->dci_client_tbl[result].client = NULL;
 			kfree(driver->dci_client_tbl[result].dci_data);
 			driver->dci_client_tbl[result].dci_data = NULL;
@@ -1609,22 +1617,15 @@
 		goto fail_free_hdlc;
 	}
 	if (pkt_type == USER_SPACE_DATA_TYPE) {
-		user_space_data = diagmem_alloc(driver, payload_size,
-								POOL_TYPE_USER);
-		if (!user_space_data) {
-			driver->dropped_count++;
-			return -ENOMEM;
-		}
-		err = copy_from_user(user_space_data, buf + 4,
+		err = copy_from_user(driver->user_space_data_buf, buf + 4,
 							 payload_size);
 		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 */
-		remote_proc = diag_get_remote(*(int *)user_space_data);
+		remote_proc =
+			diag_get_remote(*(int *)driver->user_space_data_buf);
 
 		if (remote_proc) {
 			token_offset = 4;
@@ -1634,12 +1635,9 @@
 
 		/* Check masks for On-Device logging */
 		if (driver->mask_check) {
-			if (!mask_request_validate(user_space_data +
+			if (!mask_request_validate(driver->user_space_data_buf +
 							 token_offset)) {
 				pr_alert("diag: mask request Invalid\n");
-				diagmem_free(driver, user_space_data,
-							POOL_TYPE_USER);
-				user_space_data = NULL;
 				return -EFAULT;
 			}
 		}
@@ -1647,7 +1645,7 @@
 #ifdef DIAG_DEBUG
 		pr_debug("diag: user space data %d\n", payload_size);
 		for (i = 0; i < payload_size; i++)
-			pr_debug("\t %x", *((user_space_data
+			pr_debug("\t %x", *((driver->user_space_data_buf
 						+ token_offset)+i));
 #endif
 #ifdef CONFIG_DIAG_SDIO_PIPE
@@ -1658,7 +1656,7 @@
 					 payload_size));
 			if (driver->sdio_ch && (payload_size > 0)) {
 				sdio_write(driver->sdio_ch, (void *)
-				   (user_space_data + token_offset),
+				   (driver->user_space_data_buf + token_offset),
 				   payload_size);
 			}
 		}
@@ -1689,8 +1687,8 @@
 				diag_hsic[index].in_busy_hsic_read_on_device =
 									0;
 				err = diag_bridge_write(index,
-						user_space_data + token_offset,
-						payload_size);
+						driver->user_space_data_buf +
+						token_offset, payload_size);
 				if (err) {
 					pr_err("diag: err sending mask to MDM: %d\n",
 					       err);
@@ -1711,14 +1709,12 @@
 						&& driver->lcid) {
 			if (payload_size > 0) {
 				err = msm_smux_write(driver->lcid, NULL,
-					user_space_data + token_offset,
+					driver->user_space_data_buf +
+						token_offset,
 					payload_size);
 				if (err) {
 					pr_err("diag:send mask to MDM err %d",
 							err);
-					diagmem_free(driver, user_space_data,
-								POOL_TYPE_USER);
-					user_space_data = NULL;
 					return err;
 				}
 			}
@@ -1727,9 +1723,8 @@
 		/* send masks to 8k now */
 		if (!remote_proc)
 			diag_process_hdlc((void *)
-				(user_space_data + token_offset), payload_size);
-		diagmem_free(driver, user_space_data, POOL_TYPE_USER);
-		user_space_data = NULL;
+				(driver->user_space_data_buf + token_offset),
+					payload_size);
 		return 0;
 	}
 
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index ba3ecc2..395bea0 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -2480,7 +2480,7 @@
 	driver->buf_tbl_size = (buf_tbl_size < driver->poolsize_hdlc) ?
 				driver->poolsize_hdlc : buf_tbl_size;
 	driver->supports_separate_cmdrsp = device_supports_separate_cmdrsp();
-	driver->supports_apps_hdlc_encoding = 0;
+	driver->supports_apps_hdlc_encoding = 1;
 	mutex_init(&driver->diag_hdlc_mutex);
 	mutex_init(&driver->diag_cntl_mutex);
 
@@ -2520,6 +2520,12 @@
 	    && (driver->hdlc_buf = kzalloc(HDLC_MAX, GFP_KERNEL)) == NULL)
 		goto err;
 	kmemleak_not_leak(driver->hdlc_buf);
+	if (driver->user_space_data_buf == NULL)
+		driver->user_space_data_buf = kzalloc(USER_SPACE_DATA,
+							GFP_KERNEL);
+	if (driver->user_space_data_buf == NULL)
+		goto err;
+	kmemleak_not_leak(driver->user_space_data_buf);
 	if (driver->client_map == NULL &&
 	    (driver->client_map = kzalloc
 	     ((driver->num_clients) * sizeof(struct diag_client_map),
@@ -2607,6 +2613,7 @@
 	kfree(driver->pkt_buf);
 	kfree(driver->usb_read_ptr);
 	kfree(driver->apps_rsp_buf);
+	kfree(driver->user_space_data_buf);
 	if (driver->diag_wq)
 		destroy_workqueue(driver->diag_wq);
 }
@@ -2646,5 +2653,6 @@
 	kfree(driver->pkt_buf);
 	kfree(driver->usb_read_ptr);
 	kfree(driver->apps_rsp_buf);
+	kfree(driver->user_space_data_buf);
 	destroy_workqueue(driver->diag_wq);
 }
diff --git a/drivers/char/hw_random/msm_rng.c b/drivers/char/hw_random/msm_rng.c
index 369477f..4118a7a 100644
--- a/drivers/char/hw_random/msm_rng.c
+++ b/drivers/char/hw_random/msm_rng.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-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
@@ -25,6 +25,9 @@
 #include <mach/msm_iomap.h>
 #include <mach/socinfo.h>
 #include <mach/msm_bus.h>
+#include <linux/qrng.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
 
 #define DRIVER_NAME "msm_rng"
 
@@ -51,6 +54,29 @@
 	uint32_t qrng_perf_client;
 };
 
+struct msm_rng_device msm_rng_device_info;
+
+static long msm_rng_ioctl(struct file *filp, unsigned int cmd,
+				unsigned long arg)
+{
+	long ret = 0;
+
+	pr_debug("ioctl: cmd = %d\n", cmd);
+	switch (cmd) {
+	case QRNG_IOCTL_RESET_BUS_BANDWIDTH:
+		pr_info("calling msm_rng_bus_scale(LOW)\n");
+		ret = msm_bus_scale_client_update_request(
+				msm_rng_device_info.qrng_perf_client, 0);
+		if (ret)
+			pr_err("failed qrng_reset_bus_bw, ret = %ld\n", ret);
+		break;
+	default:
+		pr_err("Unsupported IOCTL call");
+		break;
+	}
+	return ret;
+}
+
 static int msm_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
 {
 	struct msm_rng_device *msm_rng_dev;
@@ -79,12 +105,6 @@
 		dev_err(&pdev->dev, "failed to enable clock in callback\n");
 		return 0;
 	}
-	if (msm_rng_dev->qrng_perf_client) {
-		ret = msm_bus_scale_client_update_request(
-					msm_rng_dev->qrng_perf_client, 1);
-		if (ret)
-			pr_err("bus_scale_client_update_req failed!\n");
-	}
 	/* read random data from h/w */
 	do {
 		/* check status bit if data is available */
@@ -104,9 +124,6 @@
 		if ((maxsize - currsize) < 4)
 			break;
 	} while (currsize < maxsize);
-	if (msm_rng_dev->qrng_perf_client)
-		ret = msm_bus_scale_client_update_request(
-					msm_rng_dev->qrng_perf_client, 0);
 	/* vote to turn off clock */
 	clk_disable_unprepare(msm_rng_dev->prng_clk);
 
@@ -161,19 +178,24 @@
 		mb();
 	}
 	clk_disable_unprepare(msm_rng_dev->prng_clk);
-	if (msm_rng_dev->qrng_perf_client)
-		ret = msm_bus_scale_client_update_request(
-					msm_rng_dev->qrng_perf_client, 0);
-
 	return 0;
 }
 
+static const struct file_operations msm_rng_fops = {
+	.unlocked_ioctl = msm_rng_ioctl,
+};
+static struct class *msm_rng_class;
+static struct cdev msm_rng_cdev;
+
 static int __devinit msm_rng_probe(struct platform_device *pdev)
 {
 	struct resource *res;
 	struct msm_rng_device *msm_rng_dev = NULL;
 	void __iomem *base = NULL;
 	int error = 0;
+	int ret = 0;
+	struct device *dev;
+
 	struct msm_bus_scale_pdata *qrng_platform_support = NULL;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -220,6 +242,8 @@
 		qrng_platform_support = msm_bus_cl_get_pdata(pdev);
 		msm_rng_dev->qrng_perf_client = msm_bus_scale_register_client(
 						qrng_platform_support);
+		msm_rng_device_info.qrng_perf_client =
+					msm_rng_dev->qrng_perf_client;
 		if (!msm_rng_dev->qrng_perf_client)
 			pr_err("Unable to register bus client\n");
 	}
@@ -238,9 +262,27 @@
 		error = -EPERM;
 		goto rollback_clk;
 	}
+	ret = register_chrdev(QRNG_IOC_MAGIC, DRIVER_NAME, &msm_rng_fops);
 
-	return 0;
+	msm_rng_class = class_create(THIS_MODULE, "msm-rng");
+	if (IS_ERR(msm_rng_class)) {
+		pr_err("class_create failed\n");
+		return PTR_ERR(msm_rng_class);
+	}
 
+	dev = device_create(msm_rng_class, NULL, MKDEV(QRNG_IOC_MAGIC, 0),
+				NULL, "msm-rng");
+	if (IS_ERR(dev)) {
+		pr_err("Device create failed\n");
+		error = PTR_ERR(dev);
+		goto unregister_chrdev;
+	}
+	cdev_init(&msm_rng_cdev, &msm_rng_fops);
+
+	return ret;
+
+unregister_chrdev:
+	unregister_chrdev(QRNG_IOC_MAGIC, DRIVER_NAME);
 rollback_clk:
 	clk_put(msm_rng_dev->prng_clk);
 err_clk_get:
@@ -254,7 +296,7 @@
 static int __devexit msm_rng_remove(struct platform_device *pdev)
 {
 	struct msm_rng_device *msm_rng_dev = platform_get_drvdata(pdev);
-
+	unregister_chrdev(QRNG_IOC_MAGIC, DRIVER_NAME);
 	hwrng_unregister(&msm_rng);
 	clk_put(msm_rng_dev->prng_clk);
 	iounmap(msm_rng_dev->base);
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index af494c6..8f7d39c 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -318,6 +318,7 @@
 show_one(down_differential, down_differential);
 show_one(sampling_down_factor, sampling_down_factor);
 show_one(ignore_nice_load, ignore_nice);
+show_one(down_differential_multi_core, down_differential_multi_core);
 show_one(optimal_freq, optimal_freq);
 show_one(up_threshold_any_cpu_load, up_threshold_any_cpu_load);
 show_one(sync_freq, sync_freq);
@@ -437,6 +438,20 @@
 	return count;
 }
 
+static ssize_t store_down_differential_multi_core(struct kobject *a,
+			struct attribute *b, const char *buf, size_t count)
+{
+	unsigned int input;
+	int ret;
+
+	ret = sscanf(buf, "%u", &input);
+	if (ret != 1)
+		return -EINVAL;
+	dbs_tuners_ins.down_differential_multi_core = input;
+	return count;
+}
+
+
 static ssize_t store_optimal_freq(struct kobject *a, struct attribute *b,
 				   const char *buf, size_t count)
 {
@@ -625,10 +640,13 @@
 
 				cpumask_set_cpu(cpu, &cpus_timer_done);
 				if (dbs_info->cur_policy) {
+					dbs_timer_exit(dbs_info);
 					/* restart dbs timer */
+					mutex_lock(&dbs_info->timer_mutex);
 					dbs_timer_init(dbs_info);
 					/* Enable frequency synchronization
 					 * of CPUs */
+					mutex_unlock(&dbs_info->timer_mutex);
 					atomic_set(&dbs_info->sync_enabled, 1);
 				}
 skip_this_cpu:
@@ -692,6 +710,7 @@
 define_one_global_rw(ignore_nice_load);
 define_one_global_rw(powersave_bias);
 define_one_global_rw(up_threshold_multi_core);
+define_one_global_rw(down_differential_multi_core);
 define_one_global_rw(optimal_freq);
 define_one_global_rw(up_threshold_any_cpu_load);
 define_one_global_rw(sync_freq);
@@ -707,6 +726,7 @@
 	&powersave_bias.attr,
 	&io_is_busy.attr,
 	&up_threshold_multi_core.attr,
+	&down_differential_multi_core.attr,
 	&optimal_freq.attr,
 	&up_threshold_any_cpu_load.attr,
 	&sync_freq.attr,
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index 0809308..514385c 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -36,6 +36,7 @@
 #include <linux/uaccess.h>
 #include <linux/debugfs.h>
 #include <linux/dma-buf.h>
+#include <linux/idr.h>
 #include <linux/msm_ion.h>
 #include <trace/events/kmem.h>
 
@@ -70,6 +71,7 @@
  * @node:		node in the tree of all clients
  * @dev:		backpointer to ion device
  * @handles:		an rb tree of all the handles in this client
+ * @idr:		an idr space for allocating handle ids
  * @lock:		lock protecting the tree of handles
  * @name:		used for debugging
  * @task:		used for debugging
@@ -82,6 +84,7 @@
 	struct rb_node node;
 	struct ion_device *dev;
 	struct rb_root handles;
+	struct idr idr;
 	struct mutex lock;
 	char *name;
 	struct task_struct *task;
@@ -96,7 +99,7 @@
  * @buffer:		pointer to the buffer
  * @node:		node in the client's handle rbtree
  * @kmap_cnt:		count of times this client has mapped to kernel
- * @dmap_cnt:		count of times this client has mapped for dma
+ * @id:			client-unique id allocated by client->idr
  *
  * Modifications to node, map_cnt or mapping should be protected by the
  * lock in the client.  Other fields are never changed after initialization.
@@ -107,6 +110,7 @@
 	struct ion_buffer *buffer;
 	struct rb_node node;
 	unsigned int kmap_cnt;
+	int id;
 };
 
 bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer)
@@ -343,6 +347,7 @@
 		ion_handle_kmap_put(handle);
 	mutex_unlock(&buffer->lock);
 
+	idr_remove(&client->idr, handle->id);
 	if (!RB_EMPTY_NODE(&handle->node))
 		rb_erase(&handle->node, &client->handles);
 
@@ -362,9 +367,16 @@
 	kref_get(&handle->ref);
 }
 
-static int ion_handle_put(struct ion_handle *handle)
+int ion_handle_put(struct ion_handle *handle)
 {
-	return kref_put(&handle->ref, ion_handle_destroy);
+	struct ion_client *client = handle->client;
+	int ret;
+
+	mutex_lock(&client->lock);
+	ret = kref_put(&handle->ref, ion_handle_destroy);
+	mutex_unlock(&client->lock);
+
+	return ret;
 }
 
 static struct ion_handle *ion_handle_lookup(struct ion_client *client,
@@ -374,36 +386,52 @@
 
 	for (n = rb_first(&client->handles); n; n = rb_next(n)) {
 		struct ion_handle *handle = rb_entry(n, struct ion_handle,
-						     node);
+						   node);
 		if (handle->buffer == buffer)
 			return handle;
 	}
 	return NULL;
 }
 
-static bool ion_handle_validate(struct ion_client *client, struct ion_handle *handle)
+struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
+						int id)
 {
-	struct rb_node *n = client->handles.rb_node;
+	struct ion_handle *handle;
 
-	while (n) {
-		struct ion_handle *handle_node = rb_entry(n, struct ion_handle,
-							  node);
-		if (handle < handle_node)
-			n = n->rb_left;
-		else if (handle > handle_node)
-			n = n->rb_right;
-		else
-			return true;
-	}
-	return false;
+	mutex_lock(&client->lock);
+	handle = idr_find(&client->idr, id);
+	if (handle)
+		ion_handle_get(handle);
+	mutex_unlock(&client->lock);
+
+	return handle ? handle : ERR_PTR(-EINVAL);
 }
 
-static void ion_handle_add(struct ion_client *client, struct ion_handle *handle)
+static bool ion_handle_validate(struct ion_client *client, struct ion_handle *handle)
 {
+	WARN_ON(!mutex_is_locked(&client->lock));
+	return (idr_find(&client->idr, handle->id) == handle);
+}
+
+static int ion_handle_add(struct ion_client *client, struct ion_handle *handle)
+{
+	int rc;
 	struct rb_node **p = &client->handles.rb_node;
 	struct rb_node *parent = NULL;
 	struct ion_handle *entry;
 
+	do {
+		int id;
+		rc = idr_pre_get(&client->idr, GFP_KERNEL);
+		if (!rc)
+			return -ENOMEM;
+		rc = idr_get_new_above(&client->idr, handle, 1, &id);
+		handle->id = id;
+	} while (rc == -EAGAIN);
+
+	if (rc < 0)
+		return rc;
+
 	while (*p) {
 		parent = *p;
 		entry = rb_entry(parent, struct ion_handle, node);
@@ -418,6 +446,8 @@
 
 	rb_link_node(&handle->node, parent, p);
 	rb_insert_color(&handle->node, &client->handles);
+
+	return 0;
 }
 
 struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
@@ -428,6 +458,7 @@
 	struct ion_device *dev = client->dev;
 	struct ion_buffer *buffer = NULL;
 	struct ion_heap *heap;
+	int ret;
 	unsigned long secure_allocation = flags & ION_FLAG_SECURE;
 	const unsigned int MAX_DBG_STR_LEN = 64;
 	char dbg_str[MAX_DBG_STR_LEN];
@@ -518,12 +549,16 @@
 	 */
 	ion_buffer_put(buffer);
 
-	if (!IS_ERR(handle)) {
-		mutex_lock(&client->lock);
-		ion_handle_add(client, handle);
-		mutex_unlock(&client->lock);
-	}
+	if (IS_ERR(handle))
+		return handle;
 
+	mutex_lock(&client->lock);
+	ret = ion_handle_add(client, handle);
+	mutex_unlock(&client->lock);
+	if (ret) {
+		ion_handle_put(handle);
+		handle = ERR_PTR(ret);
+	}
 
 	return handle;
 }
@@ -542,8 +577,8 @@
 		mutex_unlock(&client->lock);
 		return;
 	}
-	ion_handle_put(handle);
 	mutex_unlock(&client->lock);
+	ion_handle_put(handle);
 }
 EXPORT_SYMBOL(ion_free);
 
@@ -775,6 +810,7 @@
 
 	client->dev = dev;
 	client->handles = RB_ROOT;
+	idr_init(&client->idr);
 	mutex_init(&client->lock);
 
 	client->name = kzalloc(name_len+1, GFP_KERNEL);
@@ -831,6 +867,10 @@
 						     node);
 		ion_handle_destroy(&handle->ref);
 	}
+
+	idr_remove_all(&client->idr);
+	idr_destroy(&client->idr);
+
 	down_write(&dev->lock);
 	if (client->task)
 		put_task_struct(client->task);
@@ -1175,14 +1215,15 @@
 
 	mutex_lock(&client->lock);
 	valid_handle = ion_handle_validate(client, handle);
-	mutex_unlock(&client->lock);
 	if (!valid_handle) {
 		WARN(1, "%s: invalid handle passed to share.\n", __func__);
+		mutex_unlock(&client->lock);
 		return ERR_PTR(-EINVAL);
 	}
-
 	buffer = handle->buffer;
 	ion_buffer_get(buffer);
+	mutex_unlock(&client->lock);
+
 	dmabuf = dma_buf_export(buffer, &dma_buf_ops, buffer->size, O_RDWR);
 	if (IS_ERR(dmabuf)) {
 		ion_buffer_put(buffer);
@@ -1215,6 +1256,7 @@
 	struct dma_buf *dmabuf;
 	struct ion_buffer *buffer;
 	struct ion_handle *handle;
+	int ret;
 
 	dmabuf = dma_buf_get(fd);
 	if (IS_ERR_OR_NULL(dmabuf))
@@ -1234,14 +1276,24 @@
 	handle = ion_handle_lookup(client, buffer);
 	if (!IS_ERR_OR_NULL(handle)) {
 		ion_handle_get(handle);
+		mutex_unlock(&client->lock);
 		goto end;
 	}
+	mutex_unlock(&client->lock);
+
 	handle = ion_handle_create(client, buffer);
 	if (IS_ERR_OR_NULL(handle))
 		goto end;
-	ion_handle_add(client, handle);
-end:
+
+	mutex_lock(&client->lock);
+	ret = ion_handle_add(client, handle);
 	mutex_unlock(&client->lock);
+	if (ret) {
+		ion_handle_put(handle);
+		handle = ERR_PTR(ret);
+	}
+
+end:
 	dma_buf_put(dmabuf);
 	return handle;
 }
@@ -1279,17 +1331,20 @@
 	case ION_IOC_ALLOC:
 	{
 		struct ion_allocation_data data;
+		struct ion_handle *handle;
 
 		if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
 			return -EFAULT;
-		data.handle = ion_alloc(client, data.len, data.align,
+		handle = ion_alloc(client, data.len, data.align,
 					     data.heap_mask, data.flags);
 
-		if (IS_ERR(data.handle))
-			return PTR_ERR(data.handle);
+		if (IS_ERR(handle))
+			return PTR_ERR(handle);
+
+		data.handle = (ion_user_handle_t)handle->id;
 
 		if (copy_to_user((void __user *)arg, &data, sizeof(data))) {
-			ion_free(client, data.handle);
+			ion_free(client, handle);
 			return -EFAULT;
 		}
 		break;
@@ -1297,28 +1352,31 @@
 	case ION_IOC_FREE:
 	{
 		struct ion_handle_data data;
-		bool valid;
+		struct ion_handle *handle;
 
 		if (copy_from_user(&data, (void __user *)arg,
 				   sizeof(struct ion_handle_data)))
 			return -EFAULT;
-		mutex_lock(&client->lock);
-		valid = ion_handle_validate(client, data.handle);
-		mutex_unlock(&client->lock);
-		if (!valid)
-			return -EINVAL;
-		ion_free(client, data.handle);
+		handle = ion_handle_get_by_id(client, (int)data.handle);
+		if (IS_ERR(handle))
+			return PTR_ERR(handle);
+		ion_free(client, handle);
+		ion_handle_put(handle);
 		break;
 	}
 	case ION_IOC_SHARE:
 	case ION_IOC_MAP:
 	{
 		struct ion_fd_data data;
+		struct ion_handle *handle;
 		if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
 			return -EFAULT;
 
-		data.fd = ion_share_dma_buf_fd(client, data.handle);
-
+		handle = ion_handle_get_by_id(client, (int)data.handle);
+		if (IS_ERR(handle))
+			return PTR_ERR(handle);
+		data.fd = ion_share_dma_buf_fd(client, handle);
+		ion_handle_put(handle);
 		if (copy_to_user((void __user *)arg, &data, sizeof(data)))
 			return -EFAULT;
 		if (data.fd < 0)
@@ -1328,15 +1386,17 @@
 	case ION_IOC_IMPORT:
 	{
 		struct ion_fd_data data;
+		struct ion_handle *handle;
 		int ret = 0;
 		if (copy_from_user(&data, (void __user *)arg,
 				   sizeof(struct ion_fd_data)))
 			return -EFAULT;
-		data.handle = ion_import_dma_buf(client, data.fd);
-		if (IS_ERR(data.handle)) {
-			ret = PTR_ERR(data.handle);
-			data.handle = NULL;
-		}
+		handle = ion_import_dma_buf(client, data.fd);
+		if (IS_ERR(handle))
+			ret = PTR_ERR(handle);
+		else
+			data.handle = (ion_user_handle_t)handle->id;
+
 		if (copy_to_user((void __user *)arg, &data,
 				 sizeof(struct ion_fd_data)))
 			return -EFAULT;
diff --git a/drivers/gpu/ion/ion_priv.h b/drivers/gpu/ion/ion_priv.h
index f5d0287..aa0a9e2 100644
--- a/drivers/gpu/ion/ion_priv.h
+++ b/drivers/gpu/ion/ion_priv.h
@@ -396,4 +396,9 @@
 int ion_walk_heaps(struct ion_client *client, int heap_id, void *data,
 			int (*f)(struct ion_heap *heap, void *data));
 
+struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
+					int id);
+
+int ion_handle_put(struct ion_handle *handle);
+
 #endif /* _ION_PRIV_H */
diff --git a/drivers/gpu/ion/msm/msm_ion.c b/drivers/gpu/ion/msm/msm_ion.c
index 213bcb1..cdd31e1 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -973,11 +973,18 @@
 					sizeof(struct ion_flush_data)))
 			return -EFAULT;
 
-		if (!data.handle) {
+		if (data.handle >= 0) {
+			handle = ion_handle_get_by_id(client, (int)data.handle);
+			if (IS_ERR(handle)) {
+				pr_info("%s: Could not find handle: %d\n",
+					__func__, (int)data.handle);
+				return PTR_ERR(handle);
+			}
+		} else {
 			handle = ion_import_dma_buf(client, data.fd);
 			if (IS_ERR(handle)) {
-				pr_info("%s: Could not import handle: %d\n",
-					__func__, (int)handle);
+				pr_info("%s: Could not import handle: %p\n",
+					__func__, handle);
 				return -EINVAL;
 			}
 		}
@@ -988,28 +995,20 @@
 		end = (unsigned long) data.vaddr + data.length;
 
 		if (start && check_vaddr_bounds(start, end)) {
-			up_read(&mm->mmap_sem);
 			pr_err("%s: virtual address %p is out of bounds\n",
 				__func__, data.vaddr);
-			if (!data.handle)
-				ion_free(client, handle);
-			return -EINVAL;
+			ret = -EINVAL;
+		} else {
+			ret = ion_do_cache_op(client, handle, data.vaddr,
+					data.offset, data.length, cmd);
 		}
-
-		ret = ion_do_cache_op(client,
-				data.handle ? data.handle : handle,
-				data.vaddr, data.offset, data.length,
-				cmd);
-
 		up_read(&mm->mmap_sem);
 
-		if (!data.handle)
-			ion_free(client, handle);
+		ion_free(client, handle);
 
 		if (ret < 0)
 			return ret;
 		break;
-
 	}
 	case ION_IOC_PREFETCH:
 	{
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index e5f5ad7..3d4c66a 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -4077,6 +4077,7 @@
 static int a3xx_perfcounter_init(struct adreno_device *adreno_dev)
 {
 	int ret;
+	struct kgsl_device *device = &adreno_dev->dev;
 	/* SP[3] counter is broken on a330 so disable it if a330 device */
 	if (adreno_is_a330(adreno_dev))
 		a3xx_perfcounters_sp[3].countable = KGSL_PERFCOUNTER_BROKEN;
@@ -4088,15 +4089,18 @@
 	ret = adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_PWR, 1,
 			NULL, PERFCOUNTER_FLAG_KERNEL);
 
-	/* VBIF waiting for RAM */
-	ret |= adreno_perfcounter_get(adreno_dev,
+	if (device->pwrctrl.bus_control) {
+		/* VBIF waiting for RAM */
+		ret |= adreno_perfcounter_get(adreno_dev,
 				KGSL_PERFCOUNTER_GROUP_VBIF_PWR, 0,
 				NULL, PERFCOUNTER_FLAG_KERNEL);
-	/* VBIF DDR cycles */
-	ret |= adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_VBIF,
+		/* VBIF DDR cycles */
+		ret |= adreno_perfcounter_get(adreno_dev,
+				KGSL_PERFCOUNTER_GROUP_VBIF,
 				VBIF_AXI_TOTAL_BEATS,
 				&adreno_dev->ram_cycles_lo,
 				PERFCOUNTER_FLAG_KERNEL);
+	}
 
 	/* Default performance counter profiling to false */
 	adreno_dev->profile.enabled = false;
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index fe99a4b..9aefda6 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -2878,7 +2878,7 @@
 	bool full_flush = false;
 
 	if (param->id_list == NULL || param->count == 0
-			|| param->count > (UINT_MAX/sizeof(unsigned int)))
+			|| param->count > (PAGE_SIZE / sizeof(unsigned int)))
 		return -EINVAL;
 
 	id_list = kzalloc(param->count * sizeof(unsigned int), GFP_KERNEL);
diff --git a/drivers/hwmon/qpnp-adc-current.c b/drivers/hwmon/qpnp-adc-current.c
index adaff41..9839595 100644
--- a/drivers/hwmon/qpnp-adc-current.c
+++ b/drivers/hwmon/qpnp-adc-current.c
@@ -147,7 +147,6 @@
 	struct list_head			list;
 	int64_t					die_temp;
 	struct delayed_work			iadc_work;
-	struct mutex				iadc_vadc_lock;
 	bool					iadc_mode_sel;
 	struct qpnp_iadc_comp			iadc_comp;
 	struct qpnp_vadc_chip			*vadc_dev;
@@ -1012,12 +1011,10 @@
 	if (qpnp_iadc_is_valid(iadc) < 0)
 		return -EPROBE_DEFER;
 
-	if (!iadc->iadc_mode_sel) {
-		rc = qpnp_check_pmic_temp(iadc);
-		if (rc) {
-			pr_err("Error checking pmic therm temp\n");
-			return rc;
-		}
+	rc = qpnp_check_pmic_temp(iadc);
+	if (rc) {
+		pr_err("Error checking pmic therm temp\n");
+		return rc;
 	}
 
 	mutex_lock(&iadc->adc->adc_lock);
@@ -1121,24 +1118,21 @@
 	enum qpnp_iadc_channels i_channel, struct qpnp_iadc_result *i_result,
 	enum qpnp_vadc_channels v_channel, struct qpnp_vadc_result *v_result)
 {
-	int rc = 0;
+	int rc = 0, mode_sel = 0, num = 0, rsense_n_ohms = 0, sign = 0;
+	uint16_t raw_data;
+	int32_t rsense_u_ohms = 0;
+	int64_t result_current;
 
 	if (qpnp_iadc_is_valid(iadc) < 0)
 		return -EPROBE_DEFER;
 
-	mutex_lock(&iadc->iadc_vadc_lock);
+	mutex_lock(&iadc->adc->adc_lock);
 
 	if (iadc->iadc_poll_eoc) {
 		pr_debug("acquiring iadc eoc wakelock\n");
 		pm_stay_awake(iadc->dev);
 	}
 
-	rc = qpnp_check_pmic_temp(iadc);
-	if (rc) {
-		pr_err("PMIC die temp check failed\n");
-		goto fail;
-	}
-
 	iadc->iadc_mode_sel = true;
 
 	rc = qpnp_vadc_iadc_sync_request(iadc->vadc_dev, v_channel);
@@ -1147,11 +1141,43 @@
 		goto fail;
 	}
 
-	rc = qpnp_iadc_read(iadc, i_channel, i_result);
-	if (rc)
-		pr_err("Configuring IADC failed\n");
-	/* Intentional fall through to release VADC */
+	rc = qpnp_iadc_configure(iadc, i_channel, &raw_data, mode_sel);
+	if (rc < 0) {
+		pr_err("qpnp adc result read failed with %d\n", rc);
+		goto fail_release_vadc;
+	}
 
+	rc = qpnp_iadc_get_rsense(iadc, &rsense_n_ohms);
+	pr_debug("current raw:0%x and rsense:%d\n",
+			raw_data, rsense_n_ohms);
+	rsense_u_ohms = rsense_n_ohms/1000;
+	num = raw_data - iadc->adc->calib.offset_raw;
+	if (num < 0) {
+		sign = 1;
+		num = -num;
+	}
+
+	i_result->result_uv = (num * QPNP_ADC_GAIN_NV)/
+		(iadc->adc->calib.gain_raw - iadc->adc->calib.offset_raw);
+	result_current = i_result->result_uv;
+	result_current *= QPNP_IADC_NANO_VOLTS_FACTOR;
+	/* Intentional fall through. Process the result w/o comp */
+	do_div(result_current, rsense_u_ohms);
+
+	if (sign) {
+		i_result->result_uv = -i_result->result_uv;
+		result_current = -result_current;
+	}
+	result_current *= -1;
+	rc = qpnp_iadc_comp_result(iadc, &result_current);
+	if (rc < 0)
+		pr_err("Error during compensating the IADC\n");
+	rc = 0;
+	result_current *= -1;
+
+	i_result->result_ua = (int32_t) result_current;
+
+fail_release_vadc:
 	rc = qpnp_vadc_iadc_sync_complete_request(iadc->vadc_dev, v_channel,
 							v_result);
 	if (rc)
@@ -1163,7 +1189,7 @@
 		pr_debug("releasing iadc eoc wakelock\n");
 		pm_relax(iadc->dev);
 	}
-	mutex_unlock(&iadc->iadc_vadc_lock);
+	mutex_unlock(&iadc->adc->adc_lock);
 
 	return rc;
 }
@@ -1306,7 +1332,6 @@
 		goto fail;
 	}
 
-	mutex_init(&iadc->iadc_vadc_lock);
 	INIT_WORK(&iadc->trigger_completion_work, qpnp_iadc_trigger_completion);
 	INIT_DELAYED_WORK(&iadc->iadc_work, qpnp_iadc_work);
 	rc = qpnp_iadc_comp_info(iadc);
@@ -1347,7 +1372,6 @@
 	int i = 0;
 
 	cancel_delayed_work(&iadc->iadc_work);
-	mutex_destroy(&iadc->iadc_vadc_lock);
 	for_each_child_of_node(node, child) {
 		device_remove_file(&spmi->dev,
 			&iadc->sens_attr[i].dev_attr);
diff --git a/drivers/input/misc/cm36283.c b/drivers/input/misc/cm36283.c
index 94807e7..5c89c0c 100644
--- a/drivers/input/misc/cm36283.c
+++ b/drivers/input/misc/cm36283.c
@@ -702,17 +702,9 @@
 {
 	int ret = -EIO;
 	unsigned int delay;
-	
-	mutex_lock(&als_enable_mutex);
 
-	if (lpi->als_enable) {
-		dev_err(&lpi->i2c_client->dev, "%s: already enabled\n",
-			       __func__);
-		ret = 0;
-	} else {
-		ret = control_and_report(lpi, CONTROL_ALS, 1, 0);
-	}
-	
+	mutex_lock(&als_enable_mutex);
+	ret = control_and_report(lpi, CONTROL_ALS, 1, 0);
 	mutex_unlock(&als_enable_mutex);
 
 	delay = atomic_read(&lpi->ls_poll_delay);
@@ -2015,27 +2007,40 @@
 	struct cm36283_info *lpi = lp_info;
 
 	if (lpi->als_enable) {
-		lightsensor_disable(lpi);
+		if (lightsensor_disable(lpi))
+			goto out;
 		lpi->als_enable = 1;
 	}
-	cm36283_power_set(lpi, 0);
+	if (cm36283_power_set(lpi, 0))
+		goto out;
 
 	return 0;
+
+out:
+	dev_err(&lpi->i2c_client->dev, "%s:failed during resume operation.\n",
+			__func__);
+	return -EIO;
 }
 
 static int cm36283_resume(struct device *dev)
 {
 	struct cm36283_info *lpi = lp_info;
 
-	cm36283_power_set(lpi, 1);
+	if (cm36283_power_set(lpi, 1))
+		goto out;
 
 	if (lpi->als_enable) {
-		cm36283_setup(lpi);
-		lightsensor_setup(lpi);
-		psensor_setup(lpi);
-		lightsensor_enable(lpi);
+		ls_initial_cmd(lpi);
+		psensor_initial_cmd(lpi);
+		if (lightsensor_enable(lpi))
+			goto out;
 	}
 	return 0;
+
+out:
+	dev_err(&lpi->i2c_client->dev, "%s:failed during resume operation.\n",
+			__func__);
+	return -EIO;
 }
 #endif
 
diff --git a/drivers/input/misc/mpu3050.c b/drivers/input/misc/mpu3050.c
index 3b7bf5a..fab209e 100644
--- a/drivers/input/misc/mpu3050.c
+++ b/drivers/input/misc/mpu3050.c
@@ -325,32 +325,32 @@
 {
 	struct mpu3050_sensor *sensor = dev_get_drvdata(dev);
 	unsigned long val;
+	u32 enable;
 
 	if (kstrtoul(buf, 10, &val))
 		return -EINVAL;
-	sensor->enable = (u32)val == 0 ? 0 : 1;
-	if (sensor->enable) {
+	enable = (u32)val == 0 ? 0 : 1;
+	if (enable && (!sensor->enable)) {
+		sensor->enable = enable;
 		pm_runtime_get_sync(sensor->dev);
-		gpio_set_value(sensor->enable_gpio, 1);
 		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);
+		else
 			enable_irq(sensor->client->irq);
-		}
-	} else {
+	} else if (!enable && sensor->enable) {
 		if (sensor->use_poll)
 			cancel_delayed_work_sync(&sensor->input_work);
 		else
 			disable_irq(sensor->client->irq);
-		gpio_set_value(sensor->enable_gpio, 0);
-		pm_runtime_put(sensor->dev);
+		pm_runtime_put_sync(sensor->dev);
+		sensor->enable = enable;
+	} else {
+		dev_warn(&sensor->client->dev,
+				"ignore enable state change from %d to %d\n",
+				sensor->enable, enable);
 	}
+
 	return count;
 }
 
@@ -485,54 +485,6 @@
 }
 
 /**
- *	mpu3050_input_open	-	called on input event open
- *	@input: input dev of opened device
- *
- *	The input layer calls this function when input event is opened. The
- *	function will push the device to resume. Then, the device is ready
- *	to provide data.
- */
-static int mpu3050_input_open(struct input_dev *input)
-{
-	struct mpu3050_sensor *sensor = input_get_drvdata(input);
-	int error;
-
-	pm_runtime_get_sync(sensor->dev);
-
-	/* Enable interrupts */
-	error = i2c_smbus_write_byte_data(sensor->client, MPU3050_INT_CFG,
-					MPU3050_ACTIVE_LOW |
-					MPU3050_OPEN_DRAIN |
-					MPU3050_RAW_RDY_EN);
-	if (error < 0) {
-		pm_runtime_put(sensor->dev);
-		return error;
-	}
-	if (sensor->use_poll)
-		schedule_delayed_work(&sensor->input_work,
-			msecs_to_jiffies(sensor->poll_interval));
-
-	return 0;
-}
-
-/**
- *	mpu3050_input_close	-	called on input event close
- *	@input: input dev of closed device
- *
- *	The input layer calls this function when input event is closed. The
- *	function will push the device to suspend.
- */
-static void mpu3050_input_close(struct input_dev *input)
-{
-	struct mpu3050_sensor *sensor = input_get_drvdata(input);
-
-	if (sensor->use_poll)
-		cancel_delayed_work_sync(&sensor->input_work);
-
-	pm_runtime_put(sensor->dev);
-}
-
-/**
  *	mpu3050_interrupt_thread	-	handle an IRQ
  *	@irq: interrupt numner
  *	@data: the sensor
@@ -588,18 +540,12 @@
  *
  *	Called during device probe; configures the sampling method.
  */
-static int __devinit mpu3050_hw_init(struct mpu3050_sensor *sensor)
+static int mpu3050_hw_init(struct mpu3050_sensor *sensor)
 {
 	struct i2c_client *client = sensor->client;
 	int ret;
 	u8 reg;
 
-	/* Reset */
-	ret = i2c_smbus_write_byte_data(client, MPU3050_PWR_MGM,
-					MPU3050_PWR_MGM_RESET);
-	if (ret < 0)
-		return ret;
-
 	ret = i2c_smbus_read_byte_data(client, MPU3050_PWR_MGM);
 	if (ret < 0)
 		return ret;
@@ -624,6 +570,16 @@
 	if (ret < 0)
 		return ret;
 
+	/* Enable interrupts */
+	if (!sensor->use_poll) {
+		reg = MPU3050_ACTIVE_LOW;
+		reg |= MPU3050_OPEN_DRAIN;
+		reg |= MPU3050_RAW_RDY_EN;
+		ret = i2c_smbus_write_byte_data(client, MPU3050_INT_CFG, reg);
+		if (ret < 0)
+			return ret;
+	}
+
 	return 0;
 }
 #ifdef CONFIG_OF
@@ -750,9 +706,6 @@
 	idev->name = "MPU3050";
 	idev->id.bustype = BUS_I2C;
 
-	idev->open = mpu3050_input_open;
-	idev->close = mpu3050_input_close;
-
 	input_set_capability(idev, EV_ABS, ABS_MISC);
 	input_set_abs_params(idev, ABS_X,
 			     MPU3050_MIN_VALUE, MPU3050_MAX_VALUE, 0, 0);
@@ -813,6 +766,9 @@
 		disable_irq(client->irq);
 	}
 
+	sensor->enable = 0;
+	mpu3050_set_power_mode(client, 0);
+
 	error = input_register_device(idev);
 	if (error) {
 		dev_err(&client->dev, "failed to register input device\n");
@@ -893,10 +849,11 @@
 	struct i2c_client *client = to_i2c_client(dev);
 	struct mpu3050_sensor *sensor = i2c_get_clientdata(client);
 
-	if (!sensor->use_poll)
-		disable_irq(client->irq);
-
-	mpu3050_set_power_mode(client, 0);
+	if (sensor->enable) {
+		if (!sensor->use_poll)
+			disable_irq(client->irq);
+		mpu3050_set_power_mode(client, 0);
+	}
 
 	return 0;
 }
@@ -912,16 +869,64 @@
 	struct i2c_client *client = to_i2c_client(dev);
 	struct mpu3050_sensor *sensor = i2c_get_clientdata(client);
 
-	mpu3050_set_power_mode(client, 1);
+	if (sensor->enable) {
+		mpu3050_set_power_mode(client, 1);
+		mpu3050_hw_init(sensor);
+		if (!sensor->use_poll)
+			enable_irq(client->irq);
+	}
 
-	if (!sensor->use_poll)
-		enable_irq(client->irq);
+	return 0;
+}
+
+/**
+ *	mpu3050_runtime_suspend		-	called on device enters runtime suspend
+ *	@dev: device being suspended
+ *
+ *	Put the device into sleep mode.
+ */
+static int mpu3050_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mpu3050_sensor *sensor = i2c_get_clientdata(client);
+
+	if (sensor->enable)
+		mpu3050_set_power_mode(client, 0);
+
+	return 0;
+}
+
+/**
+ *	mpu3050_runtime_resume		-	called on device enters runtime resume
+ *	@dev: device being resumed
+ *
+ *	Put the device into powered mode.
+ */
+static int mpu3050_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mpu3050_sensor *sensor = i2c_get_clientdata(client);
+
+	if (sensor->enable) {
+		mpu3050_set_power_mode(client, 1);
+		mpu3050_hw_init(sensor);
+	}
 
 	return 0;
 }
 #endif
 
-static UNIVERSAL_DEV_PM_OPS(mpu3050_pm, mpu3050_suspend, mpu3050_resume, NULL);
+static const struct dev_pm_ops mpu3050_pm = {
+	.runtime_suspend = mpu3050_runtime_suspend,
+	.runtime_resume = mpu3050_runtime_resume,
+	.runtime_idle = NULL,
+	.suspend = mpu3050_suspend,
+	.resume = mpu3050_resume,
+	.freeze = mpu3050_suspend,
+	.thaw = mpu3050_resume,
+	.poweroff = mpu3050_suspend,
+	.restore = mpu3050_resume,
+};
 
 static const struct i2c_device_id mpu3050_ids[] = {
 	{ "mpu3050", 0 },
diff --git a/drivers/input/touchscreen/cyttsp-i2c-qc.c b/drivers/input/touchscreen/cyttsp-i2c-qc.c
index 6c4e6b7..2b1360e 100644
--- a/drivers/input/touchscreen/cyttsp-i2c-qc.c
+++ b/drivers/input/touchscreen/cyttsp-i2c-qc.c
@@ -2873,6 +2873,21 @@
 	return rc;
 }
 
+static void cyttsp_release_all(struct cyttsp *ts)
+{
+	int id;
+
+	for (id = 0; id < CY_NUM_MT_TCH_ID; id++) {
+		input_mt_slot(ts->input, id);
+		input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, 0);
+	}
+
+	input_report_key(ts->input, BTN_TOUCH, 0);
+	input_report_key(ts->input, BTN_TOOL_FINGER, 0);
+
+	input_sync(ts->input);
+}
+
 /* Function to manage power-on resume */
 static int cyttsp_resume(struct device *dev)
 {
@@ -2978,6 +2993,8 @@
 	else
 		disable_irq(ts->client->irq);
 
+	cyttsp_release_all(ts);
+
 	if (!(retval < CY_OK)) {
 		if (ts->platform_data->use_sleep &&
 			(ts->platform_data->power_state == CY_ACTIVE_STATE)) {
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.c b/drivers/input/touchscreen/gt9xx/gt9xx.c
index ba38061..b39cb0d 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx.c
+++ b/drivers/input/touchscreen/gt9xx/gt9xx.c
@@ -1139,53 +1139,70 @@
 	struct i2c_client *client = ts->client;
 	struct goodix_ts_platform_data *pdata = ts->pdata;
 	int ret;
+
 	if (gpio_is_valid(pdata->irq_gpio)) {
 		ret = gpio_request(pdata->irq_gpio, "goodix_ts_irq_gpio");
 		if (ret) {
-			dev_err(&client->dev, "irq gpio request failed\n");
-			goto pwr_off;
+			dev_err(&client->dev, "Unable to request irq gpio [%d]\n",
+				pdata->irq_gpio);
+			goto err_pwr_off;
 		}
 		ret = gpio_direction_input(pdata->irq_gpio);
 		if (ret) {
-			dev_err(&client->dev,
-					"set_direction for irq gpio failed\n");
-			goto free_irq_gpio;
+			dev_err(&client->dev, "Unable to set direction for irq gpio [%d]\n",
+				pdata->irq_gpio);
+			goto err_free_irq_gpio;
 		}
 	} else {
-		dev_err(&client->dev, "irq gpio is invalid!\n");
+		dev_err(&client->dev, "Invalid irq gpio [%d]!\n",
+			pdata->irq_gpio);
 		ret = -EINVAL;
-		goto free_irq_gpio;
+		goto err_pwr_off;
 	}
 
 	if (gpio_is_valid(pdata->reset_gpio)) {
-		ret = gpio_request(pdata->reset_gpio, "goodix_ts__reset_gpio");
+		ret = gpio_request(pdata->reset_gpio, "goodix_ts_reset_gpio");
 		if (ret) {
-			dev_err(&client->dev, "reset gpio request failed\n");
-			goto free_irq_gpio;
+			dev_err(&client->dev, "Unable to request reset gpio [%d]\n",
+				pdata->reset_gpio);
+			goto err_free_irq_gpio;
 		}
 
 		ret = gpio_direction_output(pdata->reset_gpio, 0);
 		if (ret) {
-			dev_err(&client->dev,
-					"set_direction for reset gpio failed\n");
-			goto free_reset_gpio;
+			dev_err(&client->dev, "Unable to set direction for reset gpio [%d]\n",
+				pdata->reset_gpio);
+			goto err_free_reset_gpio;
 		}
 	} else {
-		dev_err(&client->dev, "reset gpio is invalid!\n");
+		dev_err(&client->dev, "Invalid irq gpio [%d]!\n",
+			pdata->reset_gpio);
 		ret = -EINVAL;
-		goto free_reset_gpio;
+		goto err_free_irq_gpio;
 	}
-	gpio_direction_input(pdata->reset_gpio);
+	/* IRQ GPIO is an input signal, but we are setting it to output
+	  * direction and pulling it down, to comply with power up timing
+	  * requirements, mentioned in power up timing section of device
+	  * datasheet.
+	  */
+	ret = gpio_direction_output(pdata->irq_gpio, 0);
+	if (ret)
+		dev_warn(&client->dev,
+			"pull down interrupt gpio failed\n");
+	ret = gpio_direction_output(pdata->reset_gpio, 0);
+	if (ret)
+		dev_warn(&client->dev,
+			"pull down reset gpio failed\n");
 
 	return ret;
 
-free_reset_gpio:
+err_free_reset_gpio:
 	if (gpio_is_valid(pdata->reset_gpio))
 		gpio_free(pdata->reset_gpio);
-free_irq_gpio:
+err_free_irq_gpio:
 	if (gpio_is_valid(pdata->irq_gpio))
 		gpio_free(pdata->irq_gpio);
-pwr_off:
+err_pwr_off:
 	return ret;
 }
 
@@ -1771,10 +1788,16 @@
 	ts->gtp_rawdiff_mode = 0;
 	ts->power_on = false;
 
+	ret = gtp_request_io_port(ts);
+	if (ret) {
+		dev_err(&client->dev, "GTP request IO port failed.\n");
+		goto exit_free_client_data;
+	}
+
 	ret = goodix_power_init(ts);
 	if (ret) {
 		dev_err(&client->dev, "GTP power init failed\n");
-		goto exit_free_client_data;
+		goto exit_free_io_port;
 	}
 
 	ret = goodix_power_on(ts);
@@ -1783,18 +1806,12 @@
 		goto exit_deinit_power;
 	}
 
-	ret = gtp_request_io_port(ts);
-	if (ret) {
-		dev_err(&client->dev, "GTP request IO port failed.\n");
-		goto exit_power_off;
-	}
-
 	gtp_reset_guitar(ts, 20);
 
 	ret = gtp_i2c_test(client);
 	if (ret != 2) {
 		dev_err(&client->dev, "I2C communication ERROR!\n");
-		goto exit_free_io_port;
+		goto exit_power_off;
 	}
 
 	if (pdata->fw_name)
@@ -1900,15 +1917,15 @@
 	}
 exit_free_inputdev:
 	kfree(ts->config_data);
+exit_power_off:
+	goodix_power_off(ts);
+exit_deinit_power:
+	goodix_power_deinit(ts);
 exit_free_io_port:
 	if (gpio_is_valid(pdata->reset_gpio))
 		gpio_free(pdata->reset_gpio);
 	if (gpio_is_valid(pdata->irq_gpio))
 		gpio_free(pdata->irq_gpio);
-exit_power_off:
-	goodix_power_off(ts);
-exit_deinit_power:
-	goodix_power_deinit(ts);
 exit_free_client_data:
 	i2c_set_clientdata(client, NULL);
 	kfree(ts);
@@ -1988,9 +2005,10 @@
 Output:
 	None.
 *******************************************************/
-static void goodix_ts_suspend(struct goodix_ts_data *ts)
+static int goodix_ts_suspend(struct device *dev)
 {
-	int ret = -1, i;
+	struct goodix_ts_data *ts = dev_get_drvdata(dev);
+	int ret = 0, i;
 
 	mutex_lock(&ts->lock);
 #if GTP_ESD_PROTECT
@@ -2020,6 +2038,8 @@
 	 */
 	msleep(58);
 	mutex_unlock(&ts->lock);
+
+	return ret;
 }
 
 /*******************************************************
@@ -2030,9 +2050,10 @@
 Output:
 	None.
 *******************************************************/
-static void goodix_ts_resume(struct goodix_ts_data *ts)
+static int goodix_ts_resume(struct device *dev)
 {
-	int ret = -1;
+	struct goodix_ts_data *ts = dev_get_drvdata(dev);
+	int ret = 0;
 
 	mutex_lock(&ts->lock);
 	ret = gtp_wakeup_sleep(ts);
@@ -2055,6 +2076,8 @@
 	gtp_esd_switch(ts->client, SWITCH_ON);
 #endif
 	mutex_unlock(&ts->lock);
+
+	return ret;
 }
 
 #if defined(CONFIG_FB)
@@ -2070,9 +2093,9 @@
 			ts && ts->client) {
 		blank = evdata->data;
 		if (*blank == FB_BLANK_UNBLANK)
-			goodix_ts_resume(ts);
+			goodix_ts_resume(&ts->client->dev);
 		else if (*blank == FB_BLANK_POWERDOWN)
-			goodix_ts_suspend(ts);
+			goodix_ts_suspend(&ts->client->dev);
 	}
 
 	return 0;
@@ -2091,7 +2114,7 @@
 	struct goodix_ts_data *ts;
 
 	ts = container_of(h, struct goodix_ts_data, early_suspend);
-	goodix_ts_suspend(ts);
+	goodix_ts_suspend(&ts->client->dev);
 	return;
 }
 
@@ -2245,6 +2268,9 @@
 }
 #endif
 
+static SIMPLE_DEV_PM_OPS(goodix_ts_dev_pm_ops, goodix_ts_suspend,
+					goodix_ts_resume);
+
 static const struct i2c_device_id goodix_ts_id[] = {
 	{ GTP_I2C_NAME, 0 },
 	{ }
@@ -2267,6 +2293,9 @@
 		.name     = GTP_I2C_NAME,
 		.owner    = THIS_MODULE,
 		.of_match_table = goodix_match_table,
+#if CONFIG_PM
+		.pm = &goodix_ts_dev_pm_ops,
+#endif
 	},
 };
 
@@ -2303,7 +2332,7 @@
 	i2c_del_driver(&goodix_ts_driver);
 }
 
-late_initcall(goodix_ts_init);
+module_init(goodix_ts_init);
 module_exit(goodix_ts_exit);
 
 MODULE_DESCRIPTION("GTP Series Driver");
diff --git a/drivers/input/touchscreen/synaptics_fw_update.c b/drivers/input/touchscreen/synaptics_fw_update.c
index ad62d5e..7da0376 100644
--- a/drivers/input/touchscreen/synaptics_fw_update.c
+++ b/drivers/input/touchscreen/synaptics_fw_update.c
@@ -352,7 +352,6 @@
 		(data->options_firmware_id == (1 << OPTION_BUILD_INFO));
 
 	if (img->is_contain_build_info) {
-		img->firmware_id = extract_uint(data->firmware_id);
 		img->package_id = (data->pkg_id_msb << 8) |
 				data->pkg_id_lsb;
 		img->package_revision_id = (data->pkg_id_rev_msb << 8) |
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.c b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
index 8123920..755084c 100644
--- a/drivers/input/touchscreen/synaptics_i2c_rmi4.c
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
@@ -607,6 +607,7 @@
 	if (rmi4_data->button_0d_enabled == input)
 		return count;
 
+	mutex_lock(&rmi->support_fn_list_mutex);
 	if (!list_empty(&rmi->support_fn_list)) {
 		list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
 			if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) {
@@ -618,7 +619,7 @@
 						&intr_enable,
 						sizeof(intr_enable));
 				if (retval < 0)
-					return retval;
+					goto exit;
 
 				if (input == 1)
 					intr_enable |= fhandler->intr_mask;
@@ -631,14 +632,17 @@
 						&intr_enable,
 						sizeof(intr_enable));
 				if (retval < 0)
-					return retval;
+					goto exit;
 			}
 		}
 	}
-
+	mutex_unlock(&rmi->support_fn_list_mutex);
 	rmi4_data->button_0d_enabled = input;
 
 	return count;
+exit:
+	mutex_unlock(&rmi->support_fn_list_mutex);
+	return retval;
 }
 
 static ssize_t synaptics_rmi4_flipx_show(struct device *dev,
@@ -1313,6 +1317,7 @@
 	 * Traverse the function handler list and service the source(s)
 	 * of the interrupt accordingly.
 	 */
+	mutex_lock(&rmi->support_fn_list_mutex);
 	if (!list_empty(&rmi->support_fn_list)) {
 		list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
 			if (fhandler->num_of_data_sources) {
@@ -1324,6 +1329,7 @@
 			}
 		}
 	}
+	mutex_unlock(&rmi->support_fn_list_mutex);
 
 	mutex_lock(&exp_fn_list_mutex);
 	if (!list_empty(&exp_fn_list)) {
@@ -2074,10 +2080,12 @@
 
 	rmi = &(rmi4_data->rmi4_mod_info);
 
+	mutex_lock(&rmi->support_fn_list_mutex);
 	if (!list_empty(&rmi->support_fn_list))
 		list_for_each_entry(new_fhandler, &rmi->support_fn_list, link)
 			if (new_fhandler->fn_number == fhandler->fn_number)
 				found = 1;
+	mutex_unlock(&rmi->support_fn_list_mutex);
 
 	return found;
 }
@@ -2253,8 +2261,11 @@
 						fhandler);
 
 				if (!found) {
+					mutex_lock(&rmi->support_fn_list_mutex);
 					list_add_tail(&fhandler->link,
-						&rmi->support_fn_list);
+							&rmi->support_fn_list);
+					mutex_unlock(
+						&rmi->support_fn_list_mutex);
 				} else {
 					if (fhandler->fn_number ==
 							SYNAPTICS_RMI4_F1A) {
@@ -2282,20 +2293,25 @@
 	 * Map out the interrupt bit masks for the interrupt sources
 	 * from the registered function handlers.
 	 */
+	mutex_lock(&rmi->support_fn_list_mutex);
 	if (!list_empty(&rmi->support_fn_list)) {
 		list_for_each_entry(fhandler, &rmi->support_fn_list, link)
 			data_sources += fhandler->num_of_data_sources;
 	}
+	mutex_unlock(&rmi->support_fn_list_mutex);
+
 	if (data_sources) {
+		mutex_lock(&rmi->support_fn_list_mutex);
 		if (!list_empty(&rmi->support_fn_list)) {
 			list_for_each_entry(fhandler,
 						&rmi->support_fn_list, link) {
 				if (fhandler->num_of_data_sources) {
 					rmi4_data->intr_mask[fhandler->intr_reg_num] |=
-							fhandler->intr_mask;
+						fhandler->intr_mask;
 				}
 			}
 		}
+		mutex_unlock(&rmi->support_fn_list_mutex);
 	}
 
 	/* Enable the interrupt sources */
@@ -2901,6 +2917,7 @@
 	mutex_init(&(rmi4_data->rmi4_io_ctrl_mutex));
 
 	INIT_LIST_HEAD(&rmi->support_fn_list);
+	mutex_init(&rmi->support_fn_list_mutex);
 
 	retval = synaptics_rmi4_query_device(rmi4_data);
 	if (retval < 0) {
@@ -2955,12 +2972,14 @@
 	i2c_set_clientdata(client, rmi4_data);
 
 	f1a = NULL;
+	mutex_lock(&rmi->support_fn_list_mutex);
 	if (!list_empty(&rmi->support_fn_list)) {
 		list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
 			if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
 				f1a = fhandler->data;
 		}
 	}
+	mutex_unlock(&rmi->support_fn_list_mutex);
 
 	if (f1a) {
 		for (ii = 0; ii < f1a->valid_button_count; ii++) {
@@ -3073,6 +3092,7 @@
 	input_unregister_device(rmi4_data->input_dev);
 
 err_register_input:
+	mutex_lock(&rmi->support_fn_list_mutex);
 	if (!list_empty(&rmi->support_fn_list)) {
 		list_for_each_entry_safe(fhandler, next_fhandler,
 					&rmi->support_fn_list, link) {
@@ -3085,6 +3105,7 @@
 			kfree(fhandler);
 		}
 	}
+	mutex_unlock(&rmi->support_fn_list_mutex);
 err_free_gpios:
 	if (gpio_is_valid(rmi4_data->board->reset_gpio))
 		gpio_free(rmi4_data->board->reset_gpio);
@@ -3140,6 +3161,7 @@
 
 	input_unregister_device(rmi4_data->input_dev);
 
+	mutex_lock(&rmi->support_fn_list_mutex);
 	if (!list_empty(&rmi->support_fn_list)) {
 		list_for_each_entry_safe(fhandler, next_fhandler,
 					&rmi->support_fn_list, link) {
@@ -3152,6 +3174,7 @@
 			kfree(fhandler);
 		}
 	}
+	mutex_unlock(&rmi->support_fn_list_mutex);
 
 	if (gpio_is_valid(rmi4_data->board->reset_gpio))
 		gpio_free(rmi4_data->board->reset_gpio);
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.h b/drivers/input/touchscreen/synaptics_i2c_rmi4.h
index f77378a..df227fb 100644
--- a/drivers/input/touchscreen/synaptics_i2c_rmi4.h
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.h
@@ -161,6 +161,7 @@
 	unsigned char product_id_string[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
 	unsigned char build_id[SYNAPTICS_RMI4_BUILD_ID_SIZE];
 	unsigned char config_id[3];
+	struct mutex support_fn_list_mutex;
 	struct list_head support_fn_list;
 };
 
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index 7954296..e776dbb 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -713,7 +713,7 @@
 			duty_us = (led->mpp_cfg->pwm_cfg->pwm_period_us *
 					led->cdev.brightness) / LED_FULL;
 			/*config pwm for brightness scaling*/
-			rc = pwm_config(led->mpp_cfg->pwm_cfg->pwm_dev,
+			rc = pwm_config_us(led->mpp_cfg->pwm_cfg->pwm_dev,
 					duty_us,
 					led->mpp_cfg->pwm_cfg->pwm_period_us);
 			if (rc < 0) {
@@ -1239,7 +1239,7 @@
 		if (led->kpdbl_cfg->pwm_cfg->mode == PWM_MODE) {
 			duty_us = (led->kpdbl_cfg->pwm_cfg->pwm_period_us *
 				led->cdev.brightness) / KPDBL_MAX_LEVEL;
-			rc = pwm_config(led->kpdbl_cfg->pwm_cfg->pwm_dev,
+			rc = pwm_config_us(led->kpdbl_cfg->pwm_cfg->pwm_dev,
 					duty_us,
 					led->kpdbl_cfg->pwm_cfg->pwm_period_us);
 			if (rc < 0) {
@@ -1261,7 +1261,7 @@
 			led->kpdbl_cfg->pwm_cfg->default_mode;
 
 		if (led->kpdbl_cfg->always_on) {
-			rc = pwm_config(led->kpdbl_cfg->pwm_cfg->pwm_dev, 0,
+			rc = pwm_config_us(led->kpdbl_cfg->pwm_cfg->pwm_dev, 0,
 					led->kpdbl_cfg->pwm_cfg->pwm_period_us);
 			if (rc < 0) {
 				dev_err(&led->spmi_dev->dev,
@@ -1310,7 +1310,8 @@
 		if (led->rgb_cfg->pwm_cfg->mode == PWM_MODE) {
 			duty_us = (led->rgb_cfg->pwm_cfg->pwm_period_us *
 				led->cdev.brightness) / LED_FULL;
-			rc = pwm_config(led->rgb_cfg->pwm_cfg->pwm_dev, duty_us,
+			rc = pwm_config_us(led->rgb_cfg->pwm_cfg->pwm_dev,
+					duty_us,
 					led->rgb_cfg->pwm_cfg->pwm_period_us);
 			if (rc < 0) {
 				dev_err(&led->spmi_dev->dev,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
index 2be1f01..59b648d 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
@@ -122,6 +122,8 @@
 {
 	int i, rc = -1;
 	struct msm_isp_buffer_mapped_info *mapped_info;
+	struct buffer_cmd *buf_pending = NULL;
+
 	for (i = 0; i < v4l2_buf->length; i++) {
 		mapped_info = &buf_info->mapped_info[i];
 		mapped_info->handle =
@@ -144,6 +146,15 @@
 		mapped_info->paddr += v4l2_buf->m.planes[i].data_offset;
 		CDBG("%s: plane: %d addr:%lu\n",
 			__func__, i, mapped_info->paddr);
+
+		buf_pending = kzalloc(sizeof(struct buffer_cmd), GFP_ATOMIC);
+		if (!buf_pending) {
+			pr_err("No free memory for buf_pending\n");
+			return rc;
+		}
+
+		buf_pending->mapped_info = mapped_info;
+		list_add_tail(&buf_pending->list, &buf_mgr->buffer_q);
 	}
 	buf_info->num_planes = v4l2_buf->length;
 	return 0;
@@ -163,11 +174,26 @@
 {
 	int i;
 	struct msm_isp_buffer_mapped_info *mapped_info;
+	struct buffer_cmd *buf_pending = NULL;
+
 	for (i = 0; i < buf_info->num_planes; i++) {
 		mapped_info = &buf_info->mapped_info[i];
-		ion_unmap_iommu(buf_mgr->client, mapped_info->handle,
-			buf_mgr->iommu_domain_num, 0);
-		ion_free(buf_mgr->client, mapped_info->handle);
+
+		list_for_each_entry(buf_pending, &buf_mgr->buffer_q, list) {
+			if (!buf_pending)
+				break;
+
+			if (buf_pending->mapped_info == mapped_info) {
+				ion_unmap_iommu(buf_mgr->client,
+					mapped_info->handle,
+					buf_mgr->iommu_domain_num, 0);
+				ion_free(buf_mgr->client, mapped_info->handle);
+
+				list_del_init(&buf_pending->list);
+				kfree(buf_pending);
+				break;
+			}
+		}
 	}
 	return;
 }
@@ -586,7 +612,7 @@
 		}
 	} else {
 		bufq = msm_isp_get_bufq(buf_mgr, info->handle);
-		if (BUF_SRC(bufq->stream_id)) {
+		if (bufq && BUF_SRC(bufq->stream_id)) {
 			rc = msm_isp_put_buf(buf_mgr,
 					info->handle, info->buf_idx);
 			if (rc < 0) {
@@ -691,6 +717,7 @@
 		if (!bufq->bufq_handle)
 			continue;
 		msm_isp_buf_unprepare(buf_mgr, bufq->bufq_handle);
+
 		kfree(bufq->bufs);
 		msm_isp_free_buf_handle(buf_mgr, bufq->bufq_handle);
 	}
@@ -739,9 +766,10 @@
 		pr_err("Invalid buffer queue number\n");
 		return rc;
 	}
-
 	CDBG("%s: E\n", __func__);
+
 	msm_isp_attach_ctx(buf_mgr);
+	INIT_LIST_HEAD(&buf_mgr->buffer_q);
 	buf_mgr->num_buf_q = num_buf_q;
 	buf_mgr->bufq =
 		kzalloc(sizeof(struct msm_isp_bufq) * num_buf_q,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
index 6d6ff9d..d8d3ba2 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
@@ -44,6 +44,11 @@
 	struct ion_handle *handle;
 };
 
+struct buffer_cmd {
+	struct list_head list;
+	struct msm_isp_buffer_mapped_info *mapped_info;
+};
+
 struct msm_isp_buffer {
 	/*Common Data structure*/
 	int num_planes;
@@ -138,6 +143,7 @@
 
 	int num_iommu_ctx;
 	struct device *iommu_ctx[2];
+	struct list_head buffer_q;
 };
 
 int msm_isp_create_isp_buf_mgr(struct msm_isp_buf_mgr *buf_mgr,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
index 2c5e136..80a0073 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
@@ -140,6 +140,7 @@
 		&vfe_vb2_ops, &vfe_layout);
 	if (rc < 0) {
 		pr_err("%s: Unable to create buffer manager\n", __func__);
+		msm_sd_unregister(&vfe_dev->subdev);
 		kfree(vfe_dev);
 		return -EINVAL;
 	}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index 87bffde..9dd0085 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -106,7 +106,7 @@
 		uint32_t reload_mask);
 	void (*enable_wm) (struct vfe_device *vfe_dev,
 		uint8_t wm_idx, uint8_t enable);
-	void (*cfg_io_format) (struct vfe_device *vfe_dev,
+	int32_t (*cfg_io_format) (struct vfe_device *vfe_dev,
 		enum msm_vfe_axi_stream_src stream_src,
 		uint32_t io_format);
 	void (*cfg_framedrop) (struct vfe_device *vfe_dev,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
index f5529cd..410fe8f 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
@@ -74,6 +74,8 @@
 			goto fs_failed;
 		}
 	}
+	else
+		goto fs_failed;
 
 	rc = msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_1_clk_info,
 		 vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe32_1_clk_info), 1);
@@ -495,12 +497,17 @@
 	}
 }
 
-static void msm_vfe32_cfg_io_format(struct vfe_device *vfe_dev,
+static int32_t msm_vfe32_cfg_io_format(struct vfe_device *vfe_dev,
 	enum msm_vfe_axi_stream_src stream_src, uint32_t io_format)
 {
 	int bpp, bpp_reg = 0, pack_fmt = 0, pack_reg = 0;
 	uint32_t io_format_reg;
 	bpp = msm_isp_get_bit_per_pixel(io_format);
+	if (bpp < 0) {
+		pr_err("%s:%d invalid io_format %d bpp %d", __func__, __LINE__,
+			io_format, bpp);
+		return -EINVAL;
+	}
 
 	switch (bpp) {
 	case 8:
@@ -512,6 +519,9 @@
 	case 12:
 		bpp_reg = 1 << 1;
 		break;
+	default:
+		pr_err("%s:%d invalid bpp %d", __func__, __LINE__, bpp);
+		return -EINVAL;
 	}
 
 	if (stream_src == IDEAL_RAW) {
@@ -537,7 +547,7 @@
 			break;
 		default:
 			pr_err("%s: invalid pack fmt!\n", __func__);
-			return;
+			return -EINVAL;
 		}
 	}
 
@@ -558,9 +568,10 @@
 	case RDI_INTF_2:
 	default:
 		pr_err("%s: Invalid stream source\n", __func__);
-		return;
+		return -EINVAL;
 	}
 	msm_camera_io_w(io_format_reg, vfe_dev->vfe_base + 0x6F8);
+	return 0;
 }
 
 static void msm_vfe32_cfg_camif(struct vfe_device *vfe_dev,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
index 50a25bd..ad4b75f 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -268,6 +268,8 @@
 			goto fs_failed;
 		}
 	}
+	else
+		goto fs_failed;
 
 	rc = msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe40_clk_info,
 		vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe40_clk_info), 1);
@@ -724,13 +726,18 @@
 			VFE40_WM_BASE(stream_info->wm[i]) + 0x1C);
 }
 
-static void msm_vfe40_cfg_io_format(struct vfe_device *vfe_dev,
+static int32_t msm_vfe40_cfg_io_format(struct vfe_device *vfe_dev,
 	enum msm_vfe_axi_stream_src stream_src, uint32_t io_format)
 {
 	int bpp, bpp_reg = 0, pack_reg = 0;
 	enum msm_isp_pack_fmt pack_fmt = 0;
 	uint32_t io_format_reg; /*io format register bit*/
 	bpp = msm_isp_get_bit_per_pixel(io_format);
+	if (bpp < 0) {
+		pr_err("%s:%d invalid io_format %d bpp %d", __func__, __LINE__,
+			io_format, bpp);
+		return -EINVAL;
+	}
 
 	switch (bpp) {
 	case 8:
@@ -742,6 +749,9 @@
 	case 12:
 		bpp_reg = 1 << 1;
 		break;
+	default:
+		pr_err("%s:%d invalid bpp %d", __func__, __LINE__, bpp);
+		return -EINVAL;
 	}
 
 	if (stream_src == IDEAL_RAW) {
@@ -768,7 +778,7 @@
 			break;
 		default:
 			pr_err("%s: invalid pack fmt!\n", __func__);
-			return;
+			return -EINVAL;
 		}
 	}
 
@@ -789,9 +799,10 @@
 	case RDI_INTF_2:
 	default:
 		pr_err("%s: Invalid stream source\n", __func__);
-		return;
+		return -EINVAL;
 	}
 	msm_camera_io_w(io_format_reg, vfe_dev->vfe_base + 0x54);
+	return 0;
 }
 
 static void msm_vfe40_cfg_camif(struct vfe_device *vfe_dev,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index c0be135..97b6347 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -68,9 +68,17 @@
 	struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd)
 {
 	int rc = -1, i;
-	struct msm_vfe_axi_stream *stream_info =
-		&axi_data->stream_info[
-			HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle)];
+	struct msm_vfe_axi_stream *stream_info = NULL;
+	uint32_t idx = 0;
+
+	if (NULL == stream_cfg_cmd || NULL == axi_data)
+		return rc;
+
+	idx = HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle);
+	if (idx < MAX_NUM_STREAM)
+		stream_info = &axi_data->stream_info[idx];
+	else
+		return rc;
 
 	switch (stream_cfg_cmd->output_format) {
 	case V4L2_PIX_FMT_SBGGR8:
@@ -428,11 +436,22 @@
 	struct msm_vfe_axi_shared_data *axi_data,
 	struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd)
 {
-	struct msm_vfe_axi_stream *stream_info =
-		&axi_data->stream_info[
-		HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle)];
-	uint32_t framedrop_period = msm_isp_get_framedrop_period(
-	   stream_cfg_cmd->frame_skip_pattern);
+	struct msm_vfe_axi_stream *stream_info = NULL;
+	uint32_t framedrop_period = 0;
+	uint8_t idx = 0;
+
+	if (NULL == axi_data || NULL == stream_cfg_cmd)
+		return;
+
+	idx = HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle);
+
+	if (idx < MAX_NUM_STREAM)
+		stream_info = &axi_data->stream_info[idx];
+	else
+		return;
+
+	framedrop_period = msm_isp_get_framedrop_period(
+			stream_cfg_cmd->frame_skip_pattern);
 
 	if (stream_cfg_cmd->frame_skip_pattern == SKIP_ALL)
 		stream_info->framedrop_pattern = 0x0;
@@ -520,8 +539,17 @@
 
 			io_format = stream_info->output_format;
 		}
-		vfe_dev->hw_info->vfe_ops.axi_ops.cfg_io_format(
+		rc = vfe_dev->hw_info->vfe_ops.axi_ops.cfg_io_format(
 			vfe_dev, stream_info->stream_src, io_format);
+		if (rc) {
+			pr_err("%s: cfg io format failed\n", __func__);
+			msm_isp_axi_free_wm(&vfe_dev->axi_data,
+				stream_info);
+			msm_isp_axi_destroy_stream(&vfe_dev->axi_data,
+				HANDLE_TO_IDX(
+				stream_cfg_cmd->axi_stream_handle));
+			return rc;
+		}
 	}
 
 	msm_isp_calculate_framedrop(&vfe_dev->axi_data, stream_cfg_cmd);
@@ -763,8 +791,9 @@
 	rc = vfe_dev->buf_mgr->ops->get_buf(vfe_dev->buf_mgr,
 			vfe_dev->pdev->id, bufq_handle, &buf);
 	if (rc < 0) {
-		vfe_dev->error_info.
-			stream_framedrop_count[stream_idx]++;
+		if(stream_idx < MAX_NUM_STREAM)
+			vfe_dev->error_info.
+				stream_framedrop_count[stream_idx]++;
 		return rc;
 	}
 
@@ -1160,8 +1189,14 @@
 			 * since for burst case, write masters already skip
 			 * all frames.
 			 */
+			if (stream_info->stream_src == RDI_INTF_0 ||
+				stream_info->stream_src == RDI_INTF_1 ||
+				stream_info->stream_src == RDI_INTF_2)
+				wait_for_complete = 1;
+			else {
 			msm_isp_axi_stream_enable_cfg(vfe_dev, stream_info);
 			stream_info->state = INACTIVE;
+			}
 		} else {
 			wait_for_complete = 1;
 		}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
index b479857..8b83144 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
@@ -39,8 +39,9 @@
 	rc = vfe_dev->buf_mgr->ops->get_buf(vfe_dev->buf_mgr,
 			vfe_dev->pdev->id, bufq_handle, &buf);
 	if (rc < 0) {
-		vfe_dev->error_info.stats_framedrop_count[
-			STATS_IDX(stream_info->stream_handle)]++;
+		uint8_t idx = STATS_IDX(stream_info->stream_handle);
+		if (idx < MSM_ISP_STATS_MAX)
+			vfe_dev->error_info.stats_framedrop_count[idx]++;
 		return rc;
 	}
 
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index ea0195d..3cb48d1 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -77,6 +77,25 @@
 	.name = "msm_camera_isp",
 };
 
+static void msm_isp_print_fourcc_error(const char *origin,
+	uint32_t fourcc_format)
+{
+	int i;
+	char text[5];
+	text[4] = '\0';
+	for (i = 0; i < 4; i++) {
+		text[i] = (char)(((fourcc_format) >> (i * 8)) & 0xFF);
+		if ((text[i] < '0') || (text[i] > 'z')) {
+			pr_err("%s: Invalid output format %d (unprintable)\n",
+				origin, fourcc_format);
+			return;
+		}
+	}
+	pr_err("%s: Invalid output format %s\n",
+		origin, text);
+	return;
+}
+
 int msm_isp_init_bandwidth_mgr(enum msm_isp_hw_client client)
 {
 	int rc = 0;
@@ -735,7 +754,7 @@
 		break;
 		/*TD: Add more image format*/
 	default:
-		pr_err("%s: Invalid output format\n", __func__);
+		msm_isp_print_fourcc_error(__func__, output_format);
 		break;
 	}
 	return val;
@@ -771,7 +790,7 @@
 	case V4L2_PIX_FMT_QRGGB12:
 		return QCOM;
 	default:
-		pr_err("%s: Invalid output format\n", __func__);
+		msm_isp_print_fourcc_error(__func__, output_format);
 		break;
 	}
 	return -EINVAL;
@@ -780,6 +799,10 @@
 int msm_isp_get_bit_per_pixel(uint32_t output_format)
 {
 	switch (output_format) {
+	case V4L2_PIX_FMT_Y4:
+		return 4;
+	case V4L2_PIX_FMT_Y6:
+		return 6;
 	case V4L2_PIX_FMT_SBGGR8:
 	case V4L2_PIX_FMT_SGBRG8:
 	case V4L2_PIX_FMT_SGRBG8:
@@ -790,6 +813,29 @@
 	case V4L2_PIX_FMT_QRGGB8:
 	case V4L2_PIX_FMT_JPEG:
 	case V4L2_PIX_FMT_META:
+	case V4L2_PIX_FMT_NV12:
+	case V4L2_PIX_FMT_NV21:
+	case V4L2_PIX_FMT_NV14:
+	case V4L2_PIX_FMT_NV41:
+	case V4L2_PIX_FMT_YVU410:
+	case V4L2_PIX_FMT_YVU420:
+	case V4L2_PIX_FMT_YUYV:
+	case V4L2_PIX_FMT_YYUV:
+	case V4L2_PIX_FMT_YVYU:
+	case V4L2_PIX_FMT_UYVY:
+	case V4L2_PIX_FMT_VYUY:
+	case V4L2_PIX_FMT_YUV422P:
+	case V4L2_PIX_FMT_YUV411P:
+	case V4L2_PIX_FMT_Y41P:
+	case V4L2_PIX_FMT_YUV444:
+	case V4L2_PIX_FMT_YUV555:
+	case V4L2_PIX_FMT_YUV565:
+	case V4L2_PIX_FMT_YUV32:
+	case V4L2_PIX_FMT_YUV410:
+	case V4L2_PIX_FMT_YUV420:
+	case V4L2_PIX_FMT_GREY:
+	case V4L2_PIX_FMT_PAL8:
+	case MSM_V4L2_PIX_FMT_META:
 		return 8;
 	case V4L2_PIX_FMT_SBGGR10:
 	case V4L2_PIX_FMT_SGBRG10:
@@ -799,6 +845,8 @@
 	case V4L2_PIX_FMT_QGBRG10:
 	case V4L2_PIX_FMT_QGRBG10:
 	case V4L2_PIX_FMT_QRGGB10:
+	case V4L2_PIX_FMT_Y10:
+	case V4L2_PIX_FMT_Y10BPACK:
 		return 10;
 	case V4L2_PIX_FMT_SBGGR12:
 	case V4L2_PIX_FMT_SGBRG12:
@@ -808,21 +856,17 @@
 	case V4L2_PIX_FMT_QGBRG12:
 	case V4L2_PIX_FMT_QGRBG12:
 	case V4L2_PIX_FMT_QRGGB12:
+	case V4L2_PIX_FMT_Y12:
 		return 12;
-	case V4L2_PIX_FMT_NV12:
-	case V4L2_PIX_FMT_NV21:
-	case V4L2_PIX_FMT_NV14:
-	case V4L2_PIX_FMT_NV41:
-		return 8;
 	case V4L2_PIX_FMT_NV16:
 	case V4L2_PIX_FMT_NV61:
+	case V4L2_PIX_FMT_Y16:
 		return 16;
 		/*TD: Add more image format*/
 	default:
-		pr_err("%s: Invalid output format\n", __func__);
-		break;
+		msm_isp_print_fourcc_error(__func__, output_format);
+		return -EINVAL;
 	}
-	return -EINVAL;
 }
 
 void msm_isp_update_error_frame_count(struct vfe_device *vfe_dev)
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c
index 77df737..44a4014 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c
@@ -337,6 +337,11 @@
 				__LINE__, hw_cmd_p->offset, max_size);
 			return -EFAULT;
 		}
+		if (hw_cmd_p->offset & 0x3) {
+			JPEG_PR_ERR("%s:%d] %d Invalid alignment\n", __func__,
+					__LINE__, hw_cmd_p->offset);
+			return -EFAULT;
+		}
 
 		switch (hw_cmd_p->type) {
 		case MSM_JPEG_HW_CMD_TYPE_READ:
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
index 8f080ce..407b81f 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
@@ -31,14 +31,19 @@
 int msm_jpeg_platform_set_clk_rate(struct msm_jpeg_device *pgmn_dev,
 		long clk_rate)
 {
-	struct msm_cam_clk_info jpeg_core_clk_info[] = {
-		{"core_clk", JPEG_CLK_RATE, 0}
-	};
+	int rc = 0;
+	struct clk *jpeg_clk;
 
-	jpeg_core_clk_info[0].clk_rate = clk_rate;
+	jpeg_clk = clk_get(&pgmn_dev->pdev->dev, "core_clk");
+	if (IS_ERR(jpeg_clk)) {
+		JPEG_PR_ERR("%s get failed\n", "core_clk");
+		rc = PTR_ERR(jpeg_clk);
+		return rc;
+	}
 
-	return msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_core_clk_info,
-			pgmn_dev->jpeg_clk, ARRAY_SIZE(jpeg_core_clk_info), 1);
+	rc = clk_set_rate(jpeg_clk, clk_rate);
+
+	return rc;
 }
 
 void msm_jpeg_platform_p2v(struct msm_jpeg_device *pgmn_dev, struct file  *file,
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
index f7241dd..5cc51ff 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
@@ -669,6 +669,8 @@
 			JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
 			return -EFAULT;
 		}
+	} else {
+		return is_copy_to_user;
 	}
 
 	return 0;
diff --git a/drivers/media/platform/msm/camera_v2/msm.c b/drivers/media/platform/msm/camera_v2/msm.c
index efa3ad0..8a2c8e5 100644
--- a/drivers/media/platform/msm/camera_v2/msm.c
+++ b/drivers/media/platform/msm/camera_v2/msm.c
@@ -438,7 +438,7 @@
 static inline int __msm_destroy_session_streams(void *d1, void *d2)
 {
 	struct msm_stream *stream = d1;
-
+	pr_err("%s: Destroyed here due to list is not empty\n", __func__);
 	INIT_LIST_HEAD(&stream->queued_list);
 	return 0;
 }
@@ -1001,8 +1001,10 @@
 	video_set_drvdata(pvdev->vdev, pvdev);
 
 	msm_session_q = kzalloc(sizeof(*msm_session_q), GFP_KERNEL);
-	if (WARN_ON(!msm_session_q))
-		goto v4l2_fail;
+	if (WARN_ON(!msm_session_q)) {
+		rc = -ENOMEM;
+		goto session_fail;
+	}
 
 	msm_init_queue(msm_session_q);
 	spin_lock_init(&msm_eventq_lock);
@@ -1010,6 +1012,8 @@
 	INIT_LIST_HEAD(&ordered_sd_list);
 	goto probe_end;
 
+session_fail:
+	video_unregister_device(pvdev->vdev);
 v4l2_fail:
 	v4l2_device_unregister(pvdev->vdev->v4l2_dev);
 register_fail:
diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
index 154ee87..7520ce5 100644
--- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
@@ -100,6 +100,24 @@
 	return ret;
 }
 
+static void msm_buf_mngr_sd_shutdown(struct msm_buf_mngr_device *buf_mngr_dev)
+{
+	unsigned long flags;
+	struct msm_get_bufs *bufs, *save;
+
+	spin_lock_irqsave(&buf_mngr_dev->buf_q_spinlock, flags);
+	if (!list_empty(&buf_mngr_dev->buf_qhead)) {
+		list_for_each_entry_safe(bufs,
+			save, &buf_mngr_dev->buf_qhead, entry) {
+			pr_err("%s: Delete invalid bufs =%x\n", __func__,
+				(unsigned int)bufs);
+			list_del_init(&bufs->entry);
+			kfree(bufs);
+		}
+	}
+	spin_unlock_irqrestore(&buf_mngr_dev->buf_q_spinlock, flags);
+}
+
 static long msm_buf_mngr_subdev_ioctl(struct v4l2_subdev *sd,
 	unsigned int cmd, void *arg)
 {
@@ -123,6 +141,9 @@
 	case VIDIOC_MSM_BUF_MNGR_PUT_BUF:
 		rc = msm_buf_mngr_put_buf(buf_mngr_dev, argp);
 		break;
+	case MSM_SD_SHUTDOWN:
+		msm_buf_mngr_sd_shutdown(buf_mngr_dev);
+		break;
 	default:
 		return -ENOIOCTLCMD;
 	}
diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
index 8fa8f8d..0fbaeca 100644
--- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
+++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
@@ -251,6 +251,7 @@
 	unsigned long flags;
 	struct msm_vb2_buffer *msm_vb2;
 	struct msm_stream *stream;
+	struct vb2_buffer *vb2_buf = NULL;
 	int rc = 0;
 
 	stream = msm_get_stream(session_id, stream_id);
@@ -258,6 +259,18 @@
 		return 0;
 	spin_lock_irqsave(&stream->stream_lock, flags);
 	if (vb) {
+		list_for_each_entry(msm_vb2, &(stream->queued_list), list) {
+			vb2_buf = &(msm_vb2->vb2_buf);
+			if (vb2_buf == vb)
+				break;
+		}
+		if (vb2_buf != vb) {
+			pr_err("%s:%d VB buffer is INVALID vb=%x, ses_id=%d, str_id=%d\n",
+				__func__, __LINE__, (unsigned int)vb,
+				session_id, stream_id);
+			rc = -EINVAL;
+			goto out;
+		}
 		msm_vb2 =
 			container_of(vb, struct msm_vb2_buffer, vb2_buf);
 		/* put buf before buf done */
@@ -268,10 +281,11 @@
 		} else
 			rc = -EINVAL;
 	} else {
-		pr_err("%s: VB buffer is null\n", __func__);
+		pr_err("%s:%d VB buffer is NULL for ses_id=%d, str_id=%d\n",
+			__func__, __LINE__, session_id, stream_id);
 		rc = -EINVAL;
 	}
-
+out:
 	spin_unlock_irqrestore(&stream->stream_lock, flags);
 	return rc;
 }
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index 63973b4..532bebc 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -57,14 +57,12 @@
 };
 
 struct msm_cpp_timer_t {
-	uint8_t used;
+	atomic_t used;
 	struct msm_cpp_timer_data_t data;
 	struct timer_list cpp_timer;
 };
 
-struct msm_cpp_timer_t cpp_timers[2];
-static int del_timer_idx;
-static int set_timer_idx;
+struct msm_cpp_timer_t cpp_timer;
 
 /* dump the frame command before writing to the hardware */
 #define  MSM_CPP_DUMP_FRM_CMD 0
@@ -596,24 +594,20 @@
 				if (msg_id == MSM_CPP_MSG_ID_FRAME_ACK) {
 					CPP_DBG("Frame done!!\n");
 					/* delete CPP timer */
-					CPP_DBG("delete timer %d.\n",
-						del_timer_idx);
-					timer = &cpp_timers[del_timer_idx];
+					CPP_DBG("delete timer.\n");
+					timer = &cpp_timer;
+					atomic_set(&timer->used, 0);
 					del_timer(&timer->cpp_timer);
-					timer->used = 0;
 					timer->data.processed_frame = NULL;
-					del_timer_idx = 1 - del_timer_idx;
 					msm_cpp_notify_frame_done(cpp_dev);
 				} else if (msg_id ==
 					MSM_CPP_MSG_ID_FRAME_NACK) {
 					pr_err("NACK error from hw!!\n");
-					CPP_DBG("delete timer %d.\n",
-						del_timer_idx);
-					timer = &cpp_timers[del_timer_idx];
+					CPP_DBG("delete timer.\n");
+					timer = &cpp_timer;
+					atomic_set(&timer->used, 0);
 					del_timer(&timer->cpp_timer);
-					timer->used = 0;
 					timer->data.processed_frame = NULL;
-					del_timer_idx = 1 - del_timer_idx;
 					msm_cpp_notify_frame_done(cpp_dev);
 				}
 				i += cmd_len + 2;
@@ -1077,97 +1071,62 @@
 {
 	int ret;
 	uint32_t i = 0;
-	struct msm_cpp_frame_info_t *this_frame =
-		cpp_timers[del_timer_idx].data.processed_frame;
-	struct msm_cpp_frame_info_t *second_frame = NULL;
+	struct msm_cpp_frame_info_t *this_frame = NULL;
 
-	pr_err("cpp_timer_callback called idx:%d. (jiffies=%lu)\n",
-		del_timer_idx, jiffies);
-	if (!work || !this_frame) {
-		pr_err("Invalid work:%p, this_frame:%p, del_idx:%d\n",
-			work, this_frame, del_timer_idx);
+	pr_err("cpp_timer_callback called. (jiffies=%lu)\n",
+		jiffies);
+	if (!work) {
+		pr_err("Invalid work:%p\n", work);
 		return;
 	}
-	pr_err("fatal: cpp_timer expired for identity=0x%x, frame_id=%03d",
-		this_frame->identity, this_frame->frame_id);
-	cpp_timers[del_timer_idx].used = 0;
-	cpp_timers[del_timer_idx].data.processed_frame = NULL;
-	del_timer_idx = 1 - del_timer_idx;
-
-	if (cpp_timers[del_timer_idx].used == 1) {
-		pr_err("deleting cpp_timer %d.\n", del_timer_idx);
-		del_timer(&cpp_timers[del_timer_idx].cpp_timer);
-		cpp_timers[del_timer_idx].used = 0;
-		second_frame = cpp_timers[del_timer_idx].data.processed_frame;
-		cpp_timers[del_timer_idx].data.processed_frame = NULL;
-		del_timer_idx = 1 - del_timer_idx;
+	if (!atomic_read(&cpp_timer.used)) {
+		pr_err("Delayed trigger, IRQ serviced\n");
+		return;
 	}
 
-	disable_irq(cpp_timers[del_timer_idx].data.cpp_dev->irq->start);
+	disable_irq(cpp_timer.data.cpp_dev->irq->start);
 	pr_err("Reloading firmware\n");
-	cpp_load_fw(cpp_timers[del_timer_idx].data.cpp_dev, NULL);
+	cpp_load_fw(cpp_timer.data.cpp_dev, NULL);
 	pr_err("Firmware loading done\n");
-	enable_irq(cpp_timers[del_timer_idx].data.cpp_dev->irq->start);
-	msm_camera_io_w_mb(0x8, cpp_timers[del_timer_idx].data.cpp_dev->base +
+	enable_irq(cpp_timer.data.cpp_dev->irq->start);
+	msm_camera_io_w_mb(0x8, cpp_timer.data.cpp_dev->base +
 		MSM_CPP_MICRO_IRQGEN_MASK);
 	msm_camera_io_w_mb(0xFFFF,
-		cpp_timers[del_timer_idx].data.cpp_dev->base +
+		cpp_timer.data.cpp_dev->base +
 		MSM_CPP_MICRO_IRQGEN_CLR);
 
-	cpp_timers[set_timer_idx].data.processed_frame = this_frame;
-	cpp_timers[set_timer_idx].used = 1;
-	pr_err("ReInstalling cpp_timer %d\n", set_timer_idx);
-	setup_timer(&cpp_timers[set_timer_idx].cpp_timer, cpp_timer_callback,
-		(unsigned long)&cpp_timers[0]);
+	if (!atomic_read(&cpp_timer.used)) {
+		pr_err("Delayed trigger, IRQ serviced\n");
+		return;
+	}
+
+	this_frame = cpp_timer.data.processed_frame;
+	pr_err("ReInstalling cpp_timer\n");
+	setup_timer(&cpp_timer.cpp_timer, cpp_timer_callback,
+		(unsigned long)&cpp_timer);
 	pr_err("Starting timer to fire in %d ms. (jiffies=%lu)\n",
 		CPP_CMD_TIMEOUT_MS, jiffies);
-	ret = mod_timer(&cpp_timers[set_timer_idx].cpp_timer,
+	ret = mod_timer(&cpp_timer.cpp_timer,
 		jiffies + msecs_to_jiffies(CPP_CMD_TIMEOUT_MS));
 	if (ret)
 		pr_err("error in mod_timer\n");
 
-	set_timer_idx = 1 - set_timer_idx;
-	pr_err("Rescheduling for identity=0x%x, frame_id=%03d",
+	pr_err("Rescheduling for identity=0x%x, frame_id=%03d\n",
 		this_frame->identity, this_frame->frame_id);
-	msm_cpp_write(0x6, cpp_timers[set_timer_idx].data.cpp_dev->base);
+	msm_cpp_write(0x6, cpp_timer.data.cpp_dev->base);
 	msm_cpp_dump_frame_cmd(this_frame->cpp_cmd_msg,
 		this_frame->msg_len);
 	for (i = 0; i < this_frame->msg_len; i++)
 		msm_cpp_write(this_frame->cpp_cmd_msg[i],
-			cpp_timers[set_timer_idx].data.cpp_dev->base);
-
-
-	if (second_frame != NULL) {
-		cpp_timers[set_timer_idx].data.processed_frame = second_frame;
-		cpp_timers[set_timer_idx].used = 1;
-		pr_err("ReInstalling cpp_timer %d\n", set_timer_idx);
-		setup_timer(&cpp_timers[set_timer_idx].cpp_timer,
-			cpp_timer_callback, (unsigned long)&cpp_timers[0]);
-		pr_err("Starting timer to fire in %d ms. (jiffies=%lu)\n",
-			CPP_CMD_TIMEOUT_MS, jiffies);
-		ret = mod_timer(&cpp_timers[set_timer_idx].cpp_timer,
-			jiffies + msecs_to_jiffies(CPP_CMD_TIMEOUT_MS));
-		if (ret)
-			pr_err("error in mod_timer\n");
-
-		set_timer_idx = 1 - set_timer_idx;
-		pr_err("Rescheduling for identity=0x%x, frame_id=%03d",
-			second_frame->identity, second_frame->frame_id);
-		msm_cpp_write(0x6,
-			cpp_timers[set_timer_idx].data.cpp_dev->base);
-		msm_cpp_dump_frame_cmd(second_frame->cpp_cmd_msg,
-			second_frame->msg_len);
-		for (i = 0; i < second_frame->msg_len; i++)
-			msm_cpp_write(second_frame->cpp_cmd_msg[i],
-				cpp_timers[set_timer_idx].data.cpp_dev->base);
-	}
+			cpp_timer.data.cpp_dev->base);
+	return;
 }
 
 void cpp_timer_callback(unsigned long data)
 {
 	struct msm_cpp_work_t *work =
-		cpp_timers[set_timer_idx].data.cpp_dev->work;
-	queue_work(cpp_timers[set_timer_idx].data.cpp_dev->timer_wq,
+		cpp_timer.data.cpp_dev->work;
+	queue_work(cpp_timer.data.cpp_dev->timer_wq,
 		(struct work_struct *)work);
 }
 
@@ -1184,21 +1143,19 @@
 		msm_enqueue(&cpp_dev->processing_q,
 					&frame_qcmd->list_frame);
 
-		cpp_timers[set_timer_idx].data.processed_frame = process_frame;
-		cpp_timers[set_timer_idx].used = 1;
+		cpp_timer.data.processed_frame = process_frame;
+		atomic_set(&cpp_timer.used, 1);
 		/* install timer for cpp timeout */
-		CPP_DBG("Installing cpp_timer %d\n", set_timer_idx);
-		setup_timer(&cpp_timers[set_timer_idx].cpp_timer,
-			cpp_timer_callback, (unsigned long)&cpp_timers[0]);
+		CPP_DBG("Installing cpp_timer\n");
+		setup_timer(&cpp_timer.cpp_timer,
+			cpp_timer_callback, (unsigned long)&cpp_timer);
 		CPP_DBG("Starting timer to fire in %d ms. (jiffies=%lu)\n",
 			CPP_CMD_TIMEOUT_MS, jiffies);
-		ret = mod_timer(&cpp_timers[set_timer_idx].cpp_timer,
+		ret = mod_timer(&cpp_timer.cpp_timer,
 			jiffies + msecs_to_jiffies(CPP_CMD_TIMEOUT_MS));
 		if (ret)
 			pr_err("error in mod_timer\n");
 
-		set_timer_idx = 1 - set_timer_idx;
-
 		msm_cpp_write(0x6, cpp_dev->base);
 		msm_cpp_dump_frame_cmd(process_frame->cpp_cmd_msg,
 				process_frame->msg_len);
@@ -1888,13 +1845,16 @@
 	cpp_dev->timer_wq = create_workqueue("msm_cpp_workqueue");
 	cpp_dev->work = kmalloc(sizeof(struct msm_cpp_work_t),
 		GFP_KERNEL);
+	if (!cpp_dev->work) {
+		pr_err("cpp_dev->work is NULL\n");
+		rc = -ENOMEM;
+		goto ERROR3;
+	}
 	INIT_WORK((struct work_struct *)cpp_dev->work, msm_cpp_do_timeout_work);
 	cpp_dev->cpp_open_cnt = 0;
 	cpp_dev->is_firmware_loaded = 0;
-	cpp_timers[0].data.cpp_dev = cpp_dev;
-	cpp_timers[1].data.cpp_dev = cpp_dev;
-	cpp_timers[0].used = 0;
-	cpp_timers[1].used = 0;
+	cpp_timer.data.cpp_dev = cpp_dev;
+	atomic_set(&cpp_timer.used, 0);
 	cpp_dev->fw_name_bin = NULL;
 	return rc;
 ERROR3:
diff --git a/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c b/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c
index dc29199..8d14363 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c
@@ -691,43 +691,47 @@
 
 	if (queue->len > 0) {
 		frame_qcmd = msm_dequeue(queue, list_frame);
-		processed_frame = frame_qcmd->command;
-		do_gettimeofday(&(processed_frame->out_time));
-		kfree(frame_qcmd);
-		event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_ATOMIC);
-		if (!event_qcmd) {
-			pr_err("%s: Insufficient memory\n", __func__);
-			return -ENOMEM;
-		}
-		atomic_set(&event_qcmd->on_heap, 1);
-		event_qcmd->command = processed_frame;
-		VPE_DBG("fid %d\n", processed_frame->frame_id);
-		msm_enqueue(&vpe_dev->eventData_q, &event_qcmd->list_eventdata);
+		if(frame_qcmd) {
+			processed_frame = frame_qcmd->command;
+			do_gettimeofday(&(processed_frame->out_time));
+			kfree(frame_qcmd);
+			event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_ATOMIC);
+			if (!event_qcmd) {
+				pr_err("%s: Insufficient memory\n", __func__);
+				return -ENOMEM;
+			}
+			atomic_set(&event_qcmd->on_heap, 1);
+			event_qcmd->command = processed_frame;
+			VPE_DBG("fid %d\n", processed_frame->frame_id);
+			msm_enqueue(&vpe_dev->eventData_q, &event_qcmd->list_eventdata);
 
-		if (!processed_frame->output_buffer_info.processed_divert) {
-			memset(&buff_mgr_info, 0 ,
-				sizeof(buff_mgr_info));
-			buff_mgr_info.session_id =
-				((processed_frame->identity >> 16) & 0xFFFF);
-			buff_mgr_info.stream_id =
-				(processed_frame->identity & 0xFFFF);
-			buff_mgr_info.frame_id = processed_frame->frame_id;
-			buff_mgr_info.timestamp = processed_frame->timestamp;
-			buff_mgr_info.index =
-				processed_frame->output_buffer_info.index;
-			rc = msm_vpe_buffer_ops(vpe_dev,
+			if (!processed_frame->output_buffer_info.processed_divert) {
+				memset(&buff_mgr_info, 0 ,
+					sizeof(buff_mgr_info));
+				buff_mgr_info.session_id =
+					((processed_frame->identity >> 16) & 0xFFFF);
+				buff_mgr_info.stream_id =
+					(processed_frame->identity & 0xFFFF);
+				buff_mgr_info.frame_id = processed_frame->frame_id;
+				buff_mgr_info.timestamp = processed_frame->timestamp;
+				buff_mgr_info.index =
+					processed_frame->output_buffer_info.index;
+				rc = msm_vpe_buffer_ops(vpe_dev,
 						VIDIOC_MSM_BUF_MNGR_BUF_DONE,
 						&buff_mgr_info);
-			if (rc < 0) {
-				pr_err("%s: error doing VIDIOC_MSM_BUF_MNGR_BUF_DONE\n",
-					__func__);
-				rc = -EINVAL;
+				if (rc < 0) {
+					pr_err("%s: error doing VIDIOC_MSM_BUF_MNGR_BUF_DONE\n",
+						__func__);
+					rc = -EINVAL;
+				}
 			}
-		}
 
-		v4l2_evt.id = processed_frame->inst_id;
-		v4l2_evt.type = V4L2_EVENT_VPE_FRAME_DONE;
-		v4l2_event_queue(vpe_dev->msm_sd.sd.devnode, &v4l2_evt);
+			v4l2_evt.id = processed_frame->inst_id;
+			v4l2_evt.type = V4L2_EVENT_VPE_FRAME_DONE;
+			v4l2_event_queue(vpe_dev->msm_sd.sd.devnode, &v4l2_evt);
+		}
+		else
+			rc = -EFAULT;
 	}
 	return rc;
 }
@@ -1368,6 +1372,8 @@
 		struct msm_vpe_frame_info_t *process_frame;
 		VPE_DBG("VIDIOC_MSM_VPE_GET_EVENTPAYLOAD\n");
 		event_qcmd = msm_dequeue(queue, list_eventdata);
+		if (NULL == event_qcmd)
+			break;
 		process_frame = event_qcmd->command;
 		VPE_DBG("fid %d\n", process_frame->frame_id);
 		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
index 45db19c..69c1faa 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
@@ -809,6 +809,7 @@
 	e_ctrl->is_supported = 0;
 	if (!of_node) {
 		pr_err("%s dev.of_node NULL\n", __func__);
+		kfree(e_ctrl);
 		return -EINVAL;
 	}
 
@@ -817,6 +818,7 @@
 	CDBG("cell-index %d, rc %d\n", pdev->id, rc);
 	if (rc < 0) {
 		pr_err("failed rc %d\n", rc);
+		kfree(e_ctrl);
 		return rc;
 	}
 	e_ctrl->subdev_id = pdev->id;
@@ -826,12 +828,14 @@
 	CDBG("qcom,cci-master %d, rc %d\n", e_ctrl->cci_master, rc);
 	if (rc < 0) {
 		pr_err("%s failed rc %d\n", __func__, rc);
+		kfree(e_ctrl);
 		return rc;
 	}
 	rc = of_property_read_u32(of_node, "qcom,slave-addr",
 		&temp);
 	if (rc < 0) {
 		pr_err("%s failed rc %d\n", __func__, rc);
+		kfree(e_ctrl);
 		return rc;
 	}
 
@@ -844,6 +848,7 @@
 		struct msm_camera_cci_client), GFP_KERNEL);
 	if (!e_ctrl->i2c_client.cci_client) {
 		pr_err("%s failed no memory\n", __func__);
+		kfree(e_ctrl);
 		return -ENOMEM;
 	}
 
@@ -936,6 +941,7 @@
 	kfree(e_ctrl->eboard_info);
 cciclient_free:
 	kfree(e_ctrl->i2c_client.cci_client);
+	kfree(e_ctrl);
 	return rc;
 }
 
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h
index 9f3a81c..a4d7f15 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h
@@ -53,9 +53,11 @@
 	const char *flash_trigger_name[MAX_LED_TRIGGERS];
 	struct led_trigger *flash_trigger[MAX_LED_TRIGGERS];
 	uint32_t flash_op_current[MAX_LED_TRIGGERS];
+	uint32_t flash_max_current[MAX_LED_TRIGGERS];
 	const char *torch_trigger_name;
 	struct led_trigger *torch_trigger;
 	uint32_t torch_op_current;
+	uint32_t torch_max_current;
 	void *data;
 	uint32_t num_sources;
 	enum msm_camera_device_type_t flash_device_type;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
index 01d2c13..b88ac00 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
@@ -51,6 +51,7 @@
 	int rc = 0;
 	struct msm_camera_led_cfg_t *cfg = (struct msm_camera_led_cfg_t *)data;
 	uint32_t i;
+	uint32_t curr_l, max_curr_l;
 	CDBG("called led_state %d\n", cfg->cfgtype);
 
 	if (!fctrl) {
@@ -68,18 +69,38 @@
 		break;
 
 	case MSM_CAMERA_LED_LOW:
-		if (fctrl->torch_trigger)
+		if (fctrl->torch_trigger) {
+			max_curr_l = fctrl->torch_max_current;
+			if (cfg->torch_current > 0 &&
+					cfg->torch_current < max_curr_l) {
+				curr_l = cfg->torch_current;
+			} else {
+				curr_l = fctrl->torch_op_current;
+				pr_err("LED current clamped to %d\n",
+					curr_l);
+			}
 			led_trigger_event(fctrl->torch_trigger,
-				fctrl->torch_op_current);
+				curr_l);
+		}
 		break;
 
 	case MSM_CAMERA_LED_HIGH:
 		if (fctrl->torch_trigger)
 			led_trigger_event(fctrl->torch_trigger, 0);
 		for (i = 0; i < fctrl->num_sources; i++)
-			if (fctrl->flash_trigger[i])
+			if (fctrl->flash_trigger[i]) {
+				max_curr_l = fctrl->flash_max_current[i];
+				if (cfg->flash_current[i] > 0 &&
+						cfg->flash_current[i] < max_curr_l) {
+					curr_l = cfg->flash_current[i];
+				} else {
+					curr_l = fctrl->flash_op_current[i];
+					pr_err("LED current clamped to %d\n",
+						curr_l);
+				}
 				led_trigger_event(fctrl->flash_trigger[i],
-					fctrl->flash_op_current[i]);
+					curr_l);
+			}
 		break;
 
 	case MSM_CAMERA_LED_INIT:
@@ -116,7 +137,7 @@
 
 static int32_t msm_led_trigger_probe(struct platform_device *pdev)
 {
-	int32_t rc = 0, i = 0;
+	int32_t rc = 0, rc_1 = 0, i = 0;
 	struct device_node *of_node = pdev->dev.of_node;
 	struct device_node *flash_src_node = NULL;
 	uint32_t count = 0;
@@ -181,7 +202,10 @@
 				rc = of_property_read_u32(flash_src_node,
 					"qcom,current",
 					&fctrl.flash_op_current[i]);
-				if (rc < 0) {
+				rc_1 = of_property_read_u32(flash_src_node,
+					"qcom,max-current",
+					&fctrl.flash_max_current[i]);
+				if ((rc < 0) || (rc_1 < 0)) {
 					pr_err("current: read failed\n");
 					of_node_put(flash_src_node);
 					continue;
@@ -229,7 +253,11 @@
 				rc = of_property_read_u32(flash_src_node,
 					"qcom,current",
 					&fctrl.torch_op_current);
-				if (rc < 0) {
+				rc_1 = of_property_read_u32(flash_src_node,
+					"qcom,max-current",
+					&fctrl.torch_max_current);
+
+				if ((rc < 0) || (rc_1 < 0)) {
 					pr_err("current: read failed\n");
 					goto torch_failed;
 				}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c
index 484dd69..336c922 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c
@@ -669,7 +669,9 @@
 			}
 			gpio_set_value_cansleep(
 				ctrl->gpio_conf->gpio_num_info->gpio_num
-				[power_setting->seq_val], GPIOF_OUT_INIT_LOW);
+				[power_setting->seq_val],
+				ctrl->gpio_conf->gpio_num_info->gpio_num
+				[power_setting->config_val]);
 			break;
 		case SENSOR_VREG:
 			if (power_setting->seq_val >= CAM_VREG_MAX) {
diff --git a/drivers/media/platform/msm/camera_v2/sensor/sp1628.c b/drivers/media/platform/msm/camera_v2/sensor/sp1628.c
old mode 100644
new mode 100755
index 82e4b7c..9a422c0
--- a/drivers/media/platform/msm/camera_v2/sensor/sp1628.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/sp1628.c
@@ -866,6 +866,42 @@
 		}
 		break;
 	}
+	case CFG_SET_SATURATION: {
+
+		break;
+	}
+	case CFG_SET_CONTRAST: {
+
+		break;
+	}
+	case CFG_SET_SHARPNESS: {
+
+		break;
+	}
+	case CFG_SET_ISO: {
+
+		break;
+	}
+	case CFG_SET_EXPOSURE_COMPENSATION: {
+
+		break;
+	}
+	case CFG_SET_EFFECT: {
+
+		break;
+	}
+	case CFG_SET_ANTIBANDING: {
+
+		break;
+	}
+	case CFG_SET_BESTSHOT_MODE: {
+
+		break;
+	}
+	case CFG_SET_WHITE_BALANCE: {
+
+		break;
+	}
 	default:
 		rc = -EFAULT;
 		break;
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
index 19a378f..5694658 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
@@ -3964,6 +3964,58 @@
 }
 EXPORT_SYMBOL(mpq_dmx_set_cipher_ops);
 
+static int mpq_sdmx_invalidate_buffer(struct mpq_feed *mpq_feed)
+{
+	struct dvb_demux_feed *feed = mpq_feed->dvb_demux_feed;
+	struct mpq_video_feed_info *feed_data;
+	struct dvb_ringbuffer *buffer;
+	struct ion_handle *ion_handle;
+	int ret = 0;
+	int i;
+
+	if (!dvb_dmx_is_video_feed(feed)) {
+		if (dvb_dmx_is_sec_feed(feed) ||
+			dvb_dmx_is_pcr_feed(feed)) {
+			buffer = (struct dvb_ringbuffer *)
+				&mpq_feed->sdmx_buf;
+			ion_handle = mpq_feed->sdmx_buf_handle;
+		} else {
+			buffer = (struct dvb_ringbuffer *)
+				feed->feed.ts.buffer.ringbuff;
+			ion_handle = feed->feed.ts.buffer.priv_handle;
+		}
+
+		ret = msm_ion_do_cache_op(mpq_feed->mpq_demux->ion_client,
+			ion_handle, buffer->data,
+			buffer->size, ION_IOC_INV_CACHES);
+		if (ret)
+			MPQ_DVB_ERR_PRINT(
+				"%s: msm_ion_do_cache_op failed, ret = %d\n",
+				__func__, ret);
+		return ret;
+	}
+
+	/* Video buffers */
+	feed_data = &mpq_feed->video_info;
+	for (i = 0; i < feed_data->buffer_desc.decoder_buffers_num; i++) {
+		if (feed_data->buffer_desc.desc[i].base) {
+			/* Non-secured buffer */
+			ret = msm_ion_do_cache_op(
+				mpq_feed->mpq_demux->ion_client,
+				feed_data->buffer_desc.ion_handle[i],
+				feed_data->buffer_desc.desc[i].base,
+				feed_data->buffer_desc.desc[i].size,
+				ION_IOC_INV_CACHES);
+			if (ret)
+				MPQ_DVB_ERR_PRINT(
+					"%s: msm_ion_do_cache_op failed, ret = %d\n",
+					__func__, ret);
+		}
+	}
+
+	return ret;
+}
+
 static void mpq_sdmx_prepare_filter_status(struct mpq_demux *mpq_demux,
 	struct sdmx_filter_status *filter_sts,
 	struct mpq_feed *mpq_feed)
@@ -4757,6 +4809,9 @@
 			 mpq_feed->session_id))
 			continue;
 
+		/* Invalidate output buffer before processing the results */
+		mpq_sdmx_invalidate_buffer(mpq_feed);
+
 		if (sts->error_indicators & SDMX_FILTER_ERR_MD_BUF_FULL)
 			MPQ_DVB_ERR_PRINT(
 				"%s: meta-data buff for pid %d overflowed!\n",
@@ -4831,7 +4886,6 @@
 	for (i = 0; i < MPQ_MAX_DMX_FILES; i++) {
 		mpq_feed = &mpq_demux->feeds[i];
 		if ((mpq_feed->sdmx_filter_handle != SDMX_INVALID_FILTER_HANDLE)
-			&& (mpq_feed->dvb_demux_feed->state == DMX_STATE_GO)
 			&& (!mpq_feed->secondary_feed)) {
 			sts = mpq_demux->sdmx_filters_state.status +
 				filter_index;
@@ -4950,6 +5004,10 @@
 	const char *buf,
 	size_t count)
 {
+	struct ion_handle *ion_handle =
+		mpq_demux->demux.dmx.dvr_input.priv_handle;
+	struct dvb_ringbuffer *rbuf = (struct dvb_ringbuffer *)
+		mpq_demux->demux.dmx.dvr_input.ringbuff;
 	struct sdmx_buff_descr buf_desc;
 	u32 read_offset;
 	int ret;
@@ -4968,6 +5026,19 @@
 	}
 	read_offset = mpq_demux->demux.dmx.dvr_input.ringbuff->pread;
 
+
+	/*
+	 * We must flush the buffer before SDMX starts reading from it
+	 * so that it gets a valid data in memory.
+	 */
+	ret = msm_ion_do_cache_op(mpq_demux->ion_client,
+		ion_handle, rbuf->data,
+		rbuf->size, ION_IOC_CLEAN_CACHES);
+	if (ret)
+		MPQ_DVB_ERR_PRINT(
+			"%s: msm_ion_do_cache_op failed, ret = %d\n",
+			__func__, ret);
+
 	return mpq_sdmx_process(mpq_demux, &buf_desc, count,
 				read_offset, mpq_demux->demux.ts_packet_size);
 }
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c
index 2fb3c35..4da0f6f 100644
--- a/drivers/media/platform/msm/vidc/hfi_packetization.c
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.c
@@ -565,7 +565,7 @@
 		u32 session_id, struct vidc_seq_hdr *seq_hdr)
 {
 	int rc = 0;
-	if (!pkt || !session_id || seq_hdr)
+	if (!pkt || !session_id || !seq_hdr)
 		return -EINVAL;
 
 	pkt->size = sizeof(struct hfi_cmd_session_parse_sequence_header_packet);
diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c
index 5140a03..9604a09 100644
--- a/drivers/media/platform/msm/vidc/msm_smem.c
+++ b/drivers/media/platform/msm/vidc/msm_smem.c
@@ -171,8 +171,10 @@
 	mem->smem_priv = hndl;
 	mem->device_addr = iova;
 	mem->size = buffer_size;
-	dprintk(VIDC_DBG, "NOTE: Buffer device address: 0x%lx, size: %d\n",
-		mem->device_addr, mem->size);
+	dprintk(VIDC_DBG,
+		"%s: ion_handle = 0x%p, fd = %d, device_addr = 0x%x, size = %d, kvaddr = 0x%p, buffer_type = %d\n",
+		__func__, mem->smem_priv, fd, (u32)mem->device_addr,
+		mem->size, mem->kvaddr, mem->buffer_type);
 	return rc;
 fail_device_address:
 	ion_free(client->clnt, hndl);
@@ -241,10 +243,11 @@
 		goto fail_device_address;
 	}
 	mem->device_addr = iova;
-	dprintk(VIDC_DBG,
-		"device_address = 0x%lx, kvaddr = 0x%p, size = %d\n",
-		mem->device_addr, mem->kvaddr, size);
 	mem->size = size;
+	dprintk(VIDC_DBG,
+		"%s: ion_handle = 0x%p, device_addr = 0x%x, size = %d, kvaddr = 0x%p, buffer_type = %d\n",
+		__func__, mem->smem_priv, (u32)mem->device_addr,
+		mem->size, mem->kvaddr, mem->buffer_type);
 	return rc;
 fail_device_address:
 	ion_unmap_kernel(client->clnt, hndl);
@@ -258,6 +261,10 @@
 {
 	int domain, partition, rc;
 
+	dprintk(VIDC_DBG,
+		"%s: ion_handle = 0x%p, device_addr = 0x%x, size = %d, kvaddr = 0x%p, buffer_type = %d\n",
+		__func__, mem->smem_priv, (u32)mem->device_addr,
+		mem->size, mem->kvaddr, mem->buffer_type);
 	rc = msm_smem_get_domain_partition((void *)client, mem->flags,
 			mem->buffer_type, &domain, &partition);
 	if (rc) {
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 25917c1..9da1220 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -489,6 +489,7 @@
 			temp->handle[plane]->device_addr + binfo->buff_off[i];
 			b->m.planes[i].m.userptr = binfo->device_addr[i];
 			binfo->mapped[i] = false;
+			binfo->handle[i] = temp->handle[i];
 		} else {
 			if (inst->map_output_buffer) {
 				binfo->handle[i] =
@@ -498,9 +499,6 @@
 					rc = -EINVAL;
 					goto exit;
 				}
-				dprintk(VIDC_DBG,
-					"[MAP] - mapped handle[%d] = %p fd[%d] = %d",
-					i, binfo->handle[i], i, binfo->fd[i]);
 				binfo->mapped[i] = true;
 				binfo->device_addr[i] =
 					binfo->handle[i]->device_addr +
@@ -511,10 +509,6 @@
 				binfo->device_addr[i] =
 					b->m.planes[i].m.userptr;
 			}
-			dprintk(VIDC_DBG, "Registering buffer: %d, %d, %d\n",
-					b->m.planes[i].reserved[0],
-					b->m.planes[i].reserved[1],
-					b->m.planes[i].length);
 		}
 		/* We maintain one ref count for all planes*/
 		if ((i == 0) && is_dynamic_output_buffer_mode(b, inst)) {
@@ -522,8 +516,12 @@
 			if (rc < 0)
 				return rc;
 		}
+		dprintk(VIDC_DBG,
+			"%s: [MAP] binfo = %p, handle[%d] = %p, device_addr = 0x%x, fd = %d, offset = %d, mapped = %d\n",
+			__func__, binfo, i, binfo->handle[i],
+			binfo->device_addr[i], binfo->fd[i],
+			binfo->buff_off[i], binfo->mapped[i]);
 	}
-	dprintk(VIDC_DBG, "[MAP] Adding binfo = %p to list\n", binfo);
 	mutex_lock(&inst->lock);
 	list_add_tail(&binfo->list, &inst->registered_bufs);
 	mutex_unlock(&inst->lock);
@@ -570,6 +568,11 @@
 		goto exit;
 
 	for (i = 0; i < temp->num_planes; i++) {
+		dprintk(VIDC_DBG,
+			"%s: [UNMAP] binfo = %p, handle[%d] = %p, device_addr = 0x%x, fd = %d, offset = %d, mapped = %d\n",
+			__func__, temp, i, temp->handle[i],
+			temp->device_addr[i], temp->fd[i],
+			temp->buff_off[i], temp->mapped[i]);
 		/*
 		* Unmap the handle only if the buffer has been mapped and no
 		* other buffer has a reference to this buffer.
@@ -668,7 +671,8 @@
 					__func__, rc);
 				return -EINVAL;
 			}
-		}
+		} else
+			dprintk(VIDC_ERR, "%s: WARN: NULL handle", __func__);
 	}
 	return 0;
 }
@@ -742,11 +746,18 @@
 					buffer_info.m.planes[0].reserved[0],
 					buffer_info.m.planes[0].reserved[1],
 					buffer_info.m.planes[0].length);
+
 			list_del(&bi->list);
 			for (i = 0; i < bi->num_planes; i++) {
-				if (bi->handle[i])
+				if (bi->handle[i] && bi->mapped[i]) {
+					dprintk(VIDC_DBG,
+						"%s: [UNMAP] binfo = %p, handle[%d] = %p, device_addr = 0x%x, fd = %d, offset = %d, mapped = %d\n",
+						__func__, bi, i, bi->handle[i],
+						bi->device_addr[i], bi->fd[i],
+						bi->buff_off[i], bi->mapped[i]);
 					msm_comm_smem_free(inst,
 							bi->handle[i]);
+				}
 			}
 			kfree(bi);
 		}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 9387a17..7588994 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -944,6 +944,12 @@
 					V4L2_QCOM_BUF_DATA_CORRUPT;
 			}
 		}
+		dprintk(VIDC_DBG,
+			"Got ebd from hal: device_addr: 0x%x, alloc: %d, status: 0x%x, pic_type: 0x%x, flags: 0x%x\n",
+			(u32)empty_buf_done->packet_buffer,
+			empty_buf_done->alloc_len, empty_buf_done->status,
+			empty_buf_done->picture_type, empty_buf_done->flags);
+
 		mutex_lock(&inst->bufq[OUTPUT_PORT].lock);
 		vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
 		mutex_unlock(&inst->bufq[OUTPUT_PORT].lock);
@@ -1102,6 +1108,7 @@
 	struct vb2_buffer *vb = NULL;
 	struct vidc_hal_fbd *fill_buf_done;
 	enum hal_buffer buffer_type;
+	int64_t time_usec = 0;
 
 	if (!response) {
 		dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
@@ -1141,7 +1148,7 @@
 		if (!(fill_buf_done->flags1 &
 			HAL_BUFFERFLAG_TIMESTAMPINVALID) &&
 			fill_buf_done->filled_len1) {
-			int64_t time_usec = fill_buf_done->timestamp_hi;
+			time_usec = fill_buf_done->timestamp_hi;
 			time_usec = (time_usec << 32) |
 				fill_buf_done->timestamp_lo;
 			vb->v4l2_buf.timestamp =
@@ -1194,10 +1201,14 @@
 			msm_vidc_debugfs_update(inst,
 				MSM_VIDC_DEBUGFS_EVENT_FBD);
 
-		dprintk(VIDC_DBG, "Filled length = %d; offset = %d; flags %x\n",
-				vb->v4l2_planes[0].bytesused,
-				vb->v4l2_planes[0].data_offset,
-				vb->v4l2_buf.flags);
+		dprintk(VIDC_DBG,
+		"Got fbd from hal: device_addr: 0x%x, alloc: %d, filled: %d, offset: %d, ts: %lld, flags: 0x%x, crop: %d %d %d %d, pic_type: 0x%x\n",
+		(u32)fill_buf_done->packet_buffer1, fill_buf_done->alloc_len1,
+		fill_buf_done->filled_len1, fill_buf_done->offset1, time_usec,
+		fill_buf_done->flags1, fill_buf_done->start_x_coord,
+		fill_buf_done->start_y_coord, fill_buf_done->frame_width,
+		fill_buf_done->frame_height, fill_buf_done->picture_type);
+
 		mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
 		vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
 		mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
@@ -2433,11 +2444,10 @@
 				V4L2_QCOM_BUF_TIMESTAMP_INVALID)
 				frame_data.timestamp = LLONG_MAX;
 			dprintk(VIDC_DBG,
-				"Sending etb to hal: device_addr: 0x%x"
-				"Alloc: %d, filled: %d, offset: %d\n",
-				frame_data.device_addr,
-				frame_data.alloc_len, frame_data.filled_len,
-				frame_data.offset);
+				"Sending etb to hal: device_addr: 0x%x, alloc: %d, filled: %d, offset: %d, ts: %lld, flags = 0x%x\n",
+				frame_data.device_addr, frame_data.alloc_len,
+				frame_data.filled_len, frame_data.offset,
+				frame_data.timestamp, frame_data.flags);
 			rc = call_hfi_op(hdev, session_etb, (void *)
 					inst->session, &frame_data);
 			if (!rc)
@@ -2462,11 +2472,10 @@
 					vb->v4l2_planes[extra_idx].length;
 			}
 			dprintk(VIDC_DBG,
-				"Sending ftb to hal: Alloc: %d :filled: %d",
-				frame_data.alloc_len, frame_data.filled_len);
-			dprintk(VIDC_DBG,
-				" extradata_addr: %d\n",
-				frame_data.extradata_addr);
+				"Sending ftb to hal: device_addr: 0x%x, alloc: %d, buffer_type: %d, ts: %lld, flags = 0x%x\n",
+				frame_data.device_addr, frame_data.alloc_len,
+				frame_data.buffer_type, frame_data.timestamp,
+				frame_data.flags);
 			if (!inst->ftb_count &&
 			   inst->session_type == MSM_VIDC_ENCODER) {
 				seq_hdr.seq_hdr = (u8 *) vb->v4l2_planes[0].
@@ -2482,9 +2491,9 @@
 			} else {
 				rc = call_hfi_op(hdev, session_ftb,
 					(void *) inst->session, &frame_data);
-			if (!rc)
-				msm_vidc_debugfs_update(inst,
-					MSM_VIDC_DEBUGFS_EVENT_FTB);
+				if (!rc)
+					msm_vidc_debugfs_update(inst,
+						MSM_VIDC_DEBUGFS_EVENT_FTB);
 			}
 			inst->ftb_count++;
 		} else {
@@ -3152,7 +3161,7 @@
 {
 	int rc = 0;
 	struct hfi_device *hdev;
-	if (!core && !core->device) {
+	if (!core || !core->device) {
 		dprintk(VIDC_WARN, "Invalid parameters: %p\n", core);
 		return -EINVAL;
 	}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c b/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c
index 394ecdc5..ecfff85 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c
@@ -289,7 +289,7 @@
 		bus_pdata->usecase[i].vectors = kzalloc(
 			sizeof(*bus_pdata->usecase[i].vectors) * num_ports,
 			GFP_KERNEL);
-		if (!bus_pdata->usecase) {
+		if (!bus_pdata->usecase[i].vectors) {
 			dprintk(VIDC_ERR,
 				"%s Failed to alloc bus_pdata usecase\n",
 				__func__);
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index eeae873..2596a30 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -30,6 +30,7 @@
 #include "venus_hfi.h"
 #include "vidc_hfi_io.h"
 #include "msm_vidc_debug.h"
+#include <linux/iopoll.h>
 
 #define FIRMWARE_SIZE			0X00A00000
 #define REG_ADDR_OFFSET_BITMASK	0x000FFFFF
@@ -3062,9 +3063,10 @@
 	ocmem->vidc_ocmem_nb.notifier_call = venus_hfi_ocmem_notify_handler;
 	ocmem->handle =
 		ocmem_notifier_register(OCMEM_VIDEO, &ocmem->vidc_ocmem_nb);
-	if (!ocmem->handle) {
-		dprintk(VIDC_WARN, "Failed to register OCMEM notifier.");
-		dprintk(VIDC_INFO, " Performance will be impacted\n");
+	if (IS_ERR_OR_NULL(ocmem->handle)) {
+		dprintk(VIDC_WARN,
+				"Failed to register OCMEM notifier. Performance might be impacted\n");
+		ocmem->handle = NULL;
 	}
 }
 
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_io.h b/drivers/media/platform/msm/vidc/vidc_hfi_io.h
index 8ec0e28..b811948 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_io.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_io.h
@@ -139,6 +139,9 @@
 #define VENUS_VBIF_AXI_HALT_CTRL0_HALT_REQ		BIT(0)
 #define VENUS_VBIF_AXI_HALT_CTRL1_HALT_ACK		BIT(0)
 #define VENUS_VBIF_AXI_HALT_ACK_TIMEOUT_US		500000
+/* Poll interval in uS */
+#define POLL_INTERVAL_US                                50
+
 
 #define VIDC_VENUS0_WRAPPER_VBIF_REQ_PRIORITY \
 	(VIDC_WRAPPER_BASE_OFFS + 0x20)
diff --git a/drivers/media/radio/radio-iris-transport.c b/drivers/media/radio/radio-iris-transport.c
index 9a9b385..d3fe11c 100644
--- a/drivers/media/radio/radio-iris-transport.c
+++ b/drivers/media/radio/radio-iris-transport.c
@@ -105,6 +105,7 @@
 	skb = alloc_skb(len, GFP_ATOMIC);
 	if (!skb) {
 		FMDERR("Memory not allocated for the socket");
+		kfree(worker);
 		return;
 	}
 
@@ -153,7 +154,13 @@
 	struct radio_hci_dev *hdev;
 	int rc;
 
+	if (hsmd == NULL)
+		return -ENODEV;
+
 	hdev = kmalloc(sizeof(struct radio_hci_dev), GFP_KERNEL);
+	if (hdev == NULL)
+		return -ENODEV;
+
 	hsmd->hdev = hdev;
 	tasklet_init(&hsmd->rx_task, radio_hci_smd_recv_event,
 		(unsigned long) hsmd);
@@ -166,6 +173,8 @@
 
 	if (rc < 0) {
 		FMDERR("Cannot open the command channel");
+		hsmd->hdev = NULL;
+		kfree(hdev);
 		return -ENODEV;
 	}
 
@@ -173,6 +182,9 @@
 
 	if (radio_hci_register_dev(hdev) < 0) {
 		FMDERR("Can't register HCI device");
+		smd_close(hsmd->fm_channel);
+		hsmd->hdev = NULL;
+		kfree(hdev);
 		return -ENODEV;
 	}
 
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index 9e25e42..5dde469 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -88,7 +88,7 @@
 
 	struct radio_hci_dev *fm_hdev;
 
-	struct v4l2_capability *g_cap;
+	struct v4l2_capability g_cap;
 	struct v4l2_control *g_ctl;
 
 	struct hci_fm_mute_mode_req mute_mode;
@@ -496,8 +496,15 @@
 static void iris_q_event(struct iris_device *radio,
 				enum iris_evt_t event)
 {
-	struct kfifo *data_b = &radio->data_buf[IRIS_BUF_EVENTS];
+	struct kfifo *data_b;
 	unsigned char evt = event;
+
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return;
+	}
+
+	data_b = &radio->data_buf[IRIS_BUF_EVENTS];
 	if (kfifo_in_locked(data_b, &evt, 1, &radio->buf_lock[IRIS_BUF_EVENTS]))
 		wake_up_interruptible(&radio->event_queue);
 }
@@ -582,8 +589,6 @@
 	skb_queue_head_init(&hdev->cmd_q);
 	skb_queue_head_init(&hdev->raw_q);
 
-	if (!radio)
-		FMDERR(":radio is null");
 
 	radio->fm_hdev = hdev;
 
@@ -674,6 +679,10 @@
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 	__u16 opcode = 0;
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
 	opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
 		HCI_FM_SET_INTERNAL_TONE_GENRATOR);
 	return radio_hci_send_cmd(hdev, opcode,
@@ -1144,7 +1153,7 @@
 	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
 }
 
-static int radio_hci_err(__u16 code)
+static int radio_hci_err(__u32 code)
 {
 	switch (code) {
 	case 0:
@@ -1642,6 +1651,11 @@
 	__u8 status = *((__u8 *) skb->data);
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 
+	if (radio == NULL) {
+                FMDERR(":radio is null");
+                return;
+        }
+
 	if ((radio->mode == FM_TURNING_OFF) && (status == 0)) {
 		iris_q_event(radio, IRIS_EVT_RADIO_DISABLED);
 		radio_hci_req_complete(hdev, status);
@@ -1659,6 +1673,10 @@
 	struct hci_fm_conf_rsp  *rsp = (void *)skb->data;
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return;
+	}
 	if (rsp->status)
 		return;
 
@@ -1672,6 +1690,11 @@
 	struct hci_fm_get_trans_conf_rsp  *rsp = (void *)skb->data;
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return;
+	}
+
 	if (rsp->status)
 		return;
 	memcpy((void *)&radio->trans_conf,  (void*)&rsp->trans_conf_rsp,
@@ -1685,6 +1708,11 @@
 	struct hci_fm_conf_rsp  *rsp = (void *)skb->data;
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return;
+	}
+
 	if (rsp->status) {
 		radio_hci_req_complete(hdev, rsp->status);
 		return;
@@ -1707,6 +1735,11 @@
 	struct hci_fm_conf_rsp  *rsp = (void *)skb->data;
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return;
+	}
+
 	if (rsp->status)
 		return;
 
@@ -1722,6 +1755,11 @@
 	struct hci_fm_sig_threshold_rsp  *rsp = (void *)skb->data;
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return;
+	}
+
 	if (rsp->status)
 		return;
 
@@ -1733,6 +1771,12 @@
 {
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 	struct hci_fm_station_rsp *rsp = (void *)skb->data;
+
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return;
+	}
+
 	radio->fm_st_rsp = *(rsp);
 
 	/* Tune is always succesful */
@@ -1772,9 +1816,16 @@
 static void hci_cc_feature_list_rsp(struct radio_hci_dev *hdev,
 	struct sk_buff *skb)
 {
+	struct v4l2_capability *v4l_cap;
 	struct hci_fm_feature_list_rsp  *rsp = (void *)skb->data;
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
-	struct v4l2_capability *v4l_cap = radio->g_cap;
+
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return;
+	}
+
+	v4l_cap = &radio->g_cap;
 
 	if (rsp->status)
 		return;
@@ -1789,8 +1840,13 @@
 {
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 	struct hci_fm_dbg_param_rsp *rsp = (void *)skb->data;
-	radio->st_dbg_param = *(rsp);
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return;
+	}
+
+	radio->st_dbg_param = *(rsp);
 	if (radio->st_dbg_param.status)
 		return;
 
@@ -1800,7 +1856,13 @@
 static void iris_q_evt_data(struct iris_device *radio,
 				char *data, int len, int event)
 {
-	struct kfifo *data_b = &radio->data_buf[event];
+	struct kfifo *data_b;
+
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return;
+	}
+	data_b = &radio->data_buf[event];
 	if (kfifo_in_locked(data_b, data, len, &radio->buf_lock[event]))
 		wake_up_interruptible(&radio->event_queue);
 }
@@ -1837,6 +1899,11 @@
 	__u8 status = *((__u8 *) skb->data);
 	__u8 len;
 
+        if (radio == NULL) {
+                FMDERR(":radio is null");
+                return;
+        }
+
 	if (status)
 		return;
 	len = skb->data[1];
@@ -1917,6 +1984,11 @@
 {
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 	u8  status = skb->data[0];
+
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return;
+	}
 	if (status) {
 		FMDERR("status = %d", status);
 		return;
@@ -2050,6 +2122,10 @@
 	int i;
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return;
+	}
 	memcpy(&radio->fm_st_rsp.station_rsp, &skb->data[0],
 				sizeof(struct hci_ev_tune_status));
 	iris_q_event(radio, IRIS_EVT_TUNE_SUCC);
@@ -2092,6 +2168,10 @@
 	int abs_freq;
 	int len;
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return;
+	}
 	ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
 	if (!ev) {
 		FMDERR("Memory allocation failed");
@@ -2150,6 +2230,10 @@
 	radio = video_get_drvdata(video_get_dev());
 	index = RDSGRP_DATA_OFFSET;
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return;
+	}
 	for (blocknum = 0; blocknum < RDS_BLOCKS_NUM; blocknum++) {
 		temp.rdsBlk[blocknum].rdsLsb =
 			(skb->data[index]);
@@ -2556,9 +2640,15 @@
 static int iris_search(struct iris_device *radio, int on, int dir)
 {
 	int retval = 0;
-	enum search_t srch = radio->g_search_mode & SRCH_MODE;
-	radio->search_on = on;
+	enum search_t srch;
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
+
+	srch = radio->g_search_mode & SRCH_MODE;
+	radio->search_on = on;
 	if (on) {
 		switch (srch) {
 		case SCAN_FOR_STRONG:
@@ -2600,6 +2690,12 @@
 
 	int rds_grps_proc = 0x00;
 	int retval = 0;
+
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
+
 	if (radio->power_mode != power_mode) {
 
 		if (power_mode) {
@@ -2638,6 +2734,12 @@
 static int iris_recv_set_region(struct iris_device *radio, int req_region)
 {
 	int retval;
+
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
+
 	radio->region = req_region;
 
 	retval = hci_set_fm_recv_conf(
@@ -2651,6 +2753,11 @@
 static int iris_trans_set_region(struct iris_device *radio, int req_region)
 {
 	int retval;
+
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
 	radio->region = req_region;
 
 	retval = hci_set_fm_trans_conf(
@@ -2664,6 +2771,11 @@
 {
 
 	int retval;
+
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
 	retval = hci_fm_tune_station(&freq, radio->fm_hdev);
 	if (retval < 0)
 		FMDERR("Error while setting the frequency : %d\n", retval);
@@ -2693,6 +2805,11 @@
 	char cal_mode = 0x00;
 	int retval = 0x00;
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
+
 	cal_mode = PROCS_CALIB_MODE;
 	radio->mode = FM_CALIB;
 	retval = hci_cmd(HCI_FM_ENABLE_RECV_CMD,
@@ -2727,6 +2844,11 @@
 	struct hci_fm_def_data_rd_req rd;
 	int lsb, msb;
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
+
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_VOLUME:
 		break;
@@ -3012,6 +3134,11 @@
 	struct iris_device *radio = video_get_drvdata(video_devdata(file));
 	struct hci_fm_def_data_rd_req default_data_rd;
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
+
 	switch ((ctrl->controls[0]).id) {
 	case V4L2_CID_PRIVATE_IRIS_READ_DEFAULT:
 		data = (ctrl->controls[0]).string;
@@ -3032,7 +3159,7 @@
 			struct v4l2_ext_controls *ctrl)
 {
 	int retval = 0;
-	int bytes_to_copy;
+	size_t bytes_to_copy;
 	struct hci_fm_tx_ps tx_ps;
 	struct hci_fm_tx_rt tx_rt;
 	struct hci_fm_def_data_wr_req default_data;
@@ -3041,14 +3168,20 @@
 	struct iris_device *radio = video_get_drvdata(video_devdata(file));
 	char *data = NULL;
 
+	if ((ctrl == NULL) || (ctrl->controls == NULL)
+		|| (ctrl->count == 0)) {
+		retval = -EINVAL;
+		return retval;
+	}
+
 	switch ((ctrl->controls[0]).id) {
 	case V4L2_CID_RDS_TX_PS_NAME:
 		FMDBG("In V4L2_CID_RDS_TX_PS_NAME\n");
 		/*Pass a sample PS string */
 
 		memset(tx_ps.ps_data, 0, MAX_PS_LENGTH);
-		bytes_to_copy = min((int)(ctrl->controls[0]).size,
-			MAX_PS_LENGTH);
+		bytes_to_copy = min(ctrl->controls[0].size,
+			(size_t)MAX_PS_LENGTH);
 		data = (ctrl->controls[0]).string;
 
 		if (copy_from_user(tx_ps.ps_data,
@@ -3065,7 +3198,7 @@
 		break;
 	case V4L2_CID_RDS_TX_RADIO_TEXT:
 		bytes_to_copy =
-		    min((int)(ctrl->controls[0]).size, MAX_RT_LENGTH);
+		    min((ctrl->controls[0]).size, (size_t)MAX_RT_LENGTH);
 		data = (ctrl->controls[0]).string;
 
 		memset(tx_rt.rt_data, 0, MAX_RT_LENGTH);
@@ -3164,6 +3297,11 @@
 	char sinr_th, sinr;
 	__u8 intf_det_low_th, intf_det_high_th, intf_det_out;
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
+
 	switch (ctrl->id) {
 	case V4L2_CID_PRIVATE_IRIS_TX_TONE:
 		radio->tone_freq = ctrl->value;
@@ -3846,6 +3984,10 @@
 	/* Pass the mode of SPUR_CLK */
 	default_data.mode = CKK_SPUR;
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
 	temp = radio->spur_table_size;
 	for (cnt = 0; cnt < (temp / 5); cnt++) {
 		offset = 0;
@@ -3916,6 +4058,10 @@
 	int retval;
 	struct iris_device *radio = video_get_drvdata(video_devdata(file));
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
 	if (tuner->index > 0) {
 		FMDERR("Invalid Tuner Index");
 		return -EINVAL;
@@ -3959,6 +4105,12 @@
 {
 	struct iris_device *radio = video_get_drvdata(video_devdata(file));
 	int retval = 0;
+
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
+
 	if (tuner->index > 0)
 		return -EINVAL;
 
@@ -4010,6 +4162,10 @@
 	int retval = -1;
 	freq->frequency = freq->frequency / TUNE_PARAM;
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
 	if (freq->type != V4L2_TUNER_RADIO)
 		return -EINVAL;
 
@@ -4137,10 +4293,19 @@
 {
 	struct iris_device *radio;
 	radio = video_get_drvdata(video_devdata(file));
+
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
 	strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
 	strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
-	capability->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
-	radio->g_cap = capability;
+
+	strlcpy(radio->g_cap.driver, DRIVER_NAME, sizeof(radio->g_cap.driver));
+	strlcpy(radio->g_cap.card, DRIVER_CARD, sizeof(radio->g_cap.card));
+
+	radio->g_cap.capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	capability->capabilities = radio->g_cap.capabilities;
 	return 0;
 }
 
@@ -4148,6 +4313,11 @@
 {
 	int retval;
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
+
 	radio->mute_mode.soft_mute = CTRL_ON;
 	retval = hci_set_fm_mute_mode(&radio->mute_mode,
 					radio->fm_hdev);
@@ -4185,7 +4355,14 @@
 static int initialise_trans(struct iris_device *radio)
 {
 
-	int retval = hci_cmd(HCI_FM_GET_TX_CONFIG, radio->fm_hdev);
+	int retval;
+
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
+
+	retval = hci_cmd(HCI_FM_GET_TX_CONFIG, radio->fm_hdev);
 	if (retval < 0)
 		FMDERR("get frequency failed %d\n", retval);
 
@@ -4196,6 +4373,11 @@
 {
 	int retval = 1;
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
+
 	if (radio->mode == FM_OFF || radio->mode == FM_RECV)
 		retval = 0;
 
@@ -4294,11 +4476,11 @@
 		if (kfifo_alloc_rc != 0) {
 			FMDERR("failed allocating buffers %d\n",
 				   kfifo_alloc_rc);
-			for (; i > -1; i--) {
+			for (; i > -1; i--)
 				kfifo_free(&radio->data_buf[i]);
-				kfree(radio);
-				return -ENOMEM;
-			}
+			video_device_release(radio->videodev);
+			kfree(radio);
+			return -ENOMEM;
 		}
 	}
 
@@ -4326,8 +4508,17 @@
 	} else {
 		priv_videodev = kzalloc(sizeof(struct video_device),
 			GFP_KERNEL);
-		memcpy(priv_videodev, radio->videodev,
-			sizeof(struct video_device));
+		if (priv_videodev != NULL) {
+			memcpy(priv_videodev, radio->videodev,
+				sizeof(struct video_device));
+		} else {
+			video_unregister_device(radio->videodev);
+			video_device_release(radio->videodev);
+			for (; i > -1; i--)
+				kfifo_free(&radio->data_buf[i]);
+			kfree(radio);
+			return -ENOMEM;
+		}
 	}
 	return 0;
 }
@@ -4338,6 +4529,10 @@
 	int i;
 	struct iris_device *radio = platform_get_drvdata(pdev);
 
+	if (radio == NULL) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
 	video_unregister_device(radio->videodev);
 
 	for (i = 0; i < IRIS_BUF_MAX; i++)
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index 6b9f2b3..c44e2a5 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -185,6 +185,10 @@
 	if (bahama_present == -ENODEV)
 		return -ENODEV;
 
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
 	if (bahama_present)
 		radio->marimba->mod_id = SLAVE_ID_BAHAMA_FM;
 	else
@@ -216,6 +220,11 @@
    * (otherwise, it may have already been there and will not be added a second
    * time).
    */
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
 	queue_delayed_work(radio->wqueue, &radio->work,
 				msecs_to_jiffies(TAVARUA_DELAY));
 	return IRQ_HANDLED;
@@ -243,6 +252,12 @@
 				unsigned char offset, int len)
 {
 	int retval = 0, i = 0;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	retval = set_fm_slave_id(radio);
 
 	if (retval == -ENODEV)
@@ -282,6 +297,12 @@
 			unsigned char offset, unsigned char value)
 {
 	int retval;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	retval = set_fm_slave_id(radio);
 
 	if (retval == -ENODEV)
@@ -322,6 +343,12 @@
 
 	int i;
 	int retval;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	retval = set_fm_slave_id(radio);
 
 	if (retval == -ENODEV)
@@ -358,6 +385,11 @@
 */
 static int read_data_blocks(struct tavarua_device *radio, unsigned char offset)
 {
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	/* read all 3 RDS blocks */
 	return tavarua_read_registers(radio, offset, RDS_BLOCK*4);
 }
@@ -376,10 +408,17 @@
 */
 static void tavarua_rds_read(struct tavarua_device *radio)
 {
-	struct kfifo *rds_buf = &radio->data_buf[TAVARUA_BUF_RAW_RDS];
+	struct kfifo *rds_buf;
 	unsigned char blocknum;
 	unsigned char tmp[3];
 
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return;
+	}
+
+	rds_buf = &radio->data_buf[TAVARUA_BUF_RAW_RDS];
+
 	if (read_data_blocks(radio, RAW_RDS) < 0)
 		return;
 	 /* copy all four RDS blocks to internal buffer */
@@ -430,6 +469,12 @@
 static int request_read_xfr(struct tavarua_device *radio,
 				enum tavarua_xfr_ctrl_t mode){
 
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	tavarua_write_register(radio, XFRCTRL, mode);
 	msleep(TAVARUA_DELAY);
 	return 0;
@@ -457,8 +502,17 @@
 static int copy_from_xfr(struct tavarua_device *radio,
 		enum tavarua_buf_t buf_type, unsigned int n){
 
-	struct kfifo *data_fifo = &radio->data_buf[buf_type];
-	unsigned char *xfr_regs = &radio->registers[XFRCTRL+1];
+	struct kfifo *data_fifo;
+	unsigned char *xfr_regs;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
+	data_fifo = &radio->data_buf[buf_type];
+	xfr_regs = &radio->registers[XFRCTRL+1];
+
 	kfifo_in_locked(data_fifo, xfr_regs, n, &radio->buf_lock[buf_type]);
 	return 0;
 }
@@ -496,6 +550,12 @@
 			char *buf, int len)
 {
 	char buffer[len+1];
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	memcpy(buffer+1, buf, len);
 	/* buffer[0] corresponds to XFRCTRL register
 	   set the CTRL bit to 1 for write mode
@@ -520,6 +580,11 @@
 static int xfr_intf_own(struct tavarua_device *radio)
 {
 
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	mutex_lock(&radio->lock);
 	if (radio->xfr_in_progress) {
 		radio->pending_xfrs[TAVARUA_XFR_SYNC] = 1;
@@ -552,6 +617,12 @@
 			enum tavarua_xfr_ctrl_t xfr_type, unsigned char *buf)
 {
 	int retval;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	retval = xfr_intf_own(radio);
 	if (retval < 0)
 		return retval;
@@ -590,6 +661,17 @@
 		enum tavarua_xfr_ctrl_t xfr_type, unsigned char *buf)
 {
 	int retval;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
+	if (unlikely(buf == NULL)) {
+		FMDERR("%s:buf is null", __func__);
+		return -EINVAL;
+	}
+
 	retval = xfr_intf_own(radio);
 	if (retval < 0)
 		return retval;
@@ -627,6 +709,12 @@
 {
 	int i;
 	enum tavarua_xfr_t xfr;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return;
+	}
+
 	for (i = 0; i < TAVARUA_XFR_MAX; i++) {
 		if (radio->pending_xfrs[i]) {
 			radio->xfr_in_progress = 1;
@@ -681,8 +769,16 @@
 				enum tavarua_evt_t event)
 {
 
-	struct kfifo *data_b = &radio->data_buf[TAVARUA_BUF_EVENTS];
+	struct kfifo *data_b;
 	unsigned char evt = event;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return;
+	}
+
+	data_b = &radio->data_buf[TAVARUA_BUF_EVENTS];
+
 	FMDBG("updating event_q with event %x\n", event);
 	if (kfifo_in_locked(data_b, &evt, 1, &radio->buf_lock[TAVARUA_BUF_EVENTS]))
 		wake_up_interruptible(&radio->event_queue);
@@ -707,12 +803,18 @@
 static void tavarua_start_xfr(struct tavarua_device *radio,
 		enum tavarua_xfr_t pending_id, enum tavarua_xfr_ctrl_t xfr_id)
 {
-		if (radio->xfr_in_progress)
-			radio->pending_xfrs[pending_id] = 1;
-		else {
-			radio->xfr_in_progress = 1;
-			request_read_xfr(radio, xfr_id);
-		}
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return;
+	}
+
+	if (radio->xfr_in_progress)
+		radio->pending_xfrs[pending_id] = 1;
+	else {
+		radio->xfr_in_progress = 1;
+		request_read_xfr(radio, xfr_id);
+	}
 }
 
 /*=============================================================================
@@ -739,6 +841,12 @@
 	int i;
 	int retval, adj_channel_tune_req = 0;
 	unsigned char xfr_status;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return;
+	}
+
 	if (!radio->handle_irq) {
 		FMDBG("IRQ happend, but I wont handle it\n");
 		return;
@@ -1143,15 +1251,34 @@
 */
 static void read_int_stat(struct work_struct *work)
 {
-	struct tavarua_device *radio = container_of(work,
-					struct tavarua_device, work.work);
+	struct tavarua_device *radio;
+
+	if (unlikely(work == NULL)) {
+		FMDERR("%s:work is null", __func__);
+		return;
+	}
+
+	radio = container_of(work, struct tavarua_device, work.work);
+
 	tavarua_handle_interrupts(radio);
 }
 
 static void fm_shutdown(struct work_struct *work)
 {
-	struct tavarua_device *radio = container_of(work,
-					struct tavarua_device, work.work);
+	struct tavarua_device *radio;
+
+	if (unlikely(work == NULL)) {
+		FMDERR("%s:work is null", __func__);
+		return;
+	}
+
+	radio = container_of(work, struct tavarua_device, work.work);
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return;
+	}
+
 	FMDERR("%s: Releasing the FM I2S GPIO\n", __func__);
 	if (radio->pdata->config_i2s_gpio != NULL)
 		radio->pdata->config_i2s_gpio(FM_I2S_OFF);
@@ -1178,9 +1305,14 @@
 static int tavarua_request_irq(struct tavarua_device *radio)
 {
 	int retval;
-	int irq = radio->pdata->irq;
-	if (radio == NULL)
+	int irq;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
 		return -EINVAL;
+	}
+
+	irq = radio->pdata->irq;
 
   /* A workqueue created with create_workqueue() will have one worker thread
    * for each CPU on the system; create_singlethread_workqueue(), instead,
@@ -1237,8 +1369,12 @@
 static int tavarua_disable_irq(struct tavarua_device *radio)
 {
 	int irq;
-	if (!radio)
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
 		return -EINVAL;
+	}
+
 	irq = radio->pdata->irq;
 	disable_irq_wake(irq);
 	free_irq(irq, radio);
@@ -1255,6 +1391,11 @@
 	unsigned int rdsMask = 0;
 	unsigned char value = 0;
 
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	adie_type_bahma = is_bahama();
 
 	switch (region) {
@@ -1435,9 +1576,17 @@
 */
 static int tavarua_search(struct tavarua_device *radio, int on, int dir)
 {
-	enum search_t srch = radio->registers[SRCHCTRL] & SRCH_MODE;
+	enum search_t srch;
 
 	FMDBG("In tavarua_search\n");
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
+	srch = radio->registers[SRCHCTRL] & SRCH_MODE;
+
 	if (on) {
 		radio->registers[SRCHRDS1] = 0x00;
 		radio->registers[SRCHRDS2] = 0x00;
@@ -1503,6 +1652,11 @@
 	enum tavarua_region_t region = req_region;
 	unsigned char adie_type_bahma;
 
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	adie_type_bahma = is_bahama();
 
 	/* Set freq band */
@@ -1671,6 +1825,17 @@
 	unsigned short chan;
 	unsigned int band_bottom;
 	unsigned int spacing;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
+	if (unlikely(freq == NULL)) {
+		FMDERR("%s:freq is null", __func__);
+		return -EINVAL;
+	}
+
 	band_bottom = radio->region_params.band_low;
 	spacing  = 0.100 * FREQ_MUL;
 	/* read channel */
@@ -1716,6 +1881,12 @@
 	unsigned char cmd[] = {0x00, 0x00};
 	unsigned int spacing;
 	int retval;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	band_bottom = radio->region_params.band_low;
 	spacing  = 0.100 * FREQ_MUL;
 	if ((freq % 1600) == 800) {
@@ -1760,8 +1931,19 @@
 				size_t count, loff_t *ppos)
 {
 	struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
-	struct kfifo *rds_buf = &radio->data_buf[TAVARUA_BUF_RAW_RDS];
+	struct kfifo *rds_buf;
 
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
+	if (unlikely(buf == NULL)) {
+		FMDERR("%s:buf is null", __func__);
+		return -EINVAL;
+	}
+
+	rds_buf = &radio->data_buf[TAVARUA_BUF_RAW_RDS];
 	/* block if no new data available */
 	while (!kfifo_len(rds_buf)) {
 		if (file->f_flags & O_NONBLOCK)
@@ -1810,6 +1992,17 @@
 	int bytes_left;
 	int chunk_index = 0;
 	unsigned char tx_data[XFR_REG_NUM];
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
+	if (unlikely(data == NULL)) {
+		FMDERR("%s:data is null", __func__);
+		return -EINVAL;
+	}
+
 	/* Disable TX of this type first */
 	switch (radio->tx_mode) {
 	case TAVARUA_TX_RT:
@@ -1897,6 +2090,11 @@
 	char buffer[] = {0x00, 0x48, 0x8A, 0x8E, 0x97, 0xB7};
 	int bahama_present = -ENODEV;
 
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	INIT_DELAYED_WORK(&radio->work, read_int_stat);
 	if (!atomic_dec_and_test(&radio->users)) {
 		pr_err("%s: Device already in use."
@@ -2518,6 +2716,16 @@
 {
 	struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
 
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
+	if (unlikely(capability == NULL)) {
+		FMDERR("%s:capability is null", __func__);
+		return -EINVAL;
+	}
+
 	strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
 	strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
 	sprintf(capability->bus_info, "I2C");
@@ -2553,6 +2761,12 @@
 	unsigned char i;
 	int retval = -EINVAL;
 
+	if (unlikely(qc == NULL)) {
+		FMDERR("%s:qc is null", __func__);
+		return -EINVAL;
+	}
+
+
 	for (i = 0; i < ARRAY_SIZE(tavarua_v4l2_queryctrl); i++) {
 		if (qc->id && qc->id == tavarua_v4l2_queryctrl[i].id) {
 			memcpy(qc, &(tavarua_v4l2_queryctrl[i]), sizeof(*qc));
@@ -2574,6 +2788,11 @@
 	int index = 0, offset = 0, addr = 0x0, val = 0;
 	int retval = 0, temp = 0, cnt = 0, j = 0;
 
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	memset(xfr_buf, 0x0, XFR_REG_NUM);
 
 	/* Read the SPUR Table Size */
@@ -2651,6 +2870,15 @@
 	unsigned char xfr_buf[XFR_REG_NUM + 1];
 	int retval = 0, temp = 0;
 
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
+	if (unlikely(buf == NULL)) {
+		FMDERR("%s:buf is null", __func__);
+		return -EINVAL;
+	}
 	/* zero initialize the buffer */
 	memset(xfr_buf, 0x0, XFR_REG_NUM);
 
@@ -2725,6 +2953,11 @@
 	int ct = 0;
 	unsigned char size = 0;
 
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	/*
 	Poking the MPX_DCC_BYPASS register to freeze the
 	value of MPX_DCC from changing while we access it
@@ -2844,6 +3077,16 @@
 	signed char ioc;
 	unsigned char size = 0;
 
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
+	if (unlikely(ctrl == NULL)) {
+		FMDERR("%s:ctrl is null", __func__);
+		return -EINVAL;
+	}
+
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_VOLUME:
 		break;
@@ -3059,6 +3302,18 @@
 	int extra_name_byte = 0;
 	int name_bytes = 0;
 
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
+	if (unlikely(ctrl == NULL) ||
+		unlikely(ctrl->controls == NULL) ||
+		unlikely(ctrl->count <= 0)) {
+		FMDERR("%s:ctrl is null", __func__);
+		return -EINVAL;
+	}
+
 	switch ((ctrl->controls[0]).id)	{
 	case V4L2_CID_RDS_TX_PS_NAME: {
 		FMDBG("In V4L2_CID_RDS_TX_PS_NAME\n");
@@ -3191,6 +3446,16 @@
 	unsigned int freq = 0, mpx_dcc = 0;
 	unsigned long curr = 0, prev = 0;
 
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
+	if (unlikely(ctrl == NULL)) {
+		FMDERR("%s:ctrl is null", __func__);
+		return -EINVAL;
+	}
+
 	memset(xfr_buf, 0x0, XFR_REG_NUM);
 
 	switch (ctrl->id) {
@@ -3797,6 +4062,16 @@
 	char rmssi = 0;
 	unsigned char size = 0;
 
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
+	if (unlikely(tuner == NULL)) {
+		FMDERR("%s:tuner is null", __func__);
+		return -EINVAL;
+	}
+
 	if (tuner->index > 0)
 		return -EINVAL;
 
@@ -3863,6 +4138,17 @@
 	struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
 	int retval;
 	int audmode;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
+	if (unlikely(tuner == NULL)) {
+		FMDERR("%s:tuner is null", __func__);
+		return -EINVAL;
+	}
+
 	if (tuner->index > 0)
 		return -EINVAL;
 
@@ -3910,6 +4196,17 @@
 		struct v4l2_frequency *freq)
 {
 	struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
+	if (unlikely(freq == NULL)) {
+		FMDERR("%s:freq is null", __func__);
+		return -EINVAL;
+	}
+
 	freq->type = V4L2_TUNER_RADIO;
 	return tavarua_get_freq(radio, freq);
 
@@ -3945,6 +4242,16 @@
 
 	FMDBG("%s\n", __func__);
 
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
+	if (unlikely(freq == NULL)) {
+		FMDERR("%s:freq is null", __func__);
+		return -EINVAL;
+	}
+
 	if (freq->type != V4L2_TUNER_RADIO)
 		return -EINVAL;
 
@@ -4108,6 +4415,17 @@
 {
 	struct tavarua_device  *radio = video_get_drvdata(video_devdata(file));
 	int dir;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
+	if (unlikely(seek == NULL)) {
+		FMDERR("%s:seek is null", __func__);
+		return -EINVAL;
+	}
+
 	if (seek->seek_upward)
 		dir = SRCH_DIR_UP;
 	else
@@ -4159,6 +4477,11 @@
 	int retval;
 	unsigned char int_ctrl[XFR_REG_NUM];
 
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	if (!radio->lp_mode)
 		return 0;
 
@@ -4222,6 +4545,12 @@
 {
 	unsigned char lpm_buf[XFR_REG_NUM];
 	int retval;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	if (radio->lp_mode)
 		return 0;
 	FMDBG("%s\n", __func__);
@@ -4270,6 +4599,12 @@
 
 	int retval;
 	FMDBG("%s <%d>\n", __func__, state);
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	/* set geographic region */
 	radio->region_params.region = TAVARUA_REGION_US;
 
@@ -4305,6 +4640,12 @@
 	int retval;
 	int users = 0;
 	printk(KERN_INFO DRIVER_NAME "%s: radio suspend\n\n", __func__);
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	if (radio) {
 		users = atomic_read(&radio->users);
 		if (!users) {
@@ -4336,6 +4677,12 @@
 	int retval;
 	int users = 0;
 	printk(KERN_INFO DRIVER_NAME "%s: radio resume\n\n", __func__);
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	if (radio) {
 		users = atomic_read(&radio->users);
 
@@ -4380,8 +4727,12 @@
 	struct tavarua_device *radio = private_data;
 	int rx_on = radio->registers[RDCTRL] & FM_RECV;
 	int retval = 0;
-	if (!radio)
-		return -ENOMEM;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	/* RX */
 	FMDBG("%s: digital: %d analog: %d\n", __func__, digital_on, analog_on);
 	if ((radio->pdata != NULL) && (radio->pdata->config_i2s_gpio != NULL)) {
@@ -4469,6 +4820,12 @@
 	int retval = 0;
 	int i = 0, j = 0;
 	FMDBG("%s: probe called\n", __func__);
+
+	if (unlikely(pdev == NULL)) {
+		FMDERR("%s:pdev is null", __func__);
+		return -EINVAL;
+	}
+
 	/* private data allocation */
 	radio = kzalloc(sizeof(struct tavarua_device), GFP_KERNEL);
 	if (!radio) {
@@ -4593,6 +4950,11 @@
 	int i;
 	struct tavarua_device *radio = platform_get_drvdata(pdev);
 
+	if (unlikely(radio == NULL)) {
+		FMDERR("%s:radio is null", __func__);
+		return -EINVAL;
+	}
+
 	/* disable irq */
 	tavarua_disable_irq(radio);
 
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index 9dd06ee..127a231 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -310,6 +310,7 @@
 		"Scalable High",
 		"Scalable High Intra",
 		"Multiview High",
+		"Constrained High",
 		NULL,
 	};
 	static const char * const vui_sar_idc[] = {
diff --git a/drivers/misc/smsc_hub.c b/drivers/misc/smsc_hub.c
index 0147e66..6f98dc7 100644
--- a/drivers/misc/smsc_hub.c
+++ b/drivers/misc/smsc_hub.c
@@ -385,26 +385,27 @@
 static int __devinit smsc_hub_probe(struct platform_device *pdev)
 {
 	int ret = 0;
-	const struct smsc_hub_platform_data *pdata;
+	struct smsc_hub_platform_data *pdata;
 	struct device_node *node = pdev->dev.of_node;
 	struct i2c_adapter *i2c_adap;
 	struct i2c_board_info i2c_info;
+	struct of_dev_auxdata *hsic_host_auxdata;
 
 	if (pdev->dev.of_node) {
 		dev_dbg(&pdev->dev, "device tree enabled\n");
-		pdev->dev.platform_data = msm_hub_dt_to_pdata(pdev);
-		if (IS_ERR(pdev->dev.platform_data))
-			return PTR_ERR(pdev->dev.platform_data);
-
-		dev_set_name(&pdev->dev, smsc_hub_driver.driver.name);
+		hsic_host_auxdata = dev_get_platdata(&pdev->dev);
+		pdata = msm_hub_dt_to_pdata(pdev);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+	} else {
+		pdata = pdev->dev.platform_data;
 	}
 
-	if (!pdev->dev.platform_data) {
+	if (!pdata) {
 		dev_err(&pdev->dev, "No platform data\n");
 		return -ENODEV;
 	}
 
-	pdata = pdev->dev.platform_data;
 	if (!pdata->hub_reset)
 		return -EINVAL;
 
@@ -413,7 +414,7 @@
 		return -ENOMEM;
 
 	smsc_hub->dev = &pdev->dev;
-	smsc_hub->pdata = pdev->dev.platform_data;
+	smsc_hub->pdata = pdata;
 
 	smsc_hub->hub_vbus_reg = devm_regulator_get(&pdev->dev, "hub_vbus");
 	ret = PTR_ERR(smsc_hub->hub_vbus_reg);
@@ -494,7 +495,7 @@
 	i2c_put_adapter(i2c_adap);
 
 i2c_add_fail:
-	ret = of_platform_populate(node, NULL, NULL, &pdev->dev);
+	ret = of_platform_populate(node, NULL, hsic_host_auxdata, &pdev->dev);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to add child node, ret=%d\n", ret);
 		goto uninit_gpio;
@@ -523,7 +524,7 @@
 {
 	const struct smsc_hub_platform_data *pdata;
 
-	pdata = pdev->dev.platform_data;
+	pdata = smsc_hub->pdata;
 	if (smsc_hub->client) {
 		i2c_unregister_device(smsc_hub->client);
 		smsc_hub->client = NULL;
diff --git a/drivers/misc/tspp.c b/drivers/misc/tspp.c
index 3d69473..19f26f2 100644
--- a/drivers/misc/tspp.c
+++ b/drivers/misc/tspp.c
@@ -1706,6 +1706,8 @@
 	dma_free_coherent(NULL, config->desc.size, config->desc.base,
 		config->desc.phys_base);
 
+	sps_free_endpoint(channel->pipe);
+
 	tspp_destroy_buffers(channel_id, channel);
 	if (channel->dma_pool) {
 		dma_pool_destroy(channel->dma_pool);
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index eb5d365..b36faff 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -414,14 +414,12 @@
 #endif
 	mmc_init_context_info(card->host);
 
-	if (mmc_use_core_runtime_pm(card->host)) {
-		ret = pm_runtime_set_active(&card->dev);
-		if (ret)
-			pr_err("%s: %s: failed setting runtime active: ret: %d\n",
-			       mmc_hostname(card->host), __func__, ret);
-		else if (!mmc_card_sdio(card))
-			pm_runtime_enable(&card->dev);
-	}
+	ret = pm_runtime_set_active(&card->dev);
+	if (ret)
+		pr_err("%s: %s: failed setting runtime active: ret: %d\n",
+		       mmc_hostname(card->host), __func__, ret);
+	else if (!mmc_card_sdio(card) && mmc_use_core_runtime_pm(card->host))
+		pm_runtime_enable(&card->dev);
 
 	ret = device_add(&card->dev);
 	if (ret)
@@ -469,6 +467,7 @@
 	}
 
 	kfree(card->wr_pack_stats.packing_events);
+	kfree(card->cached_ext_csd);
 
 	put_device(&card->dev);
 }
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index edd6a5d..c7fa876 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -78,7 +78,7 @@
 	struct mmc_host *host = cls_dev_to_mmc_host(dev);
 	int ret = 0;
 
-	if (!mmc_use_core_runtime_pm(host))
+	if (!mmc_use_core_pm(host))
 		return 0;
 
 	if (!pm_runtime_suspended(dev)) {
@@ -95,7 +95,7 @@
 	struct mmc_host *host = cls_dev_to_mmc_host(dev);
 	int ret = 0;
 
-	if (!mmc_use_core_runtime_pm(host))
+	if (!mmc_use_core_pm(host))
 		return 0;
 
 	if (!pm_runtime_suspended(dev)) {
@@ -686,14 +686,13 @@
 	WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&
 		!host->ops->enable_sdio_irq);
 
-	if (mmc_use_core_runtime_pm(host)) {
-		err = pm_runtime_set_active(&host->class_dev);
-		if (err)
-			pr_err("%s: %s: failed setting runtime active: err: %d\n",
-			       mmc_hostname(host), __func__, err);
-		else
-			pm_runtime_enable(&host->class_dev);
-	}
+	err = pm_runtime_set_active(&host->class_dev);
+	if (err)
+		pr_err("%s: %s: failed setting runtime active: err: %d\n",
+		       mmc_hostname(host), __func__, err);
+	else if (mmc_use_core_runtime_pm(host))
+		pm_runtime_enable(&host->class_dev);
+
 	err = device_add(&host->class_dev);
 	if (err)
 		return err;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 997e14b..b295bb8 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1189,9 +1189,9 @@
 		mmc_set_timing(card->host, MMC_TIMING_LEGACY);
 		mmc_set_clock(card->host, MMC_HIGH_26_MAX_DTR);
 
-		err = mmc_select_hs(card, &card->cached_ext_csd);
+		err = mmc_select_hs(card, card->cached_ext_csd);
 	} else {
-		err = mmc_select_hs400(card, &card->cached_ext_csd);
+		err = mmc_select_hs400(card, card->cached_ext_csd);
 	}
 
 	return err;
@@ -1439,7 +1439,7 @@
 		err = mmc_get_ext_csd(card, &ext_csd);
 		if (err)
 			goto free_card;
-		memcpy(&card->cached_ext_csd, ext_csd, sizeof(card->ext_csd));
+		card->cached_ext_csd = ext_csd;
 		err = mmc_read_ext_csd(card, ext_csd);
 		if (err)
 			goto free_card;
@@ -1637,15 +1637,12 @@
 	if (!oldcard)
 		host->card = card;
 
-	mmc_free_ext_csd(ext_csd);
 	return 0;
 
 free_card:
 	if (!oldcard)
 		mmc_remove_card(card);
 err:
-	mmc_free_ext_csd(ext_csd);
-
 	return err;
 }
 
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 95f0a04..c335be1 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -6962,7 +6962,7 @@
 
 static const struct of_device_id msmsdcc_dt_match[] = {
 	{.compatible = "qcom,msm-sdcc"},
-
+	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, msmsdcc_dt_match);
 
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index b93eaf4..4d3a560 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -317,6 +317,7 @@
 	bool tuning_done;
 	bool calibration_done;
 	u8 saved_tuning_phase;
+	atomic_t controller_clock;
 };
 
 enum vdd_io_level {
@@ -2213,6 +2214,50 @@
 	return sel_clk;
 }
 
+static int sdhci_msm_enable_controller_clock(struct sdhci_host *host)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_msm_host *msm_host = pltfm_host->priv;
+	int rc = 0;
+
+	if (atomic_read(&msm_host->controller_clock))
+		return 0;
+
+	sdhci_msm_bus_voting(host, 1);
+
+	if (!IS_ERR(msm_host->pclk)) {
+		rc = clk_prepare_enable(msm_host->pclk);
+		if (rc) {
+			pr_err("%s: %s: failed to enable the pclk with error %d\n",
+			       mmc_hostname(host->mmc), __func__, rc);
+			goto remove_vote;
+		}
+	}
+
+	rc = clk_prepare_enable(msm_host->clk);
+	if (rc) {
+		pr_err("%s: %s: failed to enable the host-clk with error %d\n",
+		       mmc_hostname(host->mmc), __func__, rc);
+		goto disable_pclk;
+	}
+
+	atomic_set(&msm_host->controller_clock, 1);
+	pr_debug("%s: %s: enabled controller clock\n",
+			mmc_hostname(host->mmc), __func__);
+	goto out;
+
+disable_pclk:
+	if (!IS_ERR(msm_host->pclk))
+		clk_disable_unprepare(msm_host->pclk);
+remove_vote:
+	if (msm_host->msm_bus_vote.client_handle)
+		sdhci_msm_bus_cancel_work_and_set_vote(host, 0);
+out:
+	return rc;
+}
+
+
+
 static int sdhci_msm_prepare_clocks(struct sdhci_host *host, bool enable)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -2223,36 +2268,32 @@
 		pr_debug("%s: request to enable clocks\n",
 				mmc_hostname(host->mmc));
 
-		sdhci_msm_bus_voting(host, 1);
+		/*
+		 * The bus-width or the clock rate might have changed
+		 * after controller clocks are enbaled, update bus vote
+		 * in such case.
+		 */
+		if (atomic_read(&msm_host->controller_clock))
+			sdhci_msm_bus_voting(host, 1);
+
+		rc = sdhci_msm_enable_controller_clock(host);
+		if (rc)
+			goto remove_vote;
 
 		if (!IS_ERR_OR_NULL(msm_host->bus_clk)) {
 			rc = clk_prepare_enable(msm_host->bus_clk);
 			if (rc) {
 				pr_err("%s: %s: failed to enable the bus-clock with error %d\n",
 					mmc_hostname(host->mmc), __func__, rc);
-				goto remove_vote;
+				goto disable_controller_clk;
 			}
 		}
-		if (!IS_ERR(msm_host->pclk)) {
-			rc = clk_prepare_enable(msm_host->pclk);
-			if (rc) {
-				pr_err("%s: %s: failed to enable the pclk with error %d\n",
-					mmc_hostname(host->mmc), __func__, rc);
-				goto disable_bus_clk;
-			}
-		}
-		rc = clk_prepare_enable(msm_host->clk);
-		if (rc) {
-			pr_err("%s: %s: failed to enable the host-clk with error %d\n",
-				mmc_hostname(host->mmc), __func__, rc);
-			goto disable_pclk;
-		}
 		if (!IS_ERR(msm_host->ff_clk)) {
 			rc = clk_prepare_enable(msm_host->ff_clk);
 			if (rc) {
 				pr_err("%s: %s: failed to enable the ff_clk with error %d\n",
 					mmc_hostname(host->mmc), __func__, rc);
-				goto disable_clk;
+				goto disable_bus_clk;
 			}
 		}
 		if (!IS_ERR(msm_host->sleep_clk)) {
@@ -2280,6 +2321,7 @@
 		if (!IS_ERR_OR_NULL(msm_host->bus_clk))
 			clk_disable_unprepare(msm_host->bus_clk);
 
+		atomic_set(&msm_host->controller_clock, 0);
 		sdhci_msm_bus_voting(host, 0);
 	}
 	atomic_set(&msm_host->clks_on, enable);
@@ -2287,15 +2329,15 @@
 disable_ff_clk:
 	if (!IS_ERR_OR_NULL(msm_host->ff_clk))
 		clk_disable_unprepare(msm_host->ff_clk);
-disable_clk:
-	if (!IS_ERR_OR_NULL(msm_host->clk))
-		clk_disable_unprepare(msm_host->clk);
-disable_pclk:
-	if (!IS_ERR_OR_NULL(msm_host->pclk))
-		clk_disable_unprepare(msm_host->pclk);
 disable_bus_clk:
 	if (!IS_ERR_OR_NULL(msm_host->bus_clk))
 		clk_disable_unprepare(msm_host->bus_clk);
+disable_controller_clk:
+	if (!IS_ERR_OR_NULL(msm_host->clk))
+		clk_disable_unprepare(msm_host->clk);
+	if (!IS_ERR_OR_NULL(msm_host->pclk))
+		clk_disable_unprepare(msm_host->pclk);
+	atomic_set(&msm_host->controller_clock, 0);
 remove_vote:
 	if (msm_host->msm_bus_vote.client_handle)
 		sdhci_msm_bus_cancel_work_and_set_vote(host, 0);
@@ -2558,6 +2600,7 @@
 	.get_min_clock = sdhci_msm_get_min_clock,
 	.get_max_clock = sdhci_msm_get_max_clock,
 	.disable_data_xfer = sdhci_msm_disable_data_xfer,
+	.enable_controller_clock = sdhci_msm_enable_controller_clock,
 };
 
 static int __devinit sdhci_msm_probe(struct platform_device *pdev)
@@ -2637,6 +2680,7 @@
 		if (ret)
 			goto bus_clk_disable;
 	}
+	atomic_set(&msm_host->controller_clock, 1);
 
 	/* Setup SDC MMC clock */
 	msm_host->clk = devm_clk_get(&pdev->dev, "core_clk");
@@ -2840,6 +2884,7 @@
 	msm_host->mmc->caps2 |= MMC_CAP2_CLK_SCALE;
 	msm_host->mmc->caps2 |= MMC_CAP2_STOP_REQUEST;
 	msm_host->mmc->caps2 |= MMC_CAP2_ASYNC_SDIO_IRQ_4BIT_MODE;
+	msm_host->mmc->caps2 |= MMC_CAP2_CORE_PM;
 	msm_host->mmc->pm_caps |= MMC_PM_KEEP_POWER;
 
 	if (msm_host->pdata->nonremovable)
@@ -2896,7 +2941,7 @@
 	if (ret)
 		pr_err("%s: %s: pm_runtime_set_active failed: err: %d\n",
 		       mmc_hostname(host->mmc), __func__, ret);
-	else
+	else if (mmc_use_core_runtime_pm(host->mmc))
 		pm_runtime_enable(&pdev->dev);
 
 	/* Successful initialization */
@@ -3068,6 +3113,7 @@
 #endif
 static const struct of_device_id sdhci_msm_dt_match[] = {
 	{.compatible = "qcom,sdhci-msm"},
+	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sdhci_msm_dt_match);
 
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 513ddfb..830223d 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1577,6 +1577,7 @@
 	unsigned long flags;
 	int vdd_bit = -1;
 	u8 ctrl;
+	int ret;
 
 	mutex_lock(&host->ios_mutex);
 	if (host->flags & SDHCI_DEVICE_DEAD) {
@@ -1589,6 +1590,29 @@
 	if (ios->clock)
 		sdhci_set_clock(host, ios->clock);
 
+	/*
+	 * The controller clocks may be off during power-up and we may end up
+	 * enabling card clock before giving power to the card. Hence, during
+	 * MMC_POWER_UP enable the controller clock and turn-on the regulators.
+	 * The mmc_power_up would provide the necessary delay before turning on
+	 * the clocks to the card.
+	 */
+	if (ios->power_mode & MMC_POWER_UP) {
+		if (host->ops->enable_controller_clock) {
+			ret = host->ops->enable_controller_clock(host);
+			if (ret) {
+				pr_err("%s: enabling controller clock: failed: %d\n",
+				       mmc_hostname(host->mmc), ret);
+			} else {
+				vdd_bit = sdhci_set_power(host, ios->vdd);
+
+				if (host->vmmc && vdd_bit != -1)
+					mmc_regulator_set_ocr(host->mmc,
+							      host->vmmc,
+							      vdd_bit);
+			}
+		}
+	}
 	spin_lock_irqsave(&host->lock, flags);
 	if (!host->clock) {
 		spin_unlock_irqrestore(&host->lock, flags);
@@ -1597,14 +1621,16 @@
 	}
 	spin_unlock_irqrestore(&host->lock, flags);
 
-	if (ios->power_mode & (MMC_POWER_UP | MMC_POWER_ON))
+	if (!host->ops->enable_controller_clock && (ios->power_mode &
+						    (MMC_POWER_UP |
+						     MMC_POWER_ON))) {
 		vdd_bit = sdhci_set_power(host, ios->vdd);
 
-	if (host->vmmc && vdd_bit != -1)
-		mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd_bit);
+		if (host->vmmc && vdd_bit != -1)
+			mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd_bit);
+	}
 
 	spin_lock_irqsave(&host->lock, flags);
-
 	if (host->ops->platform_send_init_74_clocks)
 		host->ops->platform_send_init_74_clocks(host, ios->power_mode);
 
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 3db99c4..db4806d 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -295,6 +295,7 @@
 	unsigned int	(*get_max_segments)(void);
 	void	(*platform_bus_voting)(struct sdhci_host *host, u32 enable);
 	void    (*disable_data_xfer)(struct sdhci_host *host);
+	int	(*enable_controller_clock)(struct sdhci_host *host);
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 8dc30ee..12c5704 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -50,6 +50,7 @@
 
 /* module params */
 #define WCNSS_CONFIG_UNSPECIFIED (-1)
+#define UINT32_MAX (0xFFFFFFFFU)
 
 static int has_48mhz_xo = WCNSS_CONFIG_UNSPECIFIED;
 module_param(has_48mhz_xo, int, S_IWUSR | S_IRUGO);
@@ -142,6 +143,7 @@
 #define MSM_PRONTO_PLL_BASE				0xfb21b1c0
 #define PRONTO_PLL_STATUS_OFFSET		0x1c
 
+#define MSM_PRONTO_TXP_STATUS           0xfb08040c
 #define MSM_PRONTO_TXP_PHY_ABORT        0xfb080488
 #define MSM_PRONTO_BRDG_ERR_SRC         0xfb080fb0
 
@@ -154,6 +156,7 @@
 #define WCNSS_CTRL_CHANNEL			"WCNSS_CTRL"
 #define WCNSS_MAX_FRAME_SIZE		(4*1024)
 #define WCNSS_VERSION_LEN			30
+#define WCNSS_MAX_BUILD_VER_LEN		256
 
 /* message types */
 #define WCNSS_CTRL_MSG_START	0x01000000
@@ -166,6 +169,8 @@
 #define	WCNSS_CALDATA_DNLD_REQ        (WCNSS_CTRL_MSG_START + 6)
 #define	WCNSS_CALDATA_DNLD_RSP        (WCNSS_CTRL_MSG_START + 7)
 #define	WCNSS_VBATT_LEVEL_IND         (WCNSS_CTRL_MSG_START + 8)
+#define	WCNSS_BUILD_VER_REQ           (WCNSS_CTRL_MSG_START + 9)
+#define	WCNSS_BUILD_VER_RSP           (WCNSS_CTRL_MSG_START + 10)
 
 
 #define VALID_VERSION(version) \
@@ -339,10 +344,10 @@
 	void __iomem *pronto_ccpu_base;
 	void __iomem *pronto_saw2_base;
 	void __iomem *pronto_pll_base;
+	void __iomem *wlan_tx_status;
 	void __iomem *wlan_tx_phy_aborts;
 	void __iomem *wlan_brdg_err_source;
 	void __iomem *fiq_reg;
-	int	ssr_boot;
 	int	nv_downloaded;
 	unsigned char *fw_cal_data;
 	unsigned char *user_cal_data;
@@ -351,7 +356,7 @@
 	int	fw_cal_available;
 	int	user_cal_read;
 	int	user_cal_available;
-	int	user_cal_rcvd;
+	u32	user_cal_rcvd;
 	int	user_cal_exp_size;
 	int	device_opened;
 	int	iris_xo_mode_set;
@@ -515,6 +520,10 @@
 	pr_info_ratelimited("%s:  PRONTO_PMU_SOFT_RESET %08x\n",
 						__func__, reg);
 
+	reg_addr = penv->pronto_saw2_base + PRONTO_SAW2_SPM_STS_OFFSET;
+	reg = readl_relaxed(reg_addr);
+	pr_info_ratelimited("%s: PRONTO_SAW2_SPM_STS %08x\n", __func__, reg);
+
 	reg_addr = penv->msm_wcnss_base + PRONTO_PMU_COM_GDSCR_OFFSET;
 	reg = readl_relaxed(reg_addr);
 	pr_info_ratelimited("%s:  PRONTO_PMU_COM_GDSCR %08x\n",
@@ -563,10 +572,6 @@
 	reg = readl_relaxed(reg_addr);
 	pr_info_ratelimited("%s: CCU_CCPU_LAST_ADDR2 %08x\n", __func__, reg);
 
-	reg_addr = penv->pronto_saw2_base + PRONTO_SAW2_SPM_STS_OFFSET;
-	reg = readl_relaxed(reg_addr);
-	pr_info_ratelimited("%s: PRONTO_SAW2_SPM_STS %08x\n", __func__, reg);
-
 	reg_addr = penv->pronto_pll_base + PRONTO_PLL_STATUS_OFFSET;
 	reg = readl_relaxed(reg_addr);
 	pr_info_ratelimited("%s: PRONTO_PLL_STATUS %08x\n", __func__, reg);
@@ -664,6 +669,8 @@
 	reg = readl_relaxed(penv->wlan_brdg_err_source);
 	pr_info_ratelimited("%s: WLAN_BRDG_ERR_SOURCE %08x\n", __func__, reg);
 
+	reg = readl_relaxed(penv->wlan_tx_status);
+	pr_info_ratelimited("%s: WLAN_TX_STATUS %08x\n", __func__, reg);
 }
 EXPORT_SYMBOL(wcnss_pronto_log_debug_regs);
 
@@ -755,8 +762,6 @@
 	case SMD_EVENT_CLOSE:
 		pr_debug("wcnss: closing WCNSS SMD channel :%s",
 				WCNSS_CTRL_CHANNEL);
-		/* This SMD is closed only during SSR */
-		penv->ssr_boot = true;
 		penv->nv_downloaded = 0;
 		break;
 
@@ -1348,6 +1353,17 @@
 		goto exit;
 	}
 
+	if (penv->fw_cal_available) {
+		/* ignore cal upload from SSR */
+		smd_read(penv->smd_ch, NULL, calhdr.frag_size);
+		penv->fw_cal_exp_frag++;
+		if (calhdr.msg_flags & LAST_FRAGMENT) {
+			penv->fw_cal_exp_frag = 0;
+			goto exit;
+		}
+		return;
+	}
+
 	if (0 == calhdr.frag_number) {
 		if (calhdr.total_size > MAX_CALIBRATED_DATA_SIZE) {
 			pr_err("wcnss: Invalid cal data size %d",
@@ -1411,7 +1427,9 @@
 	int len = 0;
 	int rc = 0;
 	unsigned char buf[sizeof(struct wcnss_version)];
+	unsigned char build[WCNSS_MAX_BUILD_VER_LEN+1];
 	struct smd_msg_hdr *phdr;
+	struct smd_msg_hdr smd_msg;
 	struct wcnss_version *pversion;
 	int hw_type;
 	unsigned char fw_status = 0;
@@ -1468,6 +1486,12 @@
 			break;
 
 		case WCNSS_PRONTO_HW:
+			smd_msg.msg_type = WCNSS_BUILD_VER_REQ;
+			smd_msg.msg_len = sizeof(smd_msg);
+			rc = wcnss_smd_tx(&smd_msg, smd_msg.msg_len);
+			if (rc < 0)
+				pr_err("wcnss: smd tx failed: %s\n", __func__);
+
 			/* supported only if pronto major >= 1 and minor >= 4 */
 			if ((pversion->major >= 1) && (pversion->minor >= 4)) {
 				pr_info("wcnss: schedule dnld work for pronto\n");
@@ -1482,6 +1506,21 @@
 		}
 		break;
 
+	case WCNSS_BUILD_VER_RSP:
+		if (len > WCNSS_MAX_BUILD_VER_LEN) {
+			pr_err("wcnss: invalid build version data from wcnss %d\n",
+					len);
+			return;
+		}
+		rc = smd_read(penv->smd_ch, build, len);
+		if (rc < len) {
+			pr_err("wcnss: incomplete data read from smd\n");
+			return;
+		}
+		build[len] = 0;
+		pr_info("wcnss: build version %s\n", build);
+		break;
+
 	case WCNSS_NVBIN_DNLD_RSP:
 		penv->nv_downloaded = true;
 		fw_status = wcnss_fw_status();
@@ -1498,7 +1537,6 @@
 		break;
 
 	case WCNSS_CALDATA_UPLD_REQ:
-		penv->fw_cal_available = 0;
 		extract_cal_data(len);
 		break;
 
@@ -1748,21 +1786,12 @@
 		while (!penv->user_cal_available && retry++ < 5)
 			msleep(500);
 	}
-
-	/* only cal data is sent during ssr (if available) */
-	if (penv->fw_cal_available && penv->ssr_boot) {
-		pr_info_ratelimited("wcnss: cal download during SSR, using fw cal");
-		wcnss_caldata_dnld(penv->fw_cal_data, penv->fw_cal_rcvd, false);
-		return;
-
-	} else if (penv->user_cal_available && penv->ssr_boot) {
-		pr_info_ratelimited("wcnss: cal download during SSR, using user cal");
-		wcnss_caldata_dnld(penv->user_cal_data,
-		penv->user_cal_rcvd, false);
-		return;
+	if (penv->fw_cal_available) {
+		pr_info_ratelimited("wcnss: cal download, using fw cal");
+		wcnss_caldata_dnld(penv->fw_cal_data, penv->fw_cal_rcvd, true);
 
 	} else if (penv->user_cal_available) {
-		pr_info_ratelimited("wcnss: cal download during cold boot, using user cal");
+		pr_info_ratelimited("wcnss: cal download, using user cal");
 		wcnss_caldata_dnld(penv->user_cal_data,
 		penv->user_cal_rcvd, true);
 	}
@@ -1965,7 +1994,12 @@
 			pr_err("%s: ioremap wlan BRDG ERR failed\n", __func__);
 			goto fail_ioremap8;
 		}
-
+		penv->wlan_tx_status = ioremap(MSM_PRONTO_TXP_STATUS, SZ_8);
+		if (!penv->wlan_tx_status) {
+			ret = -ENOMEM;
+			pr_err("%s: ioremap wlan TX STATUS failed\n", __func__);
+			goto fail_ioremap9;
+		}
 	}
 	penv->adc_tm_dev = qpnp_get_adc_tm(&penv->pdev->dev, "wcnss");
 	if (IS_ERR(penv->adc_tm_dev)) {
@@ -1991,6 +2025,9 @@
 fail_pil:
 	if (penv->riva_ccu_base)
 		iounmap(penv->riva_ccu_base);
+	if (penv->wlan_tx_status)
+		iounmap(penv->wlan_tx_status);
+fail_ioremap9:
 	if (penv->wlan_brdg_err_source)
 		iounmap(penv->wlan_brdg_err_source);
 fail_ioremap8:
@@ -2098,7 +2135,7 @@
 			*user_buffer, size_t count, loff_t *position)
 {
 	int rc = 0;
-	int size = 0;
+	size_t size = 0;
 
 	if (!penv || !penv->device_opened || penv->user_cal_available)
 		return -EFAULT;
@@ -2106,7 +2143,7 @@
 	if (penv->user_cal_rcvd == 0 && count >= 4
 			&& !penv->user_cal_data) {
 		rc = copy_from_user((void *)&size, user_buffer, 4);
-		if (size > MAX_CALIBRATED_DATA_SIZE) {
+		if (!size || size > MAX_CALIBRATED_DATA_SIZE) {
 			pr_err(DEVICE " invalid size to write %d\n", size);
 			return -EFAULT;
 		}
@@ -2125,7 +2162,8 @@
 	} else if (penv->user_cal_rcvd == 0 && count < 4)
 		return -EFAULT;
 
-	if (MAX_CALIBRATED_DATA_SIZE < count + penv->user_cal_rcvd) {
+	if ((UINT32_MAX - count < penv->user_cal_rcvd) ||
+	     MAX_CALIBRATED_DATA_SIZE < count + penv->user_cal_rcvd) {
 		pr_err(DEVICE " invalid size to write %d\n", count +
 				penv->user_cal_rcvd);
 		rc = -ENOMEM;
diff --git a/drivers/of/of_batterydata.c b/drivers/of/of_batterydata.c
index b0d40f1..32aae74 100644
--- a/drivers/of/of_batterydata.c
+++ b/drivers/of/of_batterydata.c
@@ -228,7 +228,7 @@
 	OF_PROP_READ(batt_data->rbatt_capacitive_mohm,
 			"rbatt-capacitive-mohm", node, rc, false);
 	OF_PROP_READ(batt_data->flat_ocv_threshold_uv,
-			"flat-ocv-threshold", node, rc, true);
+			"flat-ocv-threshold-uv", node, rc, true);
 	OF_PROP_READ(batt_data->max_voltage_uv,
 			"max-voltage-uv", node, rc, true);
 	OF_PROP_READ(batt_data->cutoff_uv, "v-cutoff-uv", node, rc, true);
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 5f0ba94..9ccb993 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -327,10 +327,9 @@
 	for(; lookup->compatible != NULL; lookup++) {
 		if (!of_device_is_compatible(np, lookup->compatible))
 			continue;
-		if (of_address_to_resource(np, 0, &res))
-			continue;
-		if (res.start != lookup->phys_addr)
-			continue;
+		if (!of_address_to_resource(np, 0, &res))
+			if (res.start != lookup->phys_addr)
+				continue;
 		pr_debug("%s: devname=%s\n", np->full_name, lookup->name);
 		return lookup;
 	}
diff --git a/drivers/platform/msm/qpnp-clkdiv.c b/drivers/platform/msm/qpnp-clkdiv.c
index c55ed09..696c84f 100644
--- a/drivers/platform/msm/qpnp-clkdiv.c
+++ b/drivers/platform/msm/qpnp-clkdiv.c
@@ -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
@@ -202,6 +202,7 @@
 	if (!res) {
 		dev_err(&spmi->dev, "%s: unable to get device reg resource\n",
 					__func__);
+		return -EINVAL;
 	}
 
 	q_clkdiv->slave = spmi->sid;
diff --git a/drivers/platform/msm/qpnp-pwm.c b/drivers/platform/msm/qpnp-pwm.c
index 7d26bef..588afc6 100644
--- a/drivers/platform/msm/qpnp-pwm.c
+++ b/drivers/platform/msm/qpnp-pwm.c
@@ -208,6 +208,12 @@
 #define QPNP_PWM_SIZE_8_BIT		8
 #define QPNP_PWM_SIZE_9_BIT		9
 
+/* Supported time levels */
+enum time_level {
+	LVL_NSEC,
+	LVL_USEC,
+};
+
 /* LPG revisions */
 enum qpnp_lpg_revision {
 	QPNP_LPG_REVISION_0 = 0x0,
@@ -305,8 +311,8 @@
 	bool				in_use;
 	const char			*lable;
 	int				pwm_value;
-	int				pwm_period;
-	int				pwm_duty;
+	int				pwm_period;	/* in microseconds */
+	int				pwm_duty;	/* in microseconds */
 	struct pwm_period_config	period;
 	int				force_pwm_size;
 };
@@ -425,8 +431,9 @@
  * This is the formula to figure out m for the best pre-divide and clock:
  * (PWM Period / N) = (Pre-divide * Clock Period) * 2^m
  */
-static void qpnp_lpg_calc_period(unsigned int period_us,
-				   struct pwm_device *pwm)
+static void qpnp_lpg_calc_period(enum time_level tm_lvl,
+				unsigned int period_value,
+				struct pwm_device *pwm)
 {
 	int		n, m, clk, div;
 	int		best_m, best_div, best_clk;
@@ -443,14 +450,18 @@
 	else
 		n = 6;
 
-	if (period_us < ((unsigned)(-1) / NSEC_PER_USEC)) {
-		period_n = (period_us * NSEC_PER_USEC) >> n;
+	if (tm_lvl == LVL_USEC) {
+		if (period_value < ((unsigned)(-1) / NSEC_PER_USEC)) {
+			period_n = (period_value * NSEC_PER_USEC) >> n;
+		} else {
+			if (qpnp_check_gpled_lpg_channel(id))
+				n = 8;
+			else
+				n = 9;
+			period_n = (period_value >> n) * NSEC_PER_USEC;
+		}
 	} else {
-		if (qpnp_check_gpled_lpg_channel(id))
-			n = 8;
-		else
-			n = 9;
-		period_n = (period_us >> n) * NSEC_PER_USEC;
+		period_n = period_value >> n;
 	}
 
 	if (force_pwm_size != 0) {
@@ -520,20 +531,20 @@
 }
 
 static void qpnp_lpg_calc_pwm_value(struct pwm_device *pwm,
-				      unsigned int period_us,
-				      unsigned int duty_us)
+				      unsigned int period_value,
+				      unsigned int duty_value)
 {
 	unsigned int		max_pwm_value, tmp;
 	struct qpnp_pwm_config	*pwm_config = &pwm->pwm_config;
 
 	/* Figure out pwm_value with overflow handling */
 	tmp = 1 << (sizeof(tmp) * 8 - pwm_config->period.pwm_size);
-	if (duty_us < tmp) {
-		tmp = duty_us << pwm_config->period.pwm_size;
-		pwm_config->pwm_value = tmp / period_us;
+	if (duty_value < tmp) {
+		tmp = duty_value << pwm_config->period.pwm_size;
+		pwm_config->pwm_value = tmp / period_value;
 	} else {
-		tmp = period_us >> pwm_config->period.pwm_size;
-		pwm_config->pwm_value = duty_us / tmp;
+		tmp = period_value >> pwm_config->period.pwm_size;
+		pwm_config->pwm_value = duty_value / tmp;
 	}
 	max_pwm_value = (1 << pwm_config->period.pwm_size) - 1;
 	if (pwm_config->pwm_value > max_pwm_value)
@@ -1083,25 +1094,36 @@
 	return rc;
 }
 
-static int _pwm_config(struct pwm_device *pwm, int duty_us, int period_us)
+static int _pwm_config(struct pwm_device *pwm,
+				enum time_level tm_lvl,
+				int duty_value, int period_value)
 {
 	struct qpnp_pwm_config		*pwm_config;
 	struct qpnp_lpg_chip		*chip;
 	struct pwm_period_config	*period;
-	int				rc;
+	int period_us, duty_us;
+	int	rc;
 
 	chip = pwm->chip;
 	pwm_config = &pwm->pwm_config;
 	period = &pwm_config->period;
 
+	if (tm_lvl == LVL_USEC) {
+		period_us = period_value;
+		duty_us = duty_value;
+	} else {
+		period_us = period_value / NSEC_PER_USEC;
+		duty_us = duty_value / NSEC_PER_USEC;
+	}
+
 	if (pwm_config->pwm_period != period_us) {
-		qpnp_lpg_calc_period(period_us, pwm);
+		qpnp_lpg_calc_period(tm_lvl, period_value, pwm);
 		qpnp_lpg_save_period(pwm);
 		pwm_config->pwm_period = period_us;
 	}
 
 	pwm_config->pwm_duty = duty_us;
-	qpnp_lpg_calc_pwm_value(pwm, period_us, duty_us);
+	qpnp_lpg_calc_pwm_value(pwm, period_value, duty_value);
 	rc = qpnp_lpg_save_pwm_value(pwm);
 
 	if (rc) {
@@ -1124,8 +1146,9 @@
 		return rc;
 	}
 
-	pr_debug("duty/period=%u/%u usec: pwm_value=%d (of %d)\n",
+	pr_debug("duty/period=%u/%u %s: pwm_value=%d (of %d)\n",
 		 (unsigned)duty_us, (unsigned)period_us,
+		 (tm_lvl == LVL_USEC) ? "usec" : "nsec",
 		 pwm_config->pwm_value, 1 << period->pwm_size);
 
 	return 0;
@@ -1151,7 +1174,7 @@
 	period = &pwm_config->period;
 
 	if (pwm_config->pwm_period != period_us) {
-		qpnp_lpg_calc_period(period_us, pwm);
+		qpnp_lpg_calc_period(LVL_USEC, period_us, pwm);
 		qpnp_lpg_save_period(pwm);
 		pwm_config->pwm_period = period_us;
 	}
@@ -1302,10 +1325,41 @@
 /**
  * pwm_config - change a PWM device configuration
  * @pwm: the PWM device
+ * @period_ns: period in nanoseconds
+ * @duty_ns: duty cycle in nanoseconds
+ */
+int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+	int rc;
+	unsigned long flags;
+
+	if (pwm == NULL || IS_ERR(pwm) || duty_ns > period_ns ||
+		(unsigned)period_ns < PM_PWM_PERIOD_MIN * NSEC_PER_USEC) {
+		pr_err("Invalid pwm handle or parameters\n");
+		return -EINVAL;
+	}
+
+	if (!pwm->pwm_config.in_use)
+		return -EINVAL;
+
+	spin_lock_irqsave(&pwm->chip->lpg_lock, flags);
+	rc = _pwm_config(pwm, LVL_NSEC, duty_ns, period_ns);
+	spin_unlock_irqrestore(&pwm->chip->lpg_lock, flags);
+
+	if (rc)
+		pr_err("Failed to configure PWM mode\n");
+
+	return rc;
+}
+EXPORT_SYMBOL_GPL(pwm_config);
+
+/**
+ * pwm_config_us - change a PWM device configuration
+ * @pwm: the PWM device
  * @period_us: period in microseconds
  * @duty_us: duty cycle in microseconds
  */
-int pwm_config(struct pwm_device *pwm, int duty_us, int period_us)
+int pwm_config_us(struct pwm_device *pwm, int duty_us, int period_us)
 {
 	int rc;
 	unsigned long flags;
@@ -1322,7 +1376,7 @@
 		return -EINVAL;
 
 	spin_lock_irqsave(&pwm->chip->lpg_lock, flags);
-	rc = _pwm_config(pwm, duty_us, period_us);
+	rc = _pwm_config(pwm, LVL_USEC, duty_us, period_us);
 	spin_unlock_irqrestore(&pwm->chip->lpg_lock, flags);
 
 	if (rc)
@@ -1330,7 +1384,7 @@
 
 	return rc;
 }
-EXPORT_SYMBOL_GPL(pwm_config);
+EXPORT_SYMBOL_GPL(pwm_config_us);
 
 /**
  * pwm_enable - start a PWM output toggling
@@ -1627,7 +1681,8 @@
 		return rc;
 	}
 
-	rc = _pwm_config(pwm_dev, pwm_dev->pwm_config.pwm_duty, period);
+	rc = _pwm_config(pwm_dev, LVL_USEC,
+					pwm_dev->pwm_config.pwm_duty, period);
 
 	return rc;
 }
diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c
index 4f10cf8..c621d2a 100644
--- a/drivers/platform/msm/sps/sps.c
+++ b/drivers/platform/msm/sps/sps.c
@@ -664,6 +664,11 @@
 		return SPS_ERROR;
 	}
 
+	if (sps == NULL || !sps->is_ready) {
+		SPS_DBG2("sps:%s:sps driver is not ready.\n", __func__);
+		return -EPROBE_DEFER;
+	}
+
 	mutex_lock(&sps->lock);
 	/* Search for the target BAM device */
 	bam = sps_h2bam(dev);
@@ -1100,6 +1105,11 @@
 
 	SPS_DBG("sps:%s.", __func__);
 
+	if (sps == NULL || !sps->is_ready) {
+		SPS_DBG2("sps:%s:sps driver is not ready.\n", __func__);
+		return -EPROBE_DEFER;
+	}
+
 	if (handle == NULL) {
 		SPS_ERR("sps:%s:handle is NULL.\n", __func__);
 		return SPS_ERROR;
@@ -1142,6 +1152,11 @@
 		return SPS_ERROR;
 	}
 
+	if (sps == NULL || !sps->is_ready) {
+		SPS_DBG2("sps:%s:sps driver is not ready.\n", __func__);
+		return -EPROBE_DEFER;
+	}
+
 	if (use_offset) {
 		if ((addr + size) <= sps->pipemem_size)
 			mem_buffer->phys_base = sps->pipemem_phys_base + addr;
@@ -1752,6 +1767,11 @@
 		return SPS_ERROR;
 	}
 
+	if (sps == NULL || !sps->is_ready) {
+		SPS_DBG2("sps:%s:sps driver is not ready.\n", __func__);
+		return -EPROBE_DEFER;
+	}
+
 	mutex_lock(&sps->lock);
 	/* Search for the target BAM device */
 	bam = sps_h2bam(dev);
@@ -1997,8 +2017,10 @@
 
 	SPS_DBG("sps:%s.", __func__);
 
-	if (!sps->is_ready)
+	if (sps == NULL || !sps->is_ready) {
+		SPS_DBG2("sps:%s:sps driver is not ready.\n", __func__);
 		return -EPROBE_DEFER;
+	}
 
 	if (clk_on == true) {
 		SPS_DBG("sps:vote for bam dma clk.\n");
@@ -2039,8 +2061,10 @@
 		return SPS_ERROR;
 	}
 
-	if (sps == NULL)
-		return SPS_ERROR;
+	if (sps == NULL) {
+		SPS_DBG2("sps:%s:sps driver is not ready.\n", __func__);
+		return -EPROBE_DEFER;
+	}
 
 	/* BAM-DMA is registered internally during power-up */
 	if ((!sps->is_ready) && !(bam_props->options & SPS_BAM_OPT_BAMDMA)) {
@@ -2507,7 +2531,7 @@
 
 	sps->dfab_clk = clk_get(sps->dev, "dfab_clk");
 	if (IS_ERR(sps->dfab_clk)) {
-		if (IS_ERR(sps->dfab_clk) == -EPROBE_DEFER)
+		if (PTR_ERR(sps->dfab_clk) == -EPROBE_DEFER)
 			ret = -EPROBE_DEFER;
 		else
 			SPS_ERR("sps:fail to get dfab_clk.");
@@ -2524,7 +2548,7 @@
 	if (!d_type) {
 		sps->pmem_clk = clk_get(sps->dev, "mem_clk");
 		if (IS_ERR(sps->pmem_clk)) {
-			if (IS_ERR(sps->pmem_clk) == -EPROBE_DEFER)
+			if (PTR_ERR(sps->pmem_clk) == -EPROBE_DEFER)
 				ret = -EPROBE_DEFER;
 			else
 				SPS_ERR("sps:fail to get pmem_clk.");
@@ -2541,7 +2565,7 @@
 #ifdef CONFIG_SPS_SUPPORT_BAMDMA
 	sps->bamdma_clk = clk_get(sps->dev, "dma_bam_pclk");
 	if (IS_ERR(sps->bamdma_clk)) {
-		if (IS_ERR(sps->bamdma_clk) == -EPROBE_DEFER)
+		if (PTR_ERR(sps->bamdma_clk) == -EPROBE_DEFER)
 			ret = -EPROBE_DEFER;
 		else
 			SPS_ERR("sps:fail to get bamdma_clk.");
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index b918110..4688514 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -152,6 +152,7 @@
 	POWER_SUPPLY_ATTR(current_max),
 	POWER_SUPPLY_ATTR(input_current_max),
 	POWER_SUPPLY_ATTR(input_current_trim),
+	POWER_SUPPLY_ATTR(input_current_settled),
 	POWER_SUPPLY_ATTR(current_now),
 	POWER_SUPPLY_ATTR(current_avg),
 	POWER_SUPPLY_ATTR(power_now),
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index aa4e016..85a70ea 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -765,10 +765,22 @@
 	return get_battery_status(chip) == POWER_SUPPLY_STATUS_FULL;
 }
 
+#define BAT_PRES_BIT		BIT(7)
 static bool is_battery_present(struct qpnp_bms_chip *chip)
 {
 	union power_supply_propval ret = {0,};
+	int rc;
+	u8 batt_pres;
 
+	/* first try to use the batt_pres register if given */
+	if (chip->batt_pres_addr) {
+		rc = qpnp_read_wrapper(chip, &batt_pres,
+				chip->batt_pres_addr, 1);
+		if (!rc && (batt_pres & BAT_PRES_BIT))
+			return true;
+		else
+			return false;
+	}
 	if (chip->batt_psy == NULL)
 		chip->batt_psy = power_supply_get_by_name("battery");
 	if (chip->batt_psy) {
@@ -922,14 +934,67 @@
 	}
 }
 
+#define SIGN(x) ((x) < 0 ? -1 : 1)
+#define UV_PER_SPIN 50000
+static int find_ocv_for_pc(struct qpnp_bms_chip *chip, int batt_temp, int pc)
+{
+	int new_pc;
+	int batt_temp_degc = batt_temp / 10;
+	int ocv_mv;
+	int delta_mv = 5;
+	int max_spin_count;
+	int count = 0;
+	int sign, new_sign;
+
+	ocv_mv = interpolate_ocv(chip->pc_temp_ocv_lut, batt_temp_degc, pc);
+
+	new_pc = interpolate_pc(chip->pc_temp_ocv_lut, batt_temp_degc, ocv_mv);
+	pr_debug("test revlookup pc = %d for ocv = %d\n", new_pc, ocv_mv);
+	max_spin_count = 1 + (chip->max_voltage_uv - chip->v_cutoff_uv)
+						/ UV_PER_SPIN;
+	sign = SIGN(pc - new_pc);
+
+	while (abs(new_pc - pc) != 0 && count < max_spin_count) {
+		/*
+		 * If the newly interpolated pc is larger than the lookup pc,
+		 * the ocv should be reduced and vice versa
+		 */
+		new_sign = SIGN(pc - new_pc);
+		/*
+		 * If the sign has changed, then we have passed the lookup pc.
+		 * reduce the ocv step size to get finer results.
+		 *
+		 * If we have already reduced the ocv step size and still
+		 * passed the lookup pc, just stop and use the current ocv.
+		 * This can only happen if the batterydata profile is
+		 * non-monotonic anyways.
+		 */
+		if (new_sign != sign) {
+			if (delta_mv > 1)
+				delta_mv = 1;
+			else
+				break;
+		}
+		sign = new_sign;
+
+		ocv_mv = ocv_mv + delta_mv * sign;
+		new_pc = interpolate_pc(chip->pc_temp_ocv_lut,
+				batt_temp_degc, ocv_mv);
+		pr_debug("test revlookup pc = %d for ocv = %d\n",
+			new_pc, ocv_mv);
+		count++;
+	}
+
+	return ocv_mv * 1000;
+}
+
 #define OCV_RAW_UNINITIALIZED	0xFFFF
 #define MIN_OCV_UV		2000000
 static int read_soc_params_raw(struct qpnp_bms_chip *chip,
 				struct raw_soc_params *raw,
 				int batt_temp)
 {
-	int warm_reset;
-	int rc;
+	int warm_reset, rc;
 
 	mutex_lock(&chip->bms_output_lock);
 
@@ -977,8 +1042,8 @@
 		chip->done_charging = false;
 		/* if we just finished charging, reset CC and fake 100% */
 		chip->ocv_reading_at_100 = raw->last_good_ocv_raw;
-		chip->last_ocv_uv = chip->max_voltage_uv;
-		raw->last_good_ocv_uv = chip->max_voltage_uv;
+		chip->last_ocv_uv = find_ocv_for_pc(chip, batt_temp, 100);
+		raw->last_good_ocv_uv = chip->last_ocv_uv;
 		raw->cc = 0;
 		raw->shdw_cc = 0;
 		reset_cc(chip, CLEAR_CC | CLEAR_SHDW_CC);
@@ -1355,60 +1420,6 @@
 	return pc;
 }
 
-#define SIGN(x) ((x) < 0 ? -1 : 1)
-#define UV_PER_SPIN 50000
-static int find_ocv_for_pc(struct qpnp_bms_chip *chip, int batt_temp, int pc)
-{
-	int new_pc;
-	int batt_temp_degc = batt_temp / 10;
-	int ocv_mv;
-	int delta_mv = 5;
-	int max_spin_count;
-	int count = 0;
-	int sign, new_sign;
-
-	ocv_mv = interpolate_ocv(chip->pc_temp_ocv_lut, batt_temp_degc, pc);
-
-	new_pc = interpolate_pc(chip->pc_temp_ocv_lut, batt_temp_degc, ocv_mv);
-	pr_debug("test revlookup pc = %d for ocv = %d\n", new_pc, ocv_mv);
-	max_spin_count = 1 + (chip->max_voltage_uv - chip->v_cutoff_uv)
-						/ UV_PER_SPIN;
-	sign = SIGN(pc - new_pc);
-
-	while (abs(new_pc - pc) != 0 && count < max_spin_count) {
-		/*
-		 * If the newly interpolated pc is larger than the lookup pc,
-		 * the ocv should be reduced and vice versa
-		 */
-		new_sign = SIGN(pc - new_pc);
-		/*
-		 * If the sign has changed, then we have passed the lookup pc.
-		 * reduce the ocv step size to get finer results.
-		 *
-		 * If we have already reduced the ocv step size and still
-		 * passed the lookup pc, just stop and use the current ocv.
-		 * This can only happen if the batterydata profile is
-		 * non-monotonic anyways.
-		 */
-		if (new_sign != sign) {
-			if (delta_mv > 1)
-				delta_mv = 1;
-			else
-				break;
-		}
-		sign = new_sign;
-
-		ocv_mv = ocv_mv + delta_mv * sign;
-		new_pc = interpolate_pc(chip->pc_temp_ocv_lut,
-				batt_temp_degc, ocv_mv);
-		pr_debug("test revlookup pc = %d for ocv = %d\n",
-			new_pc, ocv_mv);
-		count++;
-	}
-
-	return ocv_mv * 1000;
-}
-
 static int get_current_time(unsigned long *now_tm_sec)
 {
 	struct rtc_time tm;
@@ -1677,10 +1688,13 @@
 
 	rc = qpnp_write_wrapper(chip, &temp, chip->base + IAVG_STORAGE_REG, 1);
 
-	/* don't store soc if temperature is below 5degC */
+	/* store an invalid soc if temperature is below 5degC */
 	if (batt_temp > IGNORE_SOC_TEMP_DECIDEG)
 		qpnp_masked_write_base(chip, chip->soc_storage_addr,
 				SOC_STORAGE_MASK, (soc + 1) << 1);
+	else
+		qpnp_masked_write_base(chip, chip->soc_storage_addr,
+				SOC_STORAGE_MASK, SOC_STORAGE_MASK);
 }
 
 static int scale_soc_while_chg(struct qpnp_bms_chip *chip, int chg_time_sec,
@@ -1817,8 +1831,15 @@
 					chip->catch_up_time_sec,
 					soc, chip->last_soc);
 
-		soc_change = min((int)abs(chip->last_soc - soc),
-			time_since_last_change_sec / SOC_CHANGE_PER_SEC);
+		/* if the battery is close to cutoff allow more change */
+		if (wake_lock_active(&chip->low_voltage_wake_lock))
+			soc_change = min((int)abs(chip->last_soc - soc),
+				time_since_last_change_sec);
+		else
+			soc_change = min((int)abs(chip->last_soc - soc),
+				time_since_last_change_sec
+					/ SOC_CHANGE_PER_SEC);
+
 		if (chip->last_soc_unbound) {
 			chip->last_soc_unbound = false;
 		} else {
@@ -1994,7 +2015,7 @@
 	}
 }
 
-#define NO_ADJUST_HIGH_SOC_THRESHOLD	90
+#define NO_ADJUST_HIGH_SOC_THRESHOLD	98
 static int adjust_soc(struct qpnp_bms_chip *chip, struct soc_params *params,
 							int soc, int batt_temp)
 {
@@ -2050,9 +2071,10 @@
 	 * because we might pull it low
 	 * and cause a bad user experience
 	 */
-	if (soc_est == soc
-		|| soc_est > chip->adjust_soc_low_threshold
-		|| soc >= NO_ADJUST_HIGH_SOC_THRESHOLD)
+	if (!wake_lock_active(&chip->low_voltage_wake_lock) &&
+			(soc_est == soc
+			|| soc_est > chip->adjust_soc_low_threshold
+			|| soc >= NO_ADJUST_HIGH_SOC_THRESHOLD))
 		goto out;
 
 	if (chip->last_soc_est == -EINVAL)
@@ -2097,8 +2119,11 @@
 		pr_debug("new delta ocv = %d\n", delta_ocv_uv);
 	}
 
-	if (wake_lock_active(&chip->low_voltage_wake_lock))
+	if (wake_lock_active(&chip->low_voltage_wake_lock)) {
+		/* when in the cutoff region, do not correct upwards */
+		delta_ocv_uv = max(0, delta_ocv_uv);
 		goto skip_limits;
+	}
 
 	if (chip->last_ocv_uv > chip->flat_ocv_threshold_uv)
 		correction_limit_uv = chip->high_ocv_correction_limit_uv;
@@ -2246,6 +2271,8 @@
 	qpnp_write_wrapper(chip, (u8 *)&ocv_raw,
 			chip->base + BMS1_OCV_THR0, 2);
 
+	enable_bms_irq(&chip->ocv_thr_irq);
+	enable_bms_irq(&chip->sw_cc_thr_irq);
 	pr_debug("current sw_cc_raw = 0x%llx, current ocv = 0x%hx\n",
 			current_shdw_cc_raw, (uint16_t)current_ocv_raw);
 	pr_debug("target_cc_uah = %lld, raw64 = 0x%llx, raw 36 = 0x%llx, ocv_raw = 0x%hx\n",
@@ -2254,6 +2281,7 @@
 			(uint16_t)ocv_raw);
 }
 
+#define BAD_SOC_THRESH	-10
 static int calculate_raw_soc(struct qpnp_bms_chip *chip,
 					struct raw_soc_params *raw,
 					struct soc_params *params,
@@ -2270,7 +2298,7 @@
 	soc = DIV_ROUND_CLOSEST((remaining_usable_charge_uah * 100),
 				(params->fcc_uah - params->uuc_uah));
 
-	if (chip->first_time_calc_soc && soc < 0) {
+	if (chip->first_time_calc_soc && soc > BAD_SOC_THRESH && soc < 0) {
 		/*
 		 * first time calcualtion and the pon ocv  is too low resulting
 		 * in a bad soc. Adjust ocv to get 0 soc
@@ -2295,7 +2323,7 @@
 	if (soc > 100)
 		soc = 100;
 
-	if (soc < 0) {
+	if (soc > BAD_SOC_THRESH && soc < 0) {
 		pr_debug("bad rem_usb_chg = %d rem_chg %d, cc_uah %d, unusb_chg %d\n",
 				remaining_usable_charge_uah,
 				params->ocv_charge_uah,
@@ -2376,9 +2404,13 @@
 	 * If the battery is full, configure the cc threshold so the system
 	 * wakes up after SoC changes
 	 */
-	if (is_battery_full(chip))
+	if (is_battery_full(chip)) {
 		configure_soc_wakeup(chip, &params,
 				batt_temp, bound_soc(new_calculated_soc - 1));
+	} else {
+		disable_bms_irq(&chip->ocv_thr_irq);
+		disable_bms_irq(&chip->sw_cc_thr_irq);
+	}
 done_calculating:
 	mutex_lock(&chip->last_soc_mutex);
 	previous_soc = chip->calculated_soc;
@@ -3220,8 +3252,6 @@
 
 		if (status == POWER_SUPPLY_STATUS_FULL) {
 			pr_debug("battery full\n");
-			enable_bms_irq(&chip->ocv_thr_irq);
-			enable_bms_irq(&chip->sw_cc_thr_irq);
 			recalculate_soc(chip);
 		} else if (chip->battery_status
 				== POWER_SUPPLY_STATUS_FULL) {
@@ -3488,7 +3518,7 @@
 			|| shutdown_soc_out_of_limit) {
 		chip->battery_removed = true;
 		chip->shutdown_soc_invalid = true;
-		chip->shutdown_iavg_ma = 0;
+		chip->shutdown_iavg_ma = MIN_IAVG_MA;
 		pr_debug("Ignoring shutdown SoC: invalid = %d, offmode = %d, out_of_limit = %d\n",
 				invalid_stored_soc, offmode_battery_replaced,
 				shutdown_soc_out_of_limit);
@@ -3520,6 +3550,7 @@
 	struct qpnp_bms_chip *chip = _chip;
 
 	pr_debug("sw_cc_thr irq triggered\n");
+	disable_bms_irq(&chip->sw_cc_thr_irq);
 	bms_stay_awake(&chip->soc_wake_source);
 	schedule_work(&chip->recalc_work);
 	return IRQ_HANDLED;
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 411aebc..6ea4ea6 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -70,8 +70,9 @@
 #define CHGR_IBAT_TERM_CHGR			0x5B
 #define CHGR_IBAT_TERM_BMS			0x5C
 #define CHGR_VBAT_DET				0x5D
+#define CHGR_TTRKL_MAX_EN			0x5E
 #define CHGR_TTRKL_MAX				0x5F
-#define CHGR_TTRKL_MAX_EN			0x60
+#define CHGR_TCHG_MAX_EN			0x60
 #define CHGR_TCHG_MAX				0x61
 #define CHGR_CHG_WDOG_TIME			0x62
 #define CHGR_CHG_WDOG_DLY			0x63
@@ -101,6 +102,7 @@
 #define BUCK_VCHG_OV				0x77
 #define BUCK_TEST_SMBC_MODES			0xE6
 #define BUCK_CTRL_TRIM1				0xF1
+#define BUCK_CTRL_TRIM3				0xF3
 #define SEC_ACCESS				0xD0
 #define BAT_IF_VREF_BAT_THM_CTRL		0x4A
 #define BAT_IF_BPD_CTRL				0x48
@@ -310,6 +312,9 @@
 	bool				btc_disabled;
 	bool				use_default_batt_values;
 	bool				duty_cycle_100p;
+	bool				ibat_calibration_enabled;
+	bool				aicl_settled;
+	bool				use_external_rsense;
 	unsigned int			bpd_detection;
 	unsigned int			max_bat_chg_current;
 	unsigned int			warm_bat_chg_ma;
@@ -363,6 +368,7 @@
 	bool				batfet_ext_en;
 	struct work_struct		batfet_lcl_work;
 	struct qpnp_vadc_chip		*vadc_dev;
+	struct qpnp_iadc_chip		*iadc_dev;
 	struct qpnp_adc_tm_chip		*adc_tm_dev;
 	struct mutex			jeita_configure_lock;
 	spinlock_t			usbin_health_monitor_lock;
@@ -422,6 +428,16 @@
 	return -EINVAL;
 }
 
+static bool
+is_within_range(int value, int left, int right)
+{
+	if (left >= right && left >= value && value >= right)
+		return 1;
+	if (left <= right && left <= value && value <= right)
+		return 1;
+	return 0;
+}
+
 static int
 qpnp_chg_read(struct qpnp_chg_chip *chip, u8 *val,
 			u16 base, int count)
@@ -624,6 +640,22 @@
 	return (usbin_valid_rt_sts & USB_VALID_BIT) ? 1 : 0;
 }
 
+static bool
+qpnp_chg_is_ibat_loop_active(struct qpnp_chg_chip *chip)
+{
+	int rc;
+	u8 buck_sts;
+
+	rc = qpnp_chg_read(chip, &buck_sts,
+			INT_RT_STS(chip->buck_base), 1);
+	if (rc) {
+		pr_err("failed to read buck RT status rc=%d\n", rc);
+		return 0;
+	}
+
+	return !!(buck_sts & IBAT_LOOP_IRQ);
+}
+
 #define USB_VALID_MASK 0xC0
 #define USB_COARSE_DET 0x10
 #define USB_VALID_UVP_VALUE    0x00
@@ -1157,9 +1189,16 @@
 qpnp_chg_usb_chg_gone_irq_handler(int irq, void *_chip)
 {
 	struct qpnp_chg_chip *chip = _chip;
+	u8 usb_sts;
+	int rc;
+
+	rc = qpnp_chg_read(chip, &usb_sts,
+			INT_RT_STS(chip->usb_chgpth_base), 1);
+	if (rc)
+		pr_err("failed to read usb_chgpth_sts rc=%d\n", rc);
 
 	pr_debug("chg_gone triggered\n");
-	if (qpnp_chg_is_usb_chg_plugged_in(chip)) {
+	if (qpnp_chg_is_usb_chg_plugged_in(chip) && (usb_sts & CHG_GONE_IRQ)) {
 		qpnp_chg_charge_en(chip, 0);
 		qpnp_chg_force_run_on_batt(chip, 1);
 		schedule_delayed_work(&chip->arb_stop_work,
@@ -1246,6 +1285,21 @@
 	return 0;
 }
 
+static int
+qpnp_chg_vddmax_get(struct qpnp_chg_chip *chip)
+{
+	int rc;
+	u8 vddmax = 0;
+
+	rc = qpnp_chg_read(chip, &vddmax, chip->chgr_base + CHGR_VDD_MAX, 1);
+	if (rc) {
+		pr_err("Failed to write vddmax: %d\n", rc);
+		return rc;
+	}
+
+	return QPNP_CHG_V_MIN_MV + (int)vddmax * QPNP_CHG_V_STEP_MV;
+}
+
 /* JEITA compliance logic */
 static void
 qpnp_chg_set_appropriate_vddmax(struct qpnp_chg_chip *chip)
@@ -1405,10 +1459,10 @@
 				       (chip->usb_valid_check_ovp)) {
 				usbin_health =
 					qpnp_chg_check_usbin_health(chip);
-				if (chip->usbin_health != usbin_health) {
+				if ((chip->usbin_health != usbin_health)
+					&& (usbin_health == USBIN_OVP)) {
 					chip->usbin_health = usbin_health;
-					if (usbin_health == USBIN_OVP)
-						psy_health_sts =
+					psy_health_sts =
 					POWER_SUPPLY_HEALTH_OVERVOLTAGE;
 					power_supply_set_health_state(
 						chip->usb_psy,
@@ -1421,8 +1475,9 @@
 				qpnp_chg_set_appropriate_vddmax(chip);
 				chip->chg_done = false;
 			}
-			qpnp_chg_usb_suspend_enable(chip, 1);
+			qpnp_chg_usb_suspend_enable(chip, 0);
 			chip->prev_usb_max_ma = -EINVAL;
+			chip->aicl_settled = false;
 		} else {
 			/* when OVP clamped usbin, and then decrease
 			 * the charger voltage to lower than the OVP
@@ -1433,10 +1488,10 @@
 				       (chip->usb_valid_check_ovp)) {
 				usbin_health =
 					qpnp_chg_check_usbin_health(chip);
-				if (chip->usbin_health != usbin_health) {
+				if ((chip->usbin_health != usbin_health)
+					&& (usbin_health == USBIN_OK)) {
 					chip->usbin_health = usbin_health;
-					 if (usbin_health == USBIN_OK)
-						psy_health_sts =
+					psy_health_sts =
 						POWER_SUPPLY_HEALTH_GOOD;
 					power_supply_set_health_state(
 						chip->usb_psy,
@@ -1657,6 +1712,7 @@
 	case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
 	case POWER_SUPPLY_PROP_INPUT_CURRENT_MAX:
 	case POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM:
+	case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED:
 	case POWER_SUPPLY_PROP_VOLTAGE_MIN:
 	case POWER_SUPPLY_PROP_COOL_TEMP:
 	case POWER_SUPPLY_PROP_WARM_TEMP:
@@ -1771,6 +1827,7 @@
 	POWER_SUPPLY_PROP_CURRENT_NOW,
 	POWER_SUPPLY_PROP_INPUT_CURRENT_MAX,
 	POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM,
+	POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
 	POWER_SUPPLY_PROP_VOLTAGE_MIN,
 	POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION,
 	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
@@ -2035,6 +2092,8 @@
 		if (battery_status != POWER_SUPPLY_STATUS_CHARGING
 				&& bms_status != POWER_SUPPLY_STATUS_CHARGING
 				&& charger_in
+				&& !chip->bat_is_cool
+				&& !chip->bat_is_warm
 				&& !chip->resuming_charging
 				&& !chip->charging_disabled
 				&& chip->soc_resume_limit
@@ -2138,7 +2197,8 @@
 
 		if (ret.intval <= 2 && !chip->use_default_batt_values &&
 						get_prop_batt_present(chip)) {
-			qpnp_chg_usb_suspend_enable(chip, 1);
+			if (ret.intval ==  2)
+				qpnp_chg_usb_suspend_enable(chip, 1);
 			qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100);
 		} else {
 			qpnp_chg_usb_suspend_enable(chip, 0);
@@ -2248,6 +2308,9 @@
 	case POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM:
 		val->intval = qpnp_chg_iusb_trim_get(chip);
 		break;
+	case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED:
+		val->intval = chip->aicl_settled;
+		break;
 	case POWER_SUPPLY_PROP_VOLTAGE_MIN:
 		val->intval = qpnp_chg_vinmin_get(chip) * 1000;
 		break;
@@ -2354,22 +2417,63 @@
 			QPNP_CHG_I_MASK, temp, 1);
 }
 
+static int
+qpnp_chg_ibatmax_get(struct qpnp_chg_chip *chip, int *chg_current)
+{
+	int rc;
+	u8 temp;
+
+	*chg_current = 0;
+	rc = qpnp_chg_read(chip, &temp, chip->chgr_base + CHGR_IBAT_MAX, 1);
+	if (rc) {
+		pr_err("failed read ibat_max rc=%d\n", rc);
+		return rc;
+	}
+
+	*chg_current = ((temp & QPNP_CHG_I_MASK) * QPNP_CHG_I_STEP_MA);
+
+	return 0;
+}
+
 #define QPNP_CHG_TCHG_MASK	0x7F
+#define QPNP_CHG_TCHG_EN_MASK	0x80
 #define QPNP_CHG_TCHG_MIN	4
 #define QPNP_CHG_TCHG_MAX	512
 #define QPNP_CHG_TCHG_STEP	4
 static int qpnp_chg_tchg_max_set(struct qpnp_chg_chip *chip, int minutes)
 {
 	u8 temp;
+	int rc;
 
 	if (minutes < QPNP_CHG_TCHG_MIN || minutes > QPNP_CHG_TCHG_MAX) {
 		pr_err("bad max minutes =%d asked to set\n", minutes);
 		return -EINVAL;
 	}
 
-	temp = (minutes - 1)/QPNP_CHG_TCHG_STEP;
-	return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_TCHG_MAX,
+	rc = qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_TCHG_MAX_EN,
+			QPNP_CHG_TCHG_EN_MASK, 0, 1);
+	if (rc) {
+		pr_err("failed write tchg_max_en rc=%d\n", rc);
+		return rc;
+	}
+
+	temp = minutes / QPNP_CHG_TCHG_STEP - 1;
+
+	rc = qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_TCHG_MAX,
 			QPNP_CHG_TCHG_MASK, temp, 1);
+	if (rc) {
+		pr_err("failed write tchg_max_en rc=%d\n", rc);
+		return rc;
+	}
+
+	rc = qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_TCHG_MAX_EN,
+			QPNP_CHG_TCHG_EN_MASK, QPNP_CHG_TCHG_EN_MASK, 1);
+	if (rc) {
+		pr_err("failed write tchg_max_en rc=%d\n", rc);
+		return rc;
+	}
+
+	return 0;
 }
 
 static int
@@ -2388,6 +2492,155 @@
 		chip->chgr_base + CHGR_VDD_SAFE, 1);
 }
 
+#define IBAT_TRIM_TGT_MA		500
+#define IBAT_TRIM_OFFSET_MASK		0x7F
+#define IBAT_TRIM_GOOD_BIT		BIT(7)
+#define IBAT_TRIM_LOW_LIM		20
+#define IBAT_TRIM_HIGH_LIM		114
+#define IBAT_TRIM_MEAN			64
+
+static void
+qpnp_chg_trim_ibat(struct qpnp_chg_chip *chip, u8 ibat_trim)
+{
+	int ibat_now_ma, ibat_diff_ma, rc;
+	struct qpnp_iadc_result i_result;
+	enum qpnp_iadc_channels iadc_channel;
+
+	iadc_channel = chip->use_external_rsense ?
+				EXTERNAL_RSENSE : INTERNAL_RSENSE;
+	rc = qpnp_iadc_read(chip->iadc_dev, iadc_channel, &i_result);
+	if (rc) {
+		pr_err("Unable to read bat rc=%d\n", rc);
+		return;
+	}
+
+	ibat_now_ma = i_result.result_ua / 1000;
+
+	if (qpnp_chg_is_ibat_loop_active(chip)) {
+		ibat_diff_ma = ibat_now_ma - IBAT_TRIM_TGT_MA;
+
+		if (abs(ibat_diff_ma) > 50) {
+			ibat_trim += (ibat_diff_ma / 20);
+			ibat_trim &= IBAT_TRIM_OFFSET_MASK;
+			/* reject new ibat_trim if it is outside limits */
+			if (!is_within_range(ibat_trim, IBAT_TRIM_LOW_LIM,
+						IBAT_TRIM_HIGH_LIM))
+				return;
+		}
+		ibat_trim |= IBAT_TRIM_GOOD_BIT;
+		rc = qpnp_chg_write(chip, &ibat_trim,
+				chip->buck_base + BUCK_CTRL_TRIM3, 1);
+		if (rc)
+			pr_err("failed to set IBAT_TRIM rc=%d\n", rc);
+
+		pr_debug("ibat_now=%dmA, itgt=%dmA, ibat_diff=%dmA, ibat_trim=%x\n",
+					ibat_now_ma, IBAT_TRIM_TGT_MA,
+					ibat_diff_ma, ibat_trim);
+	} else {
+		pr_debug("ibat loop not active - cannot calibrate ibat\n");
+	}
+}
+
+static int
+qpnp_chg_input_current_settled(struct qpnp_chg_chip *chip)
+{
+	int rc, ibat_max_ma;
+	u8 reg, chgr_sts, ibat_trim, i;
+
+	chip->aicl_settled = true;
+
+	/*
+	 * Perform the ibat calibration.
+	 * This is for devices which have a IBAT_TRIM error
+	 * which can show IBAT_MAX out of spec.
+	 */
+	if (!chip->ibat_calibration_enabled)
+		return 0;
+
+	if (chip->type != SMBB)
+		return 0;
+
+	rc = qpnp_chg_read(chip, &reg,
+			chip->buck_base + BUCK_CTRL_TRIM3, 1);
+	if (rc) {
+		pr_err("failed to read BUCK_CTRL_TRIM3 rc=%d\n", rc);
+		return rc;
+	}
+	if (reg & IBAT_TRIM_GOOD_BIT) {
+		pr_debug("IBAT_TRIM_GOOD bit already set. Quitting!\n");
+		return 0;
+	}
+	ibat_trim = reg & IBAT_TRIM_OFFSET_MASK;
+
+	if (!is_within_range(ibat_trim, IBAT_TRIM_LOW_LIM,
+					IBAT_TRIM_HIGH_LIM)) {
+		pr_debug("Improper ibat_trim value=%x setting to value=%x\n",
+						ibat_trim, IBAT_TRIM_MEAN);
+		ibat_trim = IBAT_TRIM_MEAN;
+		rc = qpnp_chg_masked_write(chip,
+				chip->buck_base + BUCK_CTRL_TRIM3,
+				IBAT_TRIM_OFFSET_MASK, ibat_trim, 1);
+		if (rc) {
+			pr_err("failed to set ibat_trim to %x rc=%d\n",
+						IBAT_TRIM_MEAN, rc);
+			return rc;
+		}
+	}
+
+	rc = qpnp_chg_read(chip, &chgr_sts,
+				INT_RT_STS(chip->chgr_base), 1);
+	if (rc) {
+		pr_err("failed to read interrupt sts rc=%d\n", rc);
+		return rc;
+	}
+	if (!(chgr_sts & FAST_CHG_ON_IRQ)) {
+		pr_debug("Not in fastchg\n");
+		return rc;
+	}
+
+	/* save the ibat_max to restore it later */
+	rc = qpnp_chg_ibatmax_get(chip, &ibat_max_ma);
+	if (rc) {
+		pr_debug("failed to save ibatmax rc=%d\n", rc);
+		return rc;
+	}
+
+	rc = qpnp_chg_ibatmax_set(chip, IBAT_TRIM_TGT_MA);
+	if (rc) {
+		pr_err("failed to set ibatmax rc=%d\n", rc);
+		return rc;
+	}
+
+	for (i = 0; i < 3; i++) {
+		/*
+		 * ibat settling delay - to make sure the BMS controller
+		 * has sufficient time to sample ibat for the configured
+		 * ibat_max
+		 */
+		msleep(20);
+		if (qpnp_chg_is_ibat_loop_active(chip))
+			qpnp_chg_trim_ibat(chip, ibat_trim);
+		else
+			pr_debug("ibat loop not active\n");
+
+		/* read the adjusted ibat_trim for further adjustments */
+		rc = qpnp_chg_read(chip, &ibat_trim,
+			chip->buck_base + BUCK_CTRL_TRIM3, 1);
+		if (rc) {
+			pr_err("failed to read BUCK_CTRL_TRIM3 rc=%d\n", rc);
+			break;
+		}
+	}
+
+	/* restore IBATMAX */
+	rc = qpnp_chg_ibatmax_set(chip, ibat_max_ma);
+	if (rc)
+		pr_err("failed to restore ibatmax rc=%d\n", rc);
+
+	return rc;
+}
+
+
 #define BOOST_MIN_UV	4200000
 #define BOOST_MAX_UV	5500000
 #define BOOST_STEP_UV	50000
@@ -2882,10 +3135,17 @@
 			count = 0;
 		} else {
 			if (count == CONSECUTIVE_COUNT) {
-				pr_info("End of Charging\n");
+				if (!chip->bat_is_cool && !chip->bat_is_warm) {
+					pr_info("End of Charging\n");
+					chip->chg_done = true;
+				} else {
+					pr_info("stop charging: battery is %s, vddmax = %d reached\n",
+						chip->bat_is_cool
+							? "cool" : "warm",
+						qpnp_chg_vddmax_get(chip));
+				}
 				chip->delta_vddmax_mv = 0;
 				qpnp_chg_set_appropriate_vddmax(chip);
-				chip->chg_done = true;
 				qpnp_chg_charge_en(chip, 0);
 				/* sleep for a second before enabling */
 				msleep(2000);
@@ -3386,6 +3646,9 @@
 	case POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM:
 		qpnp_chg_iusb_trim_set(chip, val->intval);
 		break;
+	case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED:
+		qpnp_chg_input_current_settled(chip);
+		break;
 	case POWER_SUPPLY_PROP_VOLTAGE_MIN:
 		qpnp_chg_vinmin_set(chip, val->intval / 1000);
 		break;
@@ -4107,6 +4370,11 @@
 			return rc;
 	}
 
+	/* Get the use-external-rsense property */
+	chip->use_external_rsense = of_property_read_bool(
+			chip->spmi->dev.of_node,
+			"qcom,use-external-rsense");
+
 	/* Get the btc-disabled property */
 	chip->btc_disabled = of_property_read_bool(chip->spmi->dev.of_node,
 					"qcom,btc-disabled");
@@ -4139,17 +4407,21 @@
 			of_property_read_bool(chip->spmi->dev.of_node,
 					"qcom,power-stage-reduced");
 
+	chip->ibat_calibration_enabled =
+			of_property_read_bool(chip->spmi->dev.of_node,
+					"qcom,ibat-calibration-enabled");
+
 	of_get_property(chip->spmi->dev.of_node, "qcom,thermal-mitigation",
 		&(chip->thermal_levels));
 
 	if (chip->thermal_levels > sizeof(int)) {
-		chip->thermal_mitigation = kzalloc(
+		chip->thermal_mitigation = devm_kzalloc(chip->dev,
 			chip->thermal_levels,
 			GFP_KERNEL);
 
 		if (chip->thermal_mitigation == NULL) {
 			pr_err("thermal mitigation kzalloc() failed.\n");
-			return rc;
+			return -ENOMEM;
 		}
 
 		chip->thermal_levels /= sizeof(int);
@@ -4174,7 +4446,8 @@
 	struct spmi_resource *spmi_resource;
 	int rc = 0;
 
-	chip = kzalloc(sizeof *chip, GFP_KERNEL);
+	chip = devm_kzalloc(&spmi->dev,
+			sizeof(struct qpnp_chg_chip), GFP_KERNEL);
 	if (chip == NULL) {
 		pr_err("kzalloc() failed.\n");
 		return -ENOMEM;
@@ -4207,7 +4480,7 @@
 	/* Get all device tree properties */
 	rc = qpnp_charger_read_dt_props(chip);
 	if (rc)
-		goto fail_chg_enable;
+		return rc;
 
 	/*
 	 * Check if bat_if is set in DT and make sure VADC is present
@@ -4247,6 +4520,17 @@
 				goto fail_chg_enable;
 			}
 
+			if (subtype == SMBB_BAT_IF_SUBTYPE) {
+				chip->iadc_dev = qpnp_get_iadc(chip->dev,
+						"chg");
+				if (IS_ERR(chip->iadc_dev)) {
+					rc = PTR_ERR(chip->iadc_dev);
+					if (rc != -EPROBE_DEFER)
+						pr_err("iadc property missing\n");
+					goto fail_chg_enable;
+				}
+			}
+
 			rc = qpnp_chg_load_battery_data(chip);
 			if (rc)
 				goto fail_chg_enable;
@@ -4489,6 +4773,7 @@
 		goto unregister_dc_psy;
 	}
 
+	qpnp_chg_usb_chg_gone_irq_handler(chip->chg_gone.irq, chip);
 	qpnp_chg_usb_usbin_valid_irq_handler(chip->usbin_valid.irq, chip);
 	qpnp_chg_dc_dcin_valid_irq_handler(chip->dcin_valid.irq, chip);
 	power_supply_set_present(chip->usb_psy,
@@ -4519,9 +4804,6 @@
 fail_chg_enable:
 	regulator_unregister(chip->otg_vreg.rdev);
 	regulator_unregister(chip->boost_vreg.rdev);
-	kfree(chip->thermal_mitigation);
-	kfree(chip);
-	dev_set_drvdata(&spmi->dev, NULL);
 	return rc;
 }
 
@@ -4534,15 +4816,27 @@
 		qpnp_adc_tm_disable_chan_meas(chip->adc_tm_dev,
 							&chip->adc_param);
 	}
-	cancel_work_sync(&chip->adc_measure_work);
+
+	cancel_delayed_work_sync(&chip->aicl_check_work);
+	power_supply_unregister(&chip->dc_psy);
+	cancel_work_sync(&chip->soc_check_work);
+	cancel_delayed_work_sync(&chip->usbin_health_check);
+	cancel_delayed_work_sync(&chip->arb_stop_work);
 	cancel_delayed_work_sync(&chip->eoc_work);
+	cancel_work_sync(&chip->adc_disable_work);
+	cancel_work_sync(&chip->adc_measure_work);
+	power_supply_unregister(&chip->batt_psy);
+	cancel_work_sync(&chip->batfet_lcl_work);
+	cancel_work_sync(&chip->insertion_ocv_work);
+	cancel_work_sync(&chip->reduce_power_stage_work);
+	alarm_cancel(&chip->reduce_power_stage_alarm);
+
+	mutex_destroy(&chip->batfet_vreg_lock);
+	mutex_destroy(&chip->jeita_configure_lock);
 
 	regulator_unregister(chip->otg_vreg.rdev);
 	regulator_unregister(chip->boost_vreg.rdev);
 
-	dev_set_drvdata(&spmi->dev, NULL);
-	kfree(chip);
-
 	return 0;
 }
 
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 01dce2d..0d17026 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -7,7 +7,7 @@
 obj-$(CONFIG_THERMAL_TSENS)	+= msm_tsens.o
 obj-$(CONFIG_THERMAL_TSENS8960) += msm8960_tsens.o
 obj-$(CONFIG_THERMAL_PM8XXX)	+= pm8xxx-tm.o
-obj-$(CONFIG_THERMAL_MONITOR)	+= msm_thermal.o
+obj-$(CONFIG_THERMAL_MONITOR)	+= msm_thermal.o msm_thermal-dev.o
 obj-$(CONFIG_SPEAR_THERMAL)		+= spear_thermal.o
 obj-$(CONFIG_THERMAL_TSENS8974)	+= msm8974-tsens.o
 obj-$(CONFIG_THERMAL_QPNP)	+= qpnp-temp-alarm.o
diff --git a/drivers/thermal/msm_thermal-dev.c b/drivers/thermal/msm_thermal-dev.c
new file mode 100644
index 0000000..c34dd27
--- /dev/null
+++ b/drivers/thermal/msm_thermal-dev.c
@@ -0,0 +1,224 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/msm_thermal_ioctl.h>
+#include <linux/msm_thermal.h>
+#include <linux/uaccess.h>
+#include <linux/cdev.h>
+#include <linux/semaphore.h>
+#include <linux/module.h>
+
+struct msm_thermal_ioctl_dev {
+	struct semaphore sem;
+	struct cdev char_dev;
+};
+
+static int msm_thermal_major;
+static struct class *thermal_class;
+static struct msm_thermal_ioctl_dev *msm_thermal_dev;
+
+static int msm_thermal_ioctl_open(struct inode *node, struct file *filep)
+{
+	int ret = 0;
+	struct msm_thermal_ioctl_dev *dev;
+
+	dev = container_of(node->i_cdev, struct msm_thermal_ioctl_dev,
+		char_dev);
+	filep->private_data = dev;
+
+	return ret;
+}
+
+static int msm_thermal_ioctl_release(struct inode *node, struct file *filep)
+{
+	pr_debug("%s: IOCTL: release\n", KBUILD_MODNAME);
+	return 0;
+}
+
+static long validate_and_copy(unsigned int *cmd, unsigned long *arg,
+	struct msm_thermal_ioctl *query)
+{
+	long ret = 0, err_val = 0;
+
+	if ((_IOC_TYPE(*cmd) != MSM_THERMAL_MAGIC_NUM) ||
+		(_IOC_NR(*cmd) >= MSM_CMD_MAX_NR)) {
+		ret = -ENOTTY;
+		goto validate_exit;
+	}
+
+	if (_IOC_DIR(*cmd) & _IOC_READ) {
+		err_val = !access_ok(VERIFY_WRITE, (void __user *)*arg,
+				_IOC_SIZE(*cmd));
+	} else if (_IOC_DIR(*cmd) & _IOC_WRITE) {
+		err_val = !access_ok(VERIFY_READ, (void __user *)*arg,
+				_IOC_SIZE(*cmd));
+	}
+	if (err_val) {
+		ret = -EFAULT;
+		goto validate_exit;
+	}
+
+	if (copy_from_user(query, (void __user *)(*arg),
+		sizeof(struct msm_thermal_ioctl))) {
+		ret = -EACCES;
+		goto validate_exit;
+	}
+
+	if (query->size != sizeof(struct msm_thermal_ioctl)) {
+		pr_err("%s: Invalid input argument size\n", __func__);
+		ret = -EINVAL;
+		goto validate_exit;
+	}
+
+	switch (*cmd) {
+	case MSM_THERMAL_SET_CPU_MAX_FREQUENCY:
+	case MSM_THERMAL_SET_CPU_MIN_FREQUENCY:
+		if (query->cpu_freq.cpu_num >= num_possible_cpus()) {
+			pr_err("%s: Invalid CPU number: %u\n", __func__,
+				query->cpu_freq.cpu_num);
+			ret = -EINVAL;
+			goto validate_exit;
+		}
+		break;
+	default:
+		ret = -ENOTTY;
+		goto validate_exit;
+		break;
+	}
+
+validate_exit:
+	return ret;
+}
+
+static long msm_thermal_ioctl_process(struct file *filep, unsigned int cmd,
+	unsigned long arg)
+{
+	long ret = 0;
+	struct msm_thermal_ioctl query;
+
+	pr_debug("%s: IOCTL: processing cmd:%u\n", KBUILD_MODNAME, cmd);
+
+	ret = validate_and_copy(&cmd, &arg, &query);
+	if (ret)
+		goto process_exit;
+
+	switch (cmd) {
+	case MSM_THERMAL_SET_CPU_MAX_FREQUENCY:
+		ret = msm_thermal_set_frequency(query.cpu_freq.cpu_num,
+			query.cpu_freq.freq_req, true);
+		break;
+	case MSM_THERMAL_SET_CPU_MIN_FREQUENCY:
+		ret = msm_thermal_set_frequency(query.cpu_freq.cpu_num,
+			query.cpu_freq.freq_req, false);
+		break;
+	default:
+		ret = -ENOTTY;
+		goto process_exit;
+	}
+process_exit:
+	return ret;
+}
+
+static const struct file_operations msm_thermal_fops = {
+	.owner = THIS_MODULE,
+	.open = msm_thermal_ioctl_open,
+	.unlocked_ioctl = msm_thermal_ioctl_process,
+	.release = msm_thermal_ioctl_release,
+};
+
+int msm_thermal_ioctl_init()
+{
+	int ret = 0;
+	dev_t thermal_dev;
+	struct device *therm_device;
+
+	ret = alloc_chrdev_region(&thermal_dev, 0, 1,
+		MSM_THERMAL_IOCTL_NAME);
+	if (ret < 0) {
+		pr_err("%s: Error in allocating char device region. Err:%d\n",
+			KBUILD_MODNAME, ret);
+		goto ioctl_init_exit;
+	}
+
+	msm_thermal_major = MAJOR(thermal_dev);
+
+	thermal_class = class_create(THIS_MODULE, "msm_thermal");
+	if (IS_ERR(thermal_class)) {
+		pr_err("%s: Error in creating class\n",
+			KBUILD_MODNAME);
+		ret = PTR_ERR(thermal_class);
+		goto ioctl_class_fail;
+	}
+
+	therm_device = device_create(thermal_class, NULL, thermal_dev, NULL,
+				MSM_THERMAL_IOCTL_NAME);
+	if (IS_ERR(therm_device)) {
+		pr_err("%s: Error in creating character device\n",
+			KBUILD_MODNAME);
+		ret = PTR_ERR(therm_device);
+		goto ioctl_dev_fail;
+	}
+	msm_thermal_dev = kmalloc(sizeof(struct msm_thermal_ioctl_dev),
+				GFP_KERNEL);
+	if (!msm_thermal_dev) {
+		pr_err("%s: Error allocating memory\n",
+			KBUILD_MODNAME);
+		ret = -ENOMEM;
+		goto ioctl_clean_all;
+	}
+
+	memset(msm_thermal_dev, 0, sizeof(struct msm_thermal_ioctl_dev));
+	sema_init(&msm_thermal_dev->sem, 1);
+	cdev_init(&msm_thermal_dev->char_dev, &msm_thermal_fops);
+	ret = cdev_add(&msm_thermal_dev->char_dev, thermal_dev, 1);
+	if (ret < 0) {
+		pr_err("%s: Error in adding character device\n",
+			KBUILD_MODNAME);
+		goto ioctl_clean_all;
+	}
+
+	return ret;
+
+ioctl_clean_all:
+	device_destroy(thermal_class, thermal_dev);
+ioctl_dev_fail:
+	class_destroy(thermal_class);
+ioctl_class_fail:
+	unregister_chrdev_region(thermal_dev, 1);
+ioctl_init_exit:
+	return ret;
+}
+
+void msm_thermal_ioctl_cleanup()
+{
+	dev_t thermal_dev = MKDEV(msm_thermal_major, 0);
+
+	if (!msm_thermal_dev) {
+		pr_err("%s: Thermal IOCTL cleanup already done\n",
+			KBUILD_MODNAME);
+		return;
+	}
+
+	device_destroy(thermal_class, thermal_dev);
+	class_destroy(thermal_class);
+	cdev_del(&msm_thermal_dev->char_dev);
+	unregister_chrdev_region(thermal_dev, 1);
+	kfree(msm_thermal_dev);
+	msm_thermal_dev = NULL;
+	thermal_class = NULL;
+}
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index e9bb553..c366086 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -35,13 +35,13 @@
 #include <mach/rpm-regulator.h>
 #include <mach/rpm-regulator-smd.h>
 #include <linux/regulator/consumer.h>
+#include <linux/msm_thermal_ioctl.h>
 
+#define MAX_CURRENT_UA 1000000
 #define MAX_RAILS 5
 #define MAX_THRESHOLD 2
 
 static struct msm_thermal_data msm_thermal_info;
-static uint32_t limited_max_freq = UINT_MAX;
-static uint32_t limited_min_freq;
 static struct delayed_work check_temp_work;
 static bool core_control_enabled;
 static uint32_t cpus_offlined;
@@ -52,11 +52,14 @@
 static struct kobject *cc_kobj;
 static struct work_struct timer_work;
 static struct task_struct *hotplug_task;
+static struct task_struct *freq_mitigation_task;
 static struct completion hotplug_notify_complete;
+static struct completion freq_mitigation_complete;
 
 static int enabled;
 static int rails_cnt;
 static int psm_rails_cnt;
+static int ocr_rail_cnt;
 static int limit_idx;
 static int limit_idx_low;
 static int limit_idx_high;
@@ -71,18 +74,38 @@
 static bool psm_nodes_called;
 static bool psm_probed;
 static bool hotplug_enabled;
+static bool freq_mitigation_enabled;
+static bool ocr_enabled;
+static bool ocr_nodes_called;
+static bool ocr_probed;
 static int *tsens_id_map;
 static DEFINE_MUTEX(vdd_rstr_mutex);
 static DEFINE_MUTEX(psm_mutex);
+static DEFINE_MUTEX(ocr_mutex);
+static uint32_t min_freq_limit;
+
+enum thermal_threshold {
+	HOTPLUG_THRESHOLD_HIGH,
+	HOTPLUG_THRESHOLD_LOW,
+	FREQ_THRESHOLD_HIGH,
+	FREQ_THRESHOLD_LOW,
+	THRESHOLD_MAX_NR,
+};
 
 struct cpu_info {
 	uint32_t cpu;
-	bool offline;
-	bool user_offline;
-	bool thresh_cleared;
 	const char *sensor_type;
 	uint32_t sensor_id;
-	struct sensor_threshold thresh[MAX_THRESHOLD];
+	bool offline;
+	bool user_offline;
+	bool hotplug_thresh_clear;
+	struct sensor_threshold threshold[THRESHOLD_MAX_NR];
+	bool max_freq;
+	uint32_t user_max_freq;
+	uint32_t user_min_freq;
+	uint32_t limited_max_freq;
+	uint32_t limited_min_freq;
+	bool freq_thresh_clear;
 };
 
 struct rail {
@@ -104,10 +127,12 @@
 	uint8_t mode;
 	struct kobj_attribute mode_attr;
 	struct rpm_regulator *reg;
+	struct regulator *phase_reg;
 	struct attribute_group attr_gp;
 };
 
 static struct psm_rail *psm_rails;
+static struct psm_rail *ocr_rails;
 static struct rail *rails;
 static struct cpu_info cpus[NR_CPUS];
 
@@ -123,6 +148,12 @@
 	PMIC_PWM_MODE   = RPM_REGULATOR_MODE_HPM,
 };
 
+enum ocr_request {
+	OPTIMUM_CURRENT_MIN,
+	OPTIMUM_CURRENT_MAX,
+	OPTIMUM_CURRENT_NR,
+};
+
 #define VDD_RES_RO_ATTRIB(_rail, ko_attr, j, _name) \
 	ko_attr.attr.name = __stringify(_name); \
 	ko_attr.attr.mode = 444; \
@@ -148,6 +179,14 @@
 #define VDD_RSTR_REG_LEVEL_FROM_ATTRIBS(attr) \
 	(container_of(attr, struct rail, level_attr));
 
+#define OCR_RW_ATTRIB(_rail, ko_attr, j, _name) \
+	ko_attr.attr.name = __stringify(_name); \
+	ko_attr.attr.mode = 644; \
+	ko_attr.show = ocr_reg_##_name##_show; \
+	ko_attr.store = ocr_reg_##_name##_store; \
+	sysfs_attr_init(&ko_attr.attr); \
+	_rail.attr_gp.attrs[j] = &ko_attr.attr;
+
 #define PSM_RW_ATTRIB(_rail, ko_attr, j, _name) \
 	ko_attr.attr.name = __stringify(_name); \
 	ko_attr.attr.mode = 644; \
@@ -163,11 +202,20 @@
 		unsigned long event, void *data)
 {
 	struct cpufreq_policy *policy = data;
+	uint32_t max_freq_req = cpus[policy->cpu].limited_max_freq;
+	uint32_t min_freq_req = cpus[policy->cpu].limited_min_freq;
 
 	switch (event) {
 	case CPUFREQ_INCOMPATIBLE:
-		cpufreq_verify_within_limits(policy, limited_min_freq,
-				limited_max_freq);
+		pr_debug("%s: mitigating cpu %d to freq max: %u min: %u\n",
+		KBUILD_MODNAME, policy->cpu, max_freq_req, min_freq_req);
+
+		cpufreq_verify_within_limits(policy, min_freq_req,
+			max_freq_req);
+
+		if (max_freq_req < min_freq_req)
+			pr_err("Invalid frequency request Max:%u Min:%u\n",
+				max_freq_req, min_freq_req);
 		break;
 	}
 	return NOTIFY_OK;
@@ -193,9 +241,17 @@
 	return ret;
 }
 
+static void update_cpu_freq(int cpu)
+{
+	if (cpu_online(cpu)) {
+		if (cpufreq_update_policy(cpu))
+			pr_err("Unable to update policy for cpu:%d\n", cpu);
+	}
+}
+
 static int update_cpu_min_freq_all(uint32_t min)
 {
-	int cpu = 0;
+	uint32_t cpu = 0;
 	int ret = 0;
 
 	if (!freq_table_get) {
@@ -208,15 +264,17 @@
 	/* If min is larger than allowed max */
 	min = min(min, table[limit_idx_high].frequency);
 
-	limited_min_freq = min;
-
-	get_online_cpus();
-	for_each_online_cpu(cpu) {
-		if (cpufreq_update_policy(cpu))
-			pr_info("%s: Unable to update policy for cpu:%d\n",
-				KBUILD_MODNAME, cpu);
+	if (freq_mitigation_task) {
+		min_freq_limit = min;
+		complete(&freq_mitigation_complete);
+	} else {
+		get_online_cpus();
+		for_each_possible_cpu(cpu) {
+			cpus[cpu].limited_min_freq = min;
+			update_cpu_freq(cpu);
+		}
+		put_online_cpus();
 	}
-	put_online_cpus();
 
 	return ret;
 }
@@ -446,6 +504,92 @@
 	return count;
 }
 
+static int request_optimum_current(struct psm_rail *rail, enum ocr_request req)
+{
+	int ret = 0;
+
+	if ((!rail) || (req >= OPTIMUM_CURRENT_NR) ||
+		(req < 0)) {
+		pr_err("%s:%s Invalid input\n", KBUILD_MODNAME, __func__);
+		ret = -EINVAL;
+		goto request_ocr_exit;
+	}
+
+	ret = regulator_set_optimum_mode(rail->phase_reg,
+		(req == OPTIMUM_CURRENT_MAX) ? MAX_CURRENT_UA : 0);
+	if (ret < 0) {
+		pr_err("%s: Optimum current request failed\n", KBUILD_MODNAME);
+		goto request_ocr_exit;
+	}
+	ret = 0; /*regulator_set_optimum_mode returns the mode on success*/
+	pr_debug("%s: Requested optimum current mode: %d\n",
+		KBUILD_MODNAME, req);
+
+request_ocr_exit:
+	return ret;
+}
+
+static int ocr_set_mode_all(enum ocr_request req)
+{
+	int ret = 0, i;
+
+	for (i = 0; i < ocr_rail_cnt; i++) {
+		if (ocr_rails[i].mode == req)
+			continue;
+		ret = request_optimum_current(&ocr_rails[i], req);
+		if (ret)
+			goto ocr_set_mode_exit;
+		ocr_rails[i].mode = req;
+	}
+
+ocr_set_mode_exit:
+	return ret;
+}
+
+static int ocr_reg_mode_show(struct kobject *kobj,
+	struct kobj_attribute *attr, char *buf)
+{
+	struct psm_rail *reg = PSM_REG_MODE_FROM_ATTRIBS(attr);
+	return snprintf(buf, PAGE_SIZE, "%d\n", reg->mode);
+}
+
+static ssize_t ocr_reg_mode_store(struct kobject *kobj,
+	struct kobj_attribute *attr, const char *buf, size_t count)
+{
+	int ret = 0;
+	int val = 0;
+	struct psm_rail *reg = PSM_REG_MODE_FROM_ATTRIBS(attr);
+
+	if (!ocr_enabled)
+		return count;
+
+	mutex_lock(&ocr_mutex);
+	ret = kstrtoint(buf, 10, &val);
+	if (ret) {
+		pr_err("%s: Invalid input %s for mode\n",
+			KBUILD_MODNAME, buf);
+		goto done_ocr_store;
+	}
+
+	if ((val != OPTIMUM_CURRENT_MAX) &&
+		(val != OPTIMUM_CURRENT_MIN)) {
+		pr_err("%s: Invalid value %d for mode\n",
+			KBUILD_MODNAME, val);
+		goto done_ocr_store;
+	}
+
+	if (val != reg->mode) {
+		ret = request_optimum_current(reg, val);
+		if (ret)
+			goto done_ocr_store;
+		reg->mode = val;
+	}
+
+done_ocr_store:
+	mutex_unlock(&ocr_mutex);
+	return count;
+}
+
 static int psm_reg_mode_show(
 	struct kobject *kobj, struct kobj_attribute *attr, char *buf)
 {
@@ -607,27 +751,6 @@
 	return ret;
 }
 
-static int update_cpu_max_freq(int cpu, uint32_t max_freq)
-{
-	int ret = 0;
-
-	if (max_freq != UINT_MAX)
-		pr_info("%s: Limiting cpu%d max frequency to %d\n",
-				KBUILD_MODNAME, cpu, max_freq);
-	else
-		pr_info("%s: Max frequency reset for cpu%d\n",
-				KBUILD_MODNAME, cpu);
-	get_online_cpus();
-	for_each_online_cpu(cpu) {
-		if (cpufreq_update_policy(cpu))
-			pr_info("%s: Unable to update policy for cpu:%d\n",
-				KBUILD_MODNAME, cpu);
-	}
-	put_online_cpus();
-
-	return ret;
-}
-
 static int set_and_activate_threshold(uint32_t sensor_id,
 	struct sensor_threshold *threshold)
 {
@@ -788,10 +911,11 @@
 		mutex_lock(&core_control_mutex);
 		for_each_possible_cpu(cpu) {
 			if (hotplug_enabled &&
-				cpus[cpu].thresh_cleared) {
+				cpus[cpu].hotplug_thresh_clear) {
 				set_threshold(cpus[cpu].sensor_id,
-					cpus[cpu].thresh);
-				cpus[cpu].thresh_cleared = false;
+				&cpus[cpu].threshold[HOTPLUG_THRESHOLD_HIGH]);
+
+				cpus[cpu].hotplug_thresh_clear = false;
 			}
 			if (cpus[cpu].offline || cpus[cpu].user_offline)
 				mask |= BIT(cpu);
@@ -816,6 +940,63 @@
 }
 #endif
 
+static int do_ocr(void)
+{
+	struct tsens_device tsens_dev;
+	long temp = 0;
+	int ret = 0;
+	int i = 0, j = 0;
+	int auto_cnt = 0;
+
+	if (!ocr_enabled)
+		return ret;
+
+	mutex_lock(&ocr_mutex);
+	for (i = 0; i < max_tsens_num; i++) {
+		tsens_dev.sensor_num = tsens_id_map[i];
+		ret = tsens_get_temp(&tsens_dev, &temp);
+		if (ret) {
+			pr_debug("%s: Unable to read TSENS sensor %d\n",
+					__func__, tsens_dev.sensor_num);
+			auto_cnt++;
+			continue;
+		}
+
+		if (temp > msm_thermal_info.ocr_temp_degC) {
+			if (ocr_rails[0].init != OPTIMUM_CURRENT_NR)
+				for (j = 0; j < ocr_rail_cnt; j++)
+					ocr_rails[j].init = OPTIMUM_CURRENT_NR;
+			ret = ocr_set_mode_all(OPTIMUM_CURRENT_MAX);
+			if (ret)
+				pr_err("Error setting max optimum current\n");
+			goto do_ocr_exit;
+		} else if (temp <= (msm_thermal_info.ocr_temp_degC -
+			msm_thermal_info.ocr_temp_hyst_degC))
+			auto_cnt++;
+	}
+
+	if (auto_cnt == max_tsens_num ||
+		ocr_rails[0].init != OPTIMUM_CURRENT_NR) {
+		/* 'init' not equal to OPTIMUM_CURRENT_NR means this is the
+		** first polling iteration after device probe. During first
+		** iteration, if temperature is less than the set point, clear
+		** the max current request made and reset the 'init'.
+		*/
+		if (ocr_rails[0].init != OPTIMUM_CURRENT_NR)
+			for (j = 0; j < ocr_rail_cnt; j++)
+				ocr_rails[j].init = OPTIMUM_CURRENT_NR;
+		ret = ocr_set_mode_all(OPTIMUM_CURRENT_MIN);
+		if (ret) {
+			pr_err("Error setting min optimum current\n");
+			goto do_ocr_exit;
+		}
+	}
+
+do_ocr_exit:
+	mutex_unlock(&ocr_mutex);
+	return ret;
+}
+
 static int do_vdd_restriction(void)
 {
 	struct tsens_device tsens_dev;
@@ -915,14 +1096,14 @@
 
 static void __ref do_freq_control(long temp)
 {
-	int cpu = 0;
-	uint32_t max_freq = limited_max_freq;
+	uint32_t cpu = 0;
+	uint32_t max_freq = cpus[cpu].limited_max_freq;
 
 	if (temp >= msm_thermal_info.limit_temp_degC) {
 		if (limit_idx == limit_idx_low)
 			return;
 
-		limit_idx -= msm_thermal_info.freq_step;
+		limit_idx -= msm_thermal_info.bootup_freq_step;
 		if (limit_idx < limit_idx_low)
 			limit_idx = limit_idx_low;
 		max_freq = table[limit_idx].frequency;
@@ -931,7 +1112,7 @@
 		if (limit_idx == limit_idx_high)
 			return;
 
-		limit_idx += msm_thermal_info.freq_step;
+		limit_idx += msm_thermal_info.bootup_freq_step;
 		if (limit_idx >= limit_idx_high) {
 			limit_idx = limit_idx_high;
 			max_freq = UINT_MAX;
@@ -939,16 +1120,18 @@
 			max_freq = table[limit_idx].frequency;
 	}
 
-	if (max_freq == limited_max_freq)
+	if (max_freq == cpus[cpu].limited_max_freq)
 		return;
 
-	limited_max_freq = max_freq;
 	/* Update new limits */
+	get_online_cpus();
 	for_each_possible_cpu(cpu) {
-		if (!(msm_thermal_info.freq_control_mask & BIT(cpu)))
+		if (!(msm_thermal_info.bootup_freq_control_mask & BIT(cpu)))
 			continue;
-		update_cpu_max_freq(cpu, max_freq);
+		cpus[cpu].limited_max_freq = max_freq;
+		update_cpu_freq(cpu);
 	}
+	put_online_cpus();
 }
 
 static void __ref check_temp(struct work_struct *work)
@@ -977,6 +1160,7 @@
 	do_core_control(temp);
 	do_vdd_restriction();
 	do_psm();
+	do_ocr();
 	do_freq_control(temp);
 
 reschedule:
@@ -988,7 +1172,7 @@
 static int __ref msm_thermal_cpu_callback(struct notifier_block *nfb,
 		unsigned long action, void *hcpu)
 {
-	unsigned int cpu = (unsigned long)hcpu;
+	uint32_t cpu = (uint32_t)hcpu;
 
 	if (action == CPU_UP_PREPARE || action == CPU_UP_PREPARE_FROZEN) {
 		if (core_control_enabled &&
@@ -1064,7 +1248,7 @@
 		break;
 	}
 	if (hotplug_task) {
-		cpu_node->thresh_cleared = true;
+		cpu_node->hotplug_thresh_clear = true;
 		complete(&hotplug_notify_complete);
 	} else {
 		pr_err("%s: Hotplug task is not initialized\n", KBUILD_MODNAME);
@@ -1076,7 +1260,7 @@
 {
 	struct tsens_device tsens_dev;
 	long temp = 0;
-	int cpu = 0;
+	uint32_t cpu = 0;
 
 	if (!hotplug_enabled)
 		return 0;
@@ -1113,7 +1297,8 @@
 
 static void hotplug_init(void)
 {
-	int cpu = 0;
+	uint32_t cpu = 0;
+	struct sensor_threshold *hi_thresh = NULL, *low_thresh = NULL;
 
 	if (hotplug_task)
 		return;
@@ -1122,23 +1307,22 @@
 		goto init_kthread;
 
 	for_each_possible_cpu(cpu) {
-		cpus[cpu].cpu = (uint32_t)cpu;
-		cpus[cpu].thresh_cleared = false;
 		cpus[cpu].sensor_id =
 			sensor_get_id((char *)cpus[cpu].sensor_type);
 		if (!(msm_thermal_info.core_control_mask & BIT(cpus[cpu].cpu)))
 			continue;
-		cpus[cpu].thresh[0].temp = msm_thermal_info.hotplug_temp_degC;
-		cpus[cpu].thresh[0].trip = THERMAL_TRIP_CONFIGURABLE_HI;
-		cpus[cpu].thresh[0].notify = hotplug_notify;
-		cpus[cpu].thresh[0].data = (void *)&cpus[cpu];
 
-		cpus[cpu].thresh[1].temp = msm_thermal_info.hotplug_temp_degC -
+		hi_thresh = &cpus[cpu].threshold[HOTPLUG_THRESHOLD_HIGH];
+		low_thresh = &cpus[cpu].threshold[HOTPLUG_THRESHOLD_LOW];
+		hi_thresh->temp = msm_thermal_info.hotplug_temp_degC;
+		hi_thresh->trip = THERMAL_TRIP_CONFIGURABLE_HI;
+		low_thresh->temp = msm_thermal_info.hotplug_temp_degC -
 				msm_thermal_info.hotplug_temp_hysteresis_degC;
-		cpus[cpu].thresh[1].trip = THERMAL_TRIP_CONFIGURABLE_LOW;
-		cpus[cpu].thresh[1].notify = hotplug_notify;
-		cpus[cpu].thresh[1].data = (void *)&cpus[cpu];
-		set_threshold(cpus[cpu].sensor_id, cpus[cpu].thresh);
+		low_thresh->trip = THERMAL_TRIP_CONFIGURABLE_LOW;
+		hi_thresh->notify = low_thresh->notify = hotplug_notify;
+		hi_thresh->data = low_thresh->data = (void *)&cpus[cpu];
+
+		set_threshold(cpus[cpu].sensor_id, hi_thresh);
 	}
 init_kthread:
 	init_completion(&hotplug_notify_complete);
@@ -1156,6 +1340,167 @@
 		kthread_stop(hotplug_task);
 }
 
+static __ref int do_freq_mitigation(void *data)
+{
+	int ret = 0;
+	uint32_t cpu = 0, max_freq_req = 0, min_freq_req = 0;
+
+	while (!kthread_should_stop()) {
+		wait_for_completion(&freq_mitigation_complete);
+		INIT_COMPLETION(freq_mitigation_complete);
+
+		get_online_cpus();
+		for_each_possible_cpu(cpu) {
+			max_freq_req = (cpus[cpu].max_freq) ?
+					msm_thermal_info.freq_limit :
+					UINT_MAX;
+			max_freq_req = min(max_freq_req,
+					cpus[cpu].user_max_freq);
+
+			min_freq_req = max(min_freq_limit,
+					cpus[cpu].user_min_freq);
+
+			if ((max_freq_req == cpus[cpu].limited_max_freq)
+				&& (min_freq_req ==
+				cpus[cpu].limited_min_freq))
+				goto reset_threshold;
+
+			cpus[cpu].limited_max_freq = max_freq_req;
+			cpus[cpu].limited_min_freq = min_freq_req;
+			update_cpu_freq(cpu);
+reset_threshold:
+			if (freq_mitigation_enabled &&
+				cpus[cpu].freq_thresh_clear) {
+				set_threshold(cpus[cpu].sensor_id,
+				&cpus[cpu].threshold[FREQ_THRESHOLD_HIGH]);
+
+				cpus[cpu].freq_thresh_clear = false;
+			}
+		}
+		put_online_cpus();
+	}
+	return ret;
+}
+
+static int freq_mitigation_notify(enum thermal_trip_type type,
+	int temp, void *data)
+{
+	struct cpu_info *cpu_node = (struct cpu_info *) data;
+
+	pr_debug("%s: %s reached temp threshold: %d\n", KBUILD_MODNAME,
+		cpu_node->sensor_type, temp);
+
+	if (!(msm_thermal_info.freq_mitig_control_mask &
+		BIT(cpu_node->cpu)))
+		return 0;
+
+	switch (type) {
+	case THERMAL_TRIP_CONFIGURABLE_HI:
+		if (!cpu_node->max_freq) {
+			pr_info("%s: Mitigating cpu %d frequency to %d\n",
+				KBUILD_MODNAME, cpu_node->cpu,
+				msm_thermal_info.freq_limit);
+
+			cpu_node->max_freq = true;
+		}
+		break;
+	case THERMAL_TRIP_CONFIGURABLE_LOW:
+		if (cpu_node->max_freq) {
+			pr_info("%s: Removing frequency mitigation for cpu%d\n",
+				KBUILD_MODNAME, cpu_node->cpu);
+
+			cpu_node->max_freq = false;
+		}
+		break;
+	default:
+		break;
+	}
+
+	if (freq_mitigation_task) {
+		cpu_node->freq_thresh_clear = true;
+		complete(&freq_mitigation_complete);
+	} else {
+		pr_err("%s: Frequency mitigation task is not initialized\n",
+			KBUILD_MODNAME);
+	}
+
+	return 0;
+}
+
+static void freq_mitigation_init(void)
+{
+	uint32_t cpu = 0;
+	struct sensor_threshold *hi_thresh = NULL, *low_thresh = NULL;
+
+	if (freq_mitigation_task)
+		return;
+	if (!freq_mitigation_enabled)
+		goto init_freq_thread;
+
+	for_each_possible_cpu(cpu) {
+		if (!(msm_thermal_info.freq_mitig_control_mask & BIT(cpu)))
+			continue;
+		hi_thresh = &cpus[cpu].threshold[FREQ_THRESHOLD_HIGH];
+		low_thresh = &cpus[cpu].threshold[FREQ_THRESHOLD_LOW];
+
+		hi_thresh->temp = msm_thermal_info.freq_mitig_temp_degc;
+		hi_thresh->trip = THERMAL_TRIP_CONFIGURABLE_HI;
+		low_thresh->temp = msm_thermal_info.freq_mitig_temp_degc -
+			msm_thermal_info.freq_mitig_temp_hysteresis_degc;
+		low_thresh->trip = THERMAL_TRIP_CONFIGURABLE_LOW;
+		hi_thresh->notify = low_thresh->notify =
+			freq_mitigation_notify;
+		hi_thresh->data = low_thresh->data = (void *)&cpus[cpu];
+
+		set_threshold(cpus[cpu].sensor_id, hi_thresh);
+	}
+init_freq_thread:
+	init_completion(&freq_mitigation_complete);
+	freq_mitigation_task = kthread_run(do_freq_mitigation, NULL,
+		"msm_thermal:freq_mitig");
+
+	if (IS_ERR(freq_mitigation_task)) {
+		pr_err("%s: Failed to create frequency mitigation thread\n",
+				KBUILD_MODNAME);
+		return;
+	}
+}
+
+int msm_thermal_set_frequency(uint32_t cpu, uint32_t freq, bool is_max)
+{
+	int ret = 0;
+
+	if (cpu >= num_possible_cpus()) {
+		pr_err("%s: Invalid input\n", KBUILD_MODNAME);
+		ret = -EINVAL;
+		goto set_freq_exit;
+	}
+
+	if (is_max) {
+		if (cpus[cpu].user_max_freq == freq)
+			goto set_freq_exit;
+
+		cpus[cpu].user_max_freq = freq;
+	} else {
+		if (cpus[cpu].user_min_freq == freq)
+			goto set_freq_exit;
+
+		cpus[cpu].user_min_freq = freq;
+	}
+
+	if (freq_mitigation_task) {
+		complete(&freq_mitigation_complete);
+	} else {
+		pr_err("%s: Frequency mitigation task is not initialized\n",
+			KBUILD_MODNAME);
+		ret = -ESRCH;
+		goto set_freq_exit;
+	}
+
+set_freq_exit:
+	return ret;
+}
+
 /*
  * We will reset the cpu frequencies limits here. The core online/offline
  * status will be carried over to the process stopping the msm_thermal, as
@@ -1163,21 +1508,20 @@
  */
 static void __ref disable_msm_thermal(void)
 {
-	int cpu = 0;
+	uint32_t cpu = 0;
 
 	/* make sure check_temp is no longer running */
 	cancel_delayed_work(&check_temp_work);
 	flush_scheduled_work();
 
-	if (limited_max_freq == UINT_MAX)
-		return;
-
-	limited_max_freq = UINT_MAX;
 	get_online_cpus();
-	for_each_online_cpu(cpu) {
-		if (cpufreq_update_policy(cpu))
-			pr_info("%s: Unable to update policy for cpu:%d\n",
-				KBUILD_MODNAME, cpu);
+	for_each_possible_cpu(cpu) {
+		if (cpus[cpu].limited_max_freq == UINT_MAX &&
+			cpus[cpu].limited_min_freq == 0)
+			continue;
+		cpus[cpu].limited_max_freq = UINT_MAX;
+		cpus[cpu].limited_min_freq = 0;
+		update_cpu_freq(cpu);
 	}
 	put_online_cpus();
 }
@@ -1190,6 +1534,7 @@
 	if (!enabled) {
 		disable_msm_thermal();
 		hotplug_init();
+		freq_mitigation_init();
 	} else
 		pr_info("%s: no action for enabled = %d\n",
 			KBUILD_MODNAME, enabled);
@@ -1257,7 +1602,7 @@
 {
 	int ret = 0;
 	uint32_t val = 0;
-	int cpu;
+	uint32_t cpu;
 
 	mutex_lock(&core_control_mutex);
 	ret = kstrtouint(buf, 10, &val);
@@ -1422,6 +1767,7 @@
 int __devinit msm_thermal_init(struct msm_thermal_data *pdata)
 {
 	int ret = 0;
+	uint32_t cpu;
 
 	BUG_ON(!pdata);
 	tsens_get_max_sensor_num(&max_tsens_num);
@@ -1433,13 +1779,15 @@
 		return -EINVAL;
 
 	enabled = 1;
-
+	for_each_possible_cpu(cpu) {
+		cpus[cpu].limited_max_freq = UINT_MAX;
+		cpus[cpu].limited_min_freq = 0;
+	}
 	ret = cpufreq_register_notifier(&msm_thermal_cpufreq_notifier,
 			CPUFREQ_POLICY_NOTIFIER);
 	if (ret)
 		pr_err("%s: cannot register cpufreq notifier\n",
 			KBUILD_MODNAME);
-
 	INIT_DELAYED_WORK(&check_temp_work, check_temp);
 	schedule_delayed_work(&check_temp_work, 0);
 
@@ -1449,6 +1797,42 @@
 	return ret;
 }
 
+static int ocr_reg_init(struct platform_device *pdev)
+{
+	int ret = 0;
+	int i, j;
+
+	for (i = 0; i < ocr_rail_cnt; i++) {
+		/* Check if vdd_restriction has already initialized any
+		 * regualtor handle. If so use the same handle.*/
+		for (j = 0; j < rails_cnt; j++) {
+			if (!strcmp(ocr_rails[i].name, rails[j].name)) {
+				if (rails[j].reg == NULL)
+					break;
+				ocr_rails[i].phase_reg = rails[j].reg;
+				goto reg_init;
+			}
+
+		}
+		ocr_rails[i].phase_reg = devm_regulator_get(&pdev->dev,
+					ocr_rails[i].name);
+		if (IS_ERR_OR_NULL(ocr_rails[i].phase_reg)) {
+			ret = PTR_ERR(ocr_rails[i].phase_reg);
+			if (ret != -EPROBE_DEFER) {
+				pr_err("%s, could not get regulator: %s\n",
+					__func__, ocr_rails[i].name);
+				ocr_rails[i].phase_reg = NULL;
+				ocr_rails[i].mode = 0;
+				ocr_rails[i].init = 0;
+			}
+			return ret;
+		}
+reg_init:
+		ocr_rails[i].mode = OPTIMUM_CURRENT_MIN;
+	}
+	return ret;
+}
+
 static int vdd_restriction_reg_init(struct platform_device *pdev)
 {
 	int ret = 0;
@@ -1618,6 +2002,80 @@
 	return rc;
 }
 
+static int msm_thermal_add_ocr_nodes(void)
+{
+	struct kobject *module_kobj = NULL;
+	struct kobject *ocr_kobj = NULL;
+	struct kobject *ocr_reg_kobj[MAX_RAILS] = {0};
+	int rc = 0;
+	int i = 0;
+
+	if (!ocr_probed) {
+		ocr_nodes_called = true;
+		return rc;
+	}
+
+	if (ocr_probed && ocr_rail_cnt == 0)
+		return rc;
+
+	module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
+	if (!module_kobj) {
+		pr_err("%s: cannot find kobject for module %s\n",
+			__func__, KBUILD_MODNAME);
+		rc = -ENOENT;
+		goto ocr_node_exit;
+	}
+
+	ocr_kobj = kobject_create_and_add("opt_curr_req", module_kobj);
+	if (!ocr_kobj) {
+		pr_err("%s: cannot create ocr kobject\n", KBUILD_MODNAME);
+		rc = -ENOMEM;
+		goto ocr_node_exit;
+	}
+
+	for (i = 0; i < ocr_rail_cnt; i++) {
+		ocr_reg_kobj[i] = kobject_create_and_add(ocr_rails[i].name,
+					ocr_kobj);
+		if (!ocr_reg_kobj[i]) {
+			pr_err("%s: cannot create for kobject for %s\n",
+					KBUILD_MODNAME, ocr_rails[i].name);
+			rc = -ENOMEM;
+			goto ocr_node_exit;
+		}
+		ocr_rails[i].attr_gp.attrs = kzalloc( \
+				sizeof(struct attribute *) * 2, GFP_KERNEL);
+		if (!ocr_rails[i].attr_gp.attrs) {
+			rc = -ENOMEM;
+			goto ocr_node_exit;
+		}
+
+		OCR_RW_ATTRIB(ocr_rails[i], ocr_rails[i].mode_attr, 0, mode);
+		ocr_rails[i].attr_gp.attrs[1] = NULL;
+
+		rc = sysfs_create_group(ocr_reg_kobj[i], &ocr_rails[i].attr_gp);
+		if (rc) {
+			pr_err("%s: cannot create attribute group for %s\n",
+				KBUILD_MODNAME, ocr_rails[i].name);
+			goto ocr_node_exit;
+		}
+	}
+
+ocr_node_exit:
+	if (rc) {
+		for (i = 0; i < ocr_rail_cnt; i++) {
+			if (ocr_reg_kobj[i])
+				kobject_del(ocr_reg_kobj[i]);
+			if (ocr_rails[i].attr_gp.attrs) {
+				kfree(ocr_rails[i].attr_gp.attrs);
+				ocr_rails[i].attr_gp.attrs = NULL;
+			}
+		}
+		if (ocr_kobj)
+			kobject_del(ocr_kobj);
+	}
+	return rc;
+}
+
 static int msm_thermal_add_psm_nodes(void)
 {
 	struct kobject *module_kobj = NULL;
@@ -1790,6 +2248,83 @@
 	return ret;
 }
 
+static int probe_ocr(struct device_node *node, struct msm_thermal_data *data,
+		struct platform_device *pdev)
+{
+	int ret = 0;
+	int j = 0;
+	char *key = NULL;
+
+	if (ocr_probed) {
+		pr_info("%s: Nodes already probed\n",
+			__func__);
+		goto read_ocr_exit;
+	}
+	ocr_rails = NULL;
+
+	key = "qti,pmic-opt-curr-temp";
+	ret = of_property_read_u32(node, key, &data->ocr_temp_degC);
+	if (ret)
+		goto read_ocr_fail;
+
+	key = "qti,pmic-opt-curr-temp-hysteresis";
+	ret = of_property_read_u32(node, key, &data->ocr_temp_hyst_degC);
+	if (ret)
+		goto read_ocr_fail;
+
+	key = "qti,pmic-opt-curr-regs";
+	ocr_rail_cnt = of_property_count_strings(node, key);
+	ocr_rails = kzalloc(sizeof(struct psm_rail) * ocr_rail_cnt,
+			GFP_KERNEL);
+	if (!ocr_rails) {
+		pr_err("%s: Fail to allocate memory for ocr rails\n", __func__);
+		ocr_rail_cnt = 0;
+		return -ENOMEM;
+	}
+
+	for (j = 0; j < ocr_rail_cnt; j++) {
+		ret = of_property_read_string_index(node, key, j,
+				&ocr_rails[j].name);
+		if (ret)
+			goto read_ocr_fail;
+		ocr_rails[j].phase_reg = NULL;
+		ocr_rails[j].init = OPTIMUM_CURRENT_MAX;
+	}
+
+	if (ocr_rail_cnt) {
+		ret = ocr_reg_init(pdev);
+		if (ret) {
+			pr_info("%s:Failed to get regulators. KTM continues.\n",
+					__func__);
+			goto read_ocr_fail;
+		}
+		ocr_enabled = true;
+		ocr_nodes_called = false;
+		/*
+		 * Vote for max optimum current by default until we have made
+		 * our first temp reading
+		 */
+		if (ocr_set_mode_all(OPTIMUM_CURRENT_MAX))
+			pr_err("Set max optimum current failed\n");
+	}
+
+read_ocr_fail:
+	ocr_probed = true;
+	if (ret) {
+		dev_info(&pdev->dev,
+			"%s:Failed reading node=%s, key=%s. KTM continues\n",
+			__func__, node->full_name, key);
+		if (ocr_rails)
+			kfree(ocr_rails);
+		ocr_rails = NULL;
+		ocr_rail_cnt = 0;
+	}
+	if (ret == -EPROBE_DEFER)
+		ocr_probed = false;
+read_ocr_exit:
+	return ret;
+}
+
 static int probe_psm(struct device_node *node, struct msm_thermal_data *data,
 		struct platform_device *pdev)
 {
@@ -1854,9 +2389,9 @@
 		struct platform_device *pdev)
 {
 	char *key = NULL;
-	int cpu_cnt = 0;
+	uint32_t cpu_cnt = 0;
 	int ret = 0;
-	int cpu = 0;
+	uint32_t cpu = 0;
 
 	if (num_possible_cpus() > 1) {
 		core_control_enabled = 1;
@@ -1901,6 +2436,7 @@
 		cpus[cpu].cpu = cpu;
 		cpus[cpu].offline = 0;
 		cpus[cpu].user_offline = 0;
+		cpus[cpu].hotplug_thresh_clear = false;
 		ret = of_property_read_string_index(node, key, cpu,
 				&cpus[cpu].sensor_type);
 		if (ret)
@@ -1928,6 +2464,55 @@
 	return ret;
 }
 
+static int probe_freq_mitigation(struct device_node *node,
+		struct msm_thermal_data *data,
+		struct platform_device *pdev)
+{
+	char *key = NULL;
+	int ret = 0;
+	uint32_t cpu;
+
+	key = "qcom,freq-mitigation-temp";
+	ret = of_property_read_u32(node, key, &data->freq_mitig_temp_degc);
+	if (ret)
+		goto PROBE_FREQ_EXIT;
+
+	key = "qcom,freq-mitigation-temp-hysteresis";
+	ret = of_property_read_u32(node, key,
+		&data->freq_mitig_temp_hysteresis_degc);
+	if (ret)
+		goto PROBE_FREQ_EXIT;
+
+	key = "qcom,freq-mitigation-value";
+	ret = of_property_read_u32(node, key, &data->freq_limit);
+	if (ret)
+		goto PROBE_FREQ_EXIT;
+
+	key = "qcom,freq-mitigation-control-mask";
+	ret = of_property_read_u32(node, key, &data->freq_mitig_control_mask);
+	if (ret)
+		goto PROBE_FREQ_EXIT;
+
+	freq_mitigation_enabled = 1;
+	for_each_possible_cpu(cpu) {
+		cpus[cpu].max_freq = false;
+		cpus[cpu].user_max_freq = UINT_MAX;
+		cpus[cpu].user_min_freq = 0;
+		cpus[cpu].limited_max_freq = UINT_MAX;
+		cpus[cpu].limited_min_freq = 0;
+		cpus[cpu].freq_thresh_clear = false;
+	}
+
+PROBE_FREQ_EXIT:
+	if (ret) {
+		dev_info(&pdev->dev,
+			"%s:Failed reading node=%s, key=%s. KTM continues\n",
+			__func__, node->full_name, key);
+		freq_mitigation_enabled = 0;
+	}
+	return ret;
+}
+
 static int __devinit msm_thermal_dev_probe(struct platform_device *pdev)
 {
 	int ret = 0;
@@ -1958,18 +2543,23 @@
 		goto fail;
 
 	key = "qcom,freq-step";
-	ret = of_property_read_u32(node, key, &data.freq_step);
+	ret = of_property_read_u32(node, key, &data.bootup_freq_step);
 	if (ret)
 		goto fail;
 
 	key = "qcom,freq-control-mask";
-	ret = of_property_read_u32(node, key, &data.freq_control_mask);
+	ret = of_property_read_u32(node, key, &data.bootup_freq_control_mask);
 
 	ret = probe_cc(node, &data, pdev);
+
+	ret = probe_freq_mitigation(node, &data, pdev);
 	/*
 	 * Probe optional properties below. Call probe_psm before
 	 * probe_vdd_rstr because rpm_regulator_get has to be called
 	 * before devm_regulator_get
+	 * probe_ocr should be called after probe_vdd_rstr to reuse the
+	 * regualtor handle. calling devm_regulator_get more than once
+	 * will fail.
 	 */
 	ret = probe_psm(node, &data, pdev);
 	if (ret == -EPROBE_DEFER)
@@ -1977,6 +2567,9 @@
 	ret = probe_vdd_rstr(node, &data, pdev);
 	if (ret == -EPROBE_DEFER)
 		goto fail;
+	ret = probe_ocr(node, &data, pdev);
+	if (ret == -EPROBE_DEFER)
+		goto fail;
 
 	/*
 	 * In case sysfs add nodes get called before probe function.
@@ -1990,6 +2583,11 @@
 		msm_thermal_add_vdd_rstr_nodes();
 		vdd_rstr_nodes_called = false;
 	}
+	if (ocr_nodes_called) {
+		msm_thermal_add_ocr_nodes();
+		ocr_nodes_called = false;
+	}
+	msm_thermal_ioctl_init();
 	ret = msm_thermal_init(&data);
 
 	return ret;
@@ -2001,6 +2599,11 @@
 	return ret;
 }
 
+static int msm_thermal_dev_exit(struct platform_device *inp_dev)
+{
+	msm_thermal_ioctl_cleanup();
+	return 0;
+}
 
 static struct of_device_id msm_thermal_match_table[] = {
 	{.compatible = "qcom,msm-thermal"},
@@ -2014,6 +2617,7 @@
 		.owner = THIS_MODULE,
 		.of_match_table = msm_thermal_match_table,
 	},
+	.remove = msm_thermal_dev_exit,
 };
 
 int __init msm_thermal_device_init(void)
@@ -2027,6 +2631,7 @@
 		msm_thermal_add_cc_nodes();
 	msm_thermal_add_psm_nodes();
 	msm_thermal_add_vdd_rstr_nodes();
+	msm_thermal_add_ocr_nodes();
 	alarm_init(&thermal_rtc, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
 			thermal_rtc_callback);
 	INIT_WORK(&timer_work, timer_work_fn);
diff --git a/drivers/thermal/qpnp-adc-tm.c b/drivers/thermal/qpnp-adc-tm.c
index cf1801b..7d8899e 100644
--- a/drivers/thermal/qpnp-adc-tm.c
+++ b/drivers/thermal/qpnp-adc-tm.c
@@ -1339,7 +1339,7 @@
 {
 	u8 status_low = 0, status_high = 0, qpnp_adc_tm_meas_en = 0;
 	u8 adc_tm_low_enable = 0, adc_tm_high_enable = 0;
-	u8 sensor_mask = 0;
+	u8 sensor_mask = 0, adc_tm_low_thr_set = 0, adc_tm_high_thr_set = 0;
 	int rc = 0, sensor_notify_num = 0, i = 0, sensor_num = 0;
 	uint32_t btm_chan_num = 0;
 	struct qpnp_adc_thr_client_info *client_info = NULL;
@@ -1368,6 +1368,20 @@
 		goto fail;
 	}
 
+	rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_LOW_THR_INT_EN,
+						&adc_tm_low_thr_set);
+	if (rc) {
+		pr_err("adc-tm-tm read low thr failed with %d\n", rc);
+		goto fail;
+	}
+
+	rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_HIGH_THR_INT_EN,
+						&adc_tm_high_thr_set);
+	if (rc) {
+		pr_err("adc-tm-tm read high thr failed with %d\n", rc);
+		goto fail;
+	}
+
 	/* Check which interrupt threshold is lower and measure against the
 	 * enabled channel */
 	rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_MULTI_MEAS_EN,
@@ -1378,7 +1392,9 @@
 	}
 
 	adc_tm_low_enable = qpnp_adc_tm_meas_en & status_low;
+	adc_tm_low_enable &= adc_tm_low_thr_set;
 	adc_tm_high_enable = qpnp_adc_tm_meas_en & status_high;
+	adc_tm_high_enable &= adc_tm_high_thr_set;
 
 	if (adc_tm_high_enable) {
 		sensor_notify_num = adc_tm_high_enable;
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 078929b..ecfacc0 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -67,14 +67,65 @@
 #include <mach/sps.h>
 #include <mach/msm_serial_hs.h>
 #include <mach/msm_bus.h>
-
+#include <mach/msm_ipc_logging.h>
 #include "msm_serial_hs_hwreg.h"
 #define UART_SPS_CONS_PERIPHERAL 0
 #define UART_SPS_PROD_PERIPHERAL 1
 
-static int hs_serial_debug_mask = 1;
+static void *ipc_msm_hs_log_ctxt;
+#define IPC_MSM_HS_LOG_PAGES 5
+
+/* If the debug_mask gets set to FATAL_LEV,
+ * a fatal error has happened and further IPC logging
+ * is disabled so that this problem can be detected
+ */
+enum {
+	FATAL_LEV = 0U,
+	ERR_LEV = 1U,
+	WARN_LEV = 2U,
+	INFO_LEV = 3U,
+	DBG_LEV = 4U,
+};
+
+/* Default IPC log level INFO */
+static int hs_serial_debug_mask = INFO_LEV;
 module_param_named(debug_mask, hs_serial_debug_mask,
 		   int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+#define MSM_HS_DBG(x...) do { \
+	if (hs_serial_debug_mask >= DBG_LEV) { \
+		pr_debug(x); \
+		if (ipc_msm_hs_log_ctxt) \
+			ipc_log_string(ipc_msm_hs_log_ctxt, x); \
+	} \
+} while (0)
+
+#define MSM_HS_INFO(x...) do { \
+	if (hs_serial_debug_mask >= INFO_LEV) {\
+		pr_info(x); \
+		if (ipc_msm_hs_log_ctxt) \
+			ipc_log_string(ipc_msm_hs_log_ctxt, x); \
+	} \
+} while (0)
+
+/* warnings and errors show up on console always */
+#define MSM_HS_WARN(x...) do { \
+	pr_warn(x); \
+	if (ipc_msm_hs_log_ctxt && hs_serial_debug_mask >= WARN_LEV) \
+		ipc_log_string(ipc_msm_hs_log_ctxt, x); \
+} while (0)
+
+/* ERROR condition in the driver sets the hs_serial_debug_mask
+ * to ERR_FATAL level, so that this message can be seen
+ * in IPC logging. Further errors continue to log on the console
+ */
+#define MSM_HS_ERR(x...) do { \
+	pr_err(x); \
+	if (ipc_msm_hs_log_ctxt && hs_serial_debug_mask >= ERR_LEV) { \
+		ipc_log_string(ipc_msm_hs_log_ctxt, x); \
+		hs_serial_debug_mask = FATAL_LEV; \
+	} \
+} while (0)
 /*
  * There are 3 different kind of UART Core available on MSM.
  * High Speed UART (i.e. Legacy HSUART), GSBI based HSUART
@@ -316,19 +367,19 @@
 
 	switch (cmd) {
 	case MSM_ENABLE_UART_CLOCK: {
-		pr_debug("%s():ENABLE UART CLOCK: cmd=%d\n", __func__, cmd);
+		MSM_HS_DBG("%s():ENABLE UART CLOCK: cmd=%d\n", __func__, cmd);
 		msm_hs_request_clock_on(&msm_uport->uport);
 		break;
 	}
 	case MSM_DISABLE_UART_CLOCK: {
-		pr_debug("%s():DISABLE UART CLOCK: cmd=%d\n", __func__, cmd);
+		MSM_HS_DBG("%s():DISABLE UART CLOCK: cmd=%d\n", __func__, cmd);
 		msm_hs_request_clock_off(&msm_uport->uport);
 		break;
 	}
 	case MSM_GET_UART_CLOCK_STATUS: {
 		/* Return value 0 - UART CLOCK is OFF
 		 * Return value 1 - UART CLOCK is ON */
-		pr_debug("%s():GET UART CLOCK STATUS: cmd=%d\n", __func__, cmd);
+		MSM_HS_DBG("%s():GET UART CLOCK STATUS: cmd=%d\n", __func__, cmd);
 		spin_lock_irqsave(&msm_uport->uport.lock, flags);
 		clk_state = msm_uport->clk_state;
 		spin_unlock_irqrestore(&msm_uport->uport.lock, flags);
@@ -338,7 +389,7 @@
 		break;
 	}
 	default: {
-		pr_debug("%s():Unknown cmd specified: cmd=%d\n", __func__, cmd);
+		MSM_HS_DBG("%s():Unknown cmd specified: cmd=%d\n", __func__, cmd);
 		ret = -ENOIOCTLCMD;
 		break;
 	}
@@ -470,11 +521,11 @@
 	int ret;
 
 	if (is_blsp_uart(msm_uport) && msm_uport->bus_perf_client) {
-		pr_debug("Bus voting:%d\n", vote);
+		MSM_HS_DBG("Bus voting:%d\n", vote);
 		ret = msm_bus_scale_client_update_request(
 				msm_uport->bus_perf_client, vote);
 		if (ret)
-			pr_err("%s(): Failed for Bus voting: %d\n",
+			MSM_HS_ERR("%s(): Failed for Bus voting: %d\n",
 							__func__, vote);
 	}
 }
@@ -500,6 +551,37 @@
 	writel_relaxed(value, uport->membase + offset);
 }
 
+static void hex_dump_ipc(char *prefix, char *string, int size)
+{
+	char linebuf[512];
+
+	hex_dump_to_buffer(string, size, 16, 1, linebuf, sizeof(linebuf), 1);
+	MSM_HS_DBG("%s : %s", prefix, linebuf);
+}
+
+/*
+ * This API read and provides UART Core registers information.
+*/
+static void dump_uart_hs_registers(struct msm_hs_port *msm_uport)
+{
+	msm_hs_clock_vote(msm_uport);
+	MSM_HS_DBG("============= UART Registers ================\n");
+	MSM_HS_DBG("UART_DM_MR1:%x\n", msm_hs_read(&(msm_uport->uport),
+		UART_DM_MR1));
+	MSM_HS_DBG("UART_DM_MR2:%x\n", msm_hs_read(&(msm_uport->uport),
+		UART_DM_MR2));
+	MSM_HS_DBG("UART_DM_IPR:%x\n", msm_hs_read(&(msm_uport->uport),
+		UART_DM_IPR));
+	MSM_HS_DBG("UART_DM_RFWR:%x\n", msm_hs_read(&(msm_uport->uport),
+		UART_DM_RFWR));
+	MSM_HS_DBG("UART_DM_SR:%x\n", msm_hs_read(&(msm_uport->uport),
+		UART_DM_SR));
+	MSM_HS_DBG("UART_DM_IMR: %x\n", msm_hs_read(&(msm_uport->uport),
+		UART_DM_IMR));
+	MSM_HS_DBG("=============================================\n");
+	msm_hs_clock_unvote(msm_uport);
+}
+
 static void msm_hs_release_port(struct uart_port *port)
 {
 	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(port);
@@ -626,7 +708,7 @@
 						&loopback_enable_fops);
 
 	if (IS_ERR_OR_NULL(msm_uport->loopback_dir))
-		pr_err("%s(): Cannot create loopback.%d debug entry",
+		MSM_HS_ERR("%s(): Cannot create loopback.%d debug entry",
 							__func__, id);
 }
 
@@ -637,7 +719,7 @@
 	struct device *dev;
 
 	if (pdev->id < 0 || pdev->id >= UARTDM_NR) {
-		printk(KERN_ERR "Invalid plaform device ID = %d\n", pdev->id);
+		MSM_HS_ERR(KERN_ERR "Invalid plaform device ID = %d\n", pdev->id);
 		return -EINVAL;
 	}
 
@@ -691,13 +773,13 @@
 	/* Set up the MREG/NREG/DREG/MNDREG */
 	ret = clk_set_rate(msm_uport->clk, uport->uartclk);
 	if (ret) {
-		printk(KERN_WARNING "Error setting clock rate on UART\n");
+		MSM_HS_WARN("Error setting clock rate on UART\n");
 		return ret;
 	}
 
 	ret = msm_hs_clock_vote(msm_uport);
 	if (ret) {
-		printk(KERN_ERR "Error could not turn on UART clk\n");
+		MSM_HS_ERR("Error could not turn on UART clk\n");
 		return ret;
 	}
 
@@ -728,14 +810,14 @@
 	/* Establish connection between peripheral and memory endpoint */
 	ret = sps_connect(sps_pipe_handle, sps_config);
 	if (ret) {
-		pr_err("msm_serial_hs: sps_connect() failed for tx!!\n"
+		MSM_HS_ERR("msm_serial_hs: sps_connect() failed for tx!!\n"
 		"pipe_handle=0x%x ret=%d", (u32)sps_pipe_handle, ret);
 		return ret;
 	}
 	/* Register callback event for EOT (End of transfer) event. */
 	ret = sps_register_event(sps_pipe_handle, sps_event);
 	if (ret) {
-		pr_err("msm_serial_hs: sps_connect() failed for tx!!\n"
+		MSM_HS_ERR("msm_serial_hs: sps_connect() failed for tx!!\n"
 		"pipe_handle=0x%x ret=%d", (u32)sps_pipe_handle, ret);
 		goto reg_event_err;
 	}
@@ -769,14 +851,14 @@
 	/* Establish connection between peripheral and memory endpoint */
 	ret = sps_connect(sps_pipe_handle, sps_config);
 	if (ret) {
-		pr_err("msm_serial_hs: sps_connect() failed for rx!!\n"
+		MSM_HS_ERR("msm_serial_hs: sps_connect() failed for rx!!\n"
 		"pipe_handle=0x%x ret=%d", (u32)sps_pipe_handle, ret);
 		return ret;
 	}
 	/* Register callback event for DESC_DONE event. */
 	ret = sps_register_event(sps_pipe_handle, sps_event);
 	if (ret) {
-		pr_err("msm_serial_hs: sps_connect() failed for rx!!\n"
+		MSM_HS_ERR("msm_serial_hs: sps_connect() failed for rx!!\n"
 		"pipe_handle=0x%x ret=%d", (u32)sps_pipe_handle, ret);
 		goto reg_event_err;
 	}
@@ -909,7 +991,7 @@
 	}
 
 	if (clk_set_rate(msm_uport->clk, uport->uartclk)) {
-		printk(KERN_WARNING "Error setting clock rate on UART\n");
+		MSM_HS_WARN("Error setting clock rate on UART\n");
 		WARN_ON(1);
 	}
 
@@ -998,6 +1080,9 @@
 	mutex_lock(&msm_uport->clk_mutex);
 	msm_hs_write(uport, UART_DM_IMR, 0);
 
+	MSM_HS_DBG("Entering %s\n", __func__);
+	dump_uart_hs_registers(msm_uport);
+
 	/* Clear the Rx Ready Ctl bit - This ensures that
 	* flow control lines stop the other side from sending
 	* data while we change the parameters
@@ -1108,7 +1193,7 @@
 					RX_FLUSH_COMPLETE_TIMEOUT);
 			ret = sps_disconnect(sps_pipe_handle);
 			if (ret)
-				pr_err("%s(): sps_disconnect failed\n",
+				MSM_HS_ERR("%s(): sps_disconnect failed\n",
 							__func__);
 			msm_hs_spsconnect_rx(uport);
 			msm_serial_hs_rx_tlet((unsigned long) &rx->tlet);
@@ -1116,13 +1201,13 @@
 			msm_uport->rx_discard_flush_issued = true;
 			/* do discard flush */
 			msm_dmov_flush(msm_uport->dma_rx_channel, 0);
-			pr_debug("%s(): wainting for flush completion.\n",
+			MSM_HS_DBG("%s(): wainting for flush completion.\n",
 								__func__);
 			ret = wait_event_timeout(msm_uport->rx.wait,
 				msm_uport->rx_discard_flush_issued == false,
 				RX_FLUSH_COMPLETE_TIMEOUT);
 			if (!ret)
-				pr_err("%s(): Discard flush pending.\n",
+				MSM_HS_ERR("%s(): Discard flush pending.\n",
 								__func__);
 		}
 	}
@@ -1144,6 +1229,8 @@
 	msm_hs_write(uport, UART_DM_IMR, msm_uport->imr_reg);
 	mb();
 	mutex_unlock(&msm_uport->clk_mutex);
+	MSM_HS_DBG("Exit %s\n", __func__);
+	dump_uart_hs_registers(msm_uport);
 }
 
 /*
@@ -1157,7 +1244,7 @@
 	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
 
 	msm_hs_clock_vote(msm_uport);
-	data = msm_hs_read(uport, UARTDM_SR_ADDR);
+	data = msm_hs_read(uport, UART_DM_SR);
 	msm_hs_clock_unvote(msm_uport);
 
 	if (data & UARTDM_SR_TXEMT_BMSK)
@@ -1190,7 +1277,7 @@
 
 	ret = sps_disconnect(sps_pipe_handle);
 	if (ret)
-		pr_err("%s(): sps_disconnect failed\n", __func__);
+		MSM_HS_ERR("%s(): sps_disconnect failed\n", __func__);
 
 	wake_lock_timeout(&msm_uport->rx.wake_lock, HZ / 2);
 	msm_uport->rx.flush = FLUSH_SHUTDOWN;
@@ -1268,7 +1355,8 @@
 
 	if (tx_count > left)
 		tx_count = left;
-
+	MSM_HS_DBG("%s(): [UART_TX]<%d>\n", __func__, tx_count);
+	hex_dump_ipc("HSUART write: ", &tx_buf->buf[tx_buf->tail], tx_count);
 	src_addr = tx->dma_base + tx_buf->tail;
 	/* Mask the src_addr to align on a cache
 	 * and add those bytes to tx_count */
@@ -1316,7 +1404,10 @@
 			sizeof(u32), DMA_TO_DEVICE);
 
 		msm_dmov_enqueue_cmd(msm_uport->dma_tx_channel, &tx->xfer);
+
 	}
+	MSM_HS_DBG("%s:Enqueue Tx Cmd\n", __func__);
+	dump_uart_hs_registers(msm_uport);
 }
 
 /* Start to receive the next chunk of data */
@@ -1331,7 +1422,7 @@
 
 	msm_uport->rx.buffer_pending = 0;
 	if (buffer_pending && hs_serial_debug_mask)
-		printk(KERN_ERR "Error: rx started in buffer state = %x",
+		MSM_HS_ERR("Error: rx started in buffer state = %x",
 		       buffer_pending);
 
 	msm_hs_write(uport, UART_DM_CR, RESET_STALE_INT);
@@ -1383,6 +1474,8 @@
 		msm_dmov_enqueue_cmd(msm_uport->dma_rx_channel,
 				&msm_uport->rx.xfer);
 	}
+	MSM_HS_DBG("%s:Enqueue Rx Cmd\n", __func__);
+	dump_uart_hs_registers(msm_uport);
 }
 
 static void flip_insert_work(struct work_struct *work)
@@ -1397,7 +1490,7 @@
 	spin_lock_irqsave(&msm_uport->uport.lock, flags);
 	if (msm_uport->rx.buffer_pending == NONE_PENDING) {
 		if (hs_serial_debug_mask)
-			printk(KERN_ERR "Error: No buffer pending in %s",
+			MSM_HS_ERR("Error: No buffer pending in %s",
 			       __func__);
 		return;
 	}
@@ -1429,11 +1522,7 @@
 	else
 		if ((msm_uport->clk_state == MSM_HS_CLK_ON) &&
 		    (msm_uport->rx.flush <= FLUSH_IGNORE)) {
-			if (hs_serial_debug_mask)
-				printk(KERN_WARNING
-				       "msm_serial_hs: "
-				       "Pending buffers cleared. "
-				       "Restarting\n");
+		MSM_HS_WARN("Pending buffers cleared,restarting\n");
 			msm_hs_start_rx_locked(&msm_uport->uport);
 		}
 	spin_unlock_irqrestore(&msm_uport->uport.lock, flags);
@@ -1470,6 +1559,9 @@
 	if (!is_blsp_uart(msm_uport))
 		msm_hs_write(uport, UART_DM_CR, STALE_EVENT_DISABLE);
 
+	MSM_HS_DBG("In %s\n", __func__);
+	dump_uart_hs_registers(msm_uport);
+
 	/* overflow is not connect to data in a FIFO */
 	if (unlikely((status & UARTDM_SR_OVERRUN_BMSK) &&
 		     (uport->read_status_mask & CREAD))) {
@@ -1486,7 +1578,7 @@
 	if (unlikely(status & UARTDM_SR_PAR_FRAME_BMSK)) {
 		/* Can not tell difference between parity & frame error */
 		if (hs_serial_debug_mask)
-			printk(KERN_WARNING "msm_serial_hs: parity error\n");
+			MSM_HS_WARN("msm_serial_hs: parity error\n");
 		uport->icount.parity++;
 		error_f = 1;
 		if (!(uport->ignore_status_mask & IGNPAR)) {
@@ -1498,7 +1590,7 @@
 
 	if (unlikely(status & UARTDM_SR_RX_BREAK_BMSK)) {
 		if (hs_serial_debug_mask)
-			printk(KERN_WARNING "msm_serial_hs: Rx break\n");
+			MSM_HS_WARN("msm_serial_hs: Rx break\n");
 		uport->icount.brk++;
 		error_f = 1;
 		if (!(uport->ignore_status_mask & IGNBRK)) {
@@ -1533,15 +1625,20 @@
 		rmb();
 	}
 
+	MSM_HS_DBG("%s():[UART_RX]<%d>\n", __func__, rx_count);
+	hex_dump_ipc("HSUART Read: ", msm_uport->rx.buffer, rx_count);
 	if (0 != (uport->read_status_mask & CREAD)) {
 		retval = tty_insert_flip_string(tty, msm_uport->rx.buffer,
 						rx_count);
 		if (retval != rx_count) {
+			MSM_HS_DBG("%s(): retval %d rx_count %d", __func__,
+					retval, rx_count);
 			msm_uport->rx.buffer_pending |= CHARS_NORMAL |
 				retval << 5 | (rx_count - retval) << 16;
 		}
 	}
 
+	MSM_HS_DBG("%s() read rx buffer complete", __func__);
 	/* order the read of rx.buffer and the start of next rx xfer */
 	wmb();
 
@@ -1561,11 +1658,7 @@
 	}
 out:
 	if (msm_uport->rx.buffer_pending) {
-		if (hs_serial_debug_mask)
-			printk(KERN_WARNING
-			       "msm_serial_hs: "
-			       "tty buffer exhausted. "
-			       "Stalling\n");
+		MSM_HS_WARN("tty buffer exhausted.Stalling\n");
 		schedule_delayed_work(&msm_uport->rx.flip_insert_work
 				      , msecs_to_jiffies(RETRY_TIMEOUT));
 	}
@@ -1606,7 +1699,7 @@
 		((struct sps_event_notify *)notify)->user;
 
 	msm_uport->notify = *notify;
-	pr_debug("%s: sps ev_id=%d, addr=0x%x, size=0x%x, flags=0x%x\n",
+	MSM_HS_DBG("%s: sps ev_id=%d, addr=0x%x, size=0x%x, flags=0x%x\n",
 		__func__, notify->event_id,
 		notify->data.transfer.iovec.addr,
 		notify->data.transfer.iovec.size,
@@ -1659,6 +1752,8 @@
 	mb();
 
 	spin_unlock_irqrestore(&(msm_uport->uport.lock), flags);
+	MSM_HS_DBG("In %s()\n", __func__);
+	dump_uart_hs_registers(msm_uport);
 }
 
 /**
@@ -1681,7 +1776,7 @@
 
 	uport = &(msm_uport->uport);
 	msm_uport->notify = *notify;
-	pr_debug("%s: sps ev_id=%d, addr=0x%x, size=0x%x, flags=0x%x\n",
+	MSM_HS_DBG("%s: sps ev_id=%d, addr=0x%x, size=0x%x, flags=0x%x\n",
 		__func__, notify->event_id,
 		notify->data.transfer.iovec.addr,
 		notify->data.transfer.iovec.size,
@@ -1713,7 +1808,7 @@
 	msm_uport = container_of(cmd_ptr, struct msm_hs_port, rx.xfer);
 	uport = &(msm_uport->uport);
 
-	pr_debug("%s(): called result:%x\n", __func__, result);
+	MSM_HS_DBG("%s(): called result:%x\n", __func__, result);
 	if (!(result & DMOV_RSLT_ERROR)) {
 		if (result & DMOV_RSLT_FLUSH) {
 			if (msm_uport->rx_discard_flush_issued) {
@@ -1935,13 +2030,13 @@
 
 		spin_unlock_irqrestore(&uport->lock, flags);
 		if (msm_uport->rx_discard_flush_issued) {
-			pr_debug("%s(): wainting for flush completion.\n",
+			MSM_HS_DBG("%s(): wainting for flush completion.\n",
 								__func__);
 			ret = wait_event_timeout(msm_uport->rx.wait,
 				msm_uport->rx_discard_flush_issued == false,
 				RX_FLUSH_COMPLETE_TIMEOUT);
 			if (!ret)
-				pr_err("%s(): Flush complete pending.\n",
+				MSM_HS_ERR("%s(): Flush complete pending.\n",
 								__func__);
 		}
 
@@ -2005,10 +2100,13 @@
 	spin_lock_irqsave(&uport->lock, flags);
 
 	isr_status = msm_hs_read(uport, UART_DM_MISR);
+	MSM_HS_DBG("%s:UART_DM_MISR %lx", __func__, isr_status);
+	dump_uart_hs_registers(msm_uport);
 
 	/* Uart RX starting */
 	if (isr_status & UARTDM_ISR_RXLEV_BMSK) {
 		wake_lock(&rx->wake_lock);  /* hold wakelock while rx dma */
+		MSM_HS_DBG("%s:UARTDM_ISR_RXLEV_BMSK\n", __func__);
 		msm_uport->imr_reg &= ~UARTDM_ISR_RXLEV_BMSK;
 		msm_hs_write(uport, UART_DM_IMR, msm_uport->imr_reg);
 		/* Complete device write for IMR. Hence mb() requires. */
@@ -2023,6 +2121,7 @@
 		 * mb() requires here.
 		 */
 		mb();
+		MSM_HS_DBG("%s:Stal Interrupt\n", __func__);
 
 		if (msm_uport->clk_req_off_state ==
 					CLK_REQ_OFF_RXSTALE_ISSUED)
@@ -2036,6 +2135,7 @@
 	}
 	/* tx ready interrupt */
 	if (isr_status & UARTDM_ISR_TX_READY_BMSK) {
+		MSM_HS_DBG("%s: ISR_TX_READY Interrupt\n", __func__);
 		/* Clear  TX Ready */
 		msm_hs_write(uport, UART_DM_CR, CLEAR_TX_READY);
 
@@ -2114,7 +2214,7 @@
 		msm_uport->clk_state = MSM_HS_CLK_REQUEST_OFF;
 		msm_uport->clk_req_off_state = CLK_REQ_OFF_START;
 		msm_uport->imr_reg |= UARTDM_ISR_TXLEV_BMSK;
-		msm_hs_write(uport, UARTDM_IMR, msm_uport->imr_reg);
+		msm_hs_write(uport, UART_DM_IMR, msm_uport->imr_reg);
 		/*
 		 * Complete device write before retuning back.
 		 * Hence mb() requires here.
@@ -2252,7 +2352,7 @@
 		if (gpio_is_valid(pdata->uart_rfr_gpio))
 			gpio_free(pdata->uart_rfr_gpio);
 	} else {
-		pr_err("Error:Pdata is NULL.\n");
+		MSM_HS_ERR("Error:Pdata is NULL.\n");
 	}
 }
 
@@ -2272,7 +2372,7 @@
 			ret = gpio_request(pdata->uart_tx_gpio,
 							"UART_TX_GPIO");
 			if (unlikely(ret)) {
-				pr_err("gpio request failed for:%d\n",
+				MSM_HS_ERR("gpio request failed for:%d\n",
 					pdata->uart_tx_gpio);
 				goto exit_uart_config;
 			}
@@ -2282,7 +2382,7 @@
 			ret = gpio_request(pdata->uart_rx_gpio,
 							"UART_RX_GPIO");
 			if (unlikely(ret)) {
-				pr_err("gpio request failed for:%d\n",
+				MSM_HS_ERR("gpio request failed for:%d\n",
 					pdata->uart_rx_gpio);
 				goto uart_tx_unconfig;
 			}
@@ -2292,7 +2392,7 @@
 			ret = gpio_request(pdata->uart_cts_gpio,
 							"UART_CTS_GPIO");
 			if (unlikely(ret)) {
-				pr_err("gpio request failed for:%d\n",
+				MSM_HS_ERR("gpio request failed for:%d\n",
 					pdata->uart_cts_gpio);
 				goto uart_rx_unconfig;
 			}
@@ -2302,13 +2402,13 @@
 			ret = gpio_request(pdata->uart_rfr_gpio,
 							"UART_RFR_GPIO");
 			if (unlikely(ret)) {
-				pr_err("gpio request failed for:%d\n",
+				MSM_HS_ERR("gpio request failed for:%d\n",
 					pdata->uart_rfr_gpio);
 				goto uart_cts_unconfig;
 			}
 		}
 	} else {
-		pr_err("Pdata is NULL.\n");
+		MSM_HS_ERR("Pdata is NULL.\n");
 		ret = -EINVAL;
 	}
 	return ret;
@@ -2354,7 +2454,7 @@
 	/* turn on uart clk */
 	ret = msm_hs_init_clk(uport);
 	if (unlikely(ret)) {
-		pr_err("Turning ON uartclk error\n");
+		MSM_HS_ERR("Turning ON uartclk error\n");
 		wake_unlock(&msm_uport->dma_wake_lock);
 		return ret;
 	}
@@ -2362,7 +2462,7 @@
 	if (is_blsp_uart(msm_uport)) {
 		ret = msm_hs_config_uart_gpios(uport);
 		if (ret) {
-			pr_err("Uart GPIO request failed\n");
+			MSM_HS_ERR("Uart GPIO request failed\n");
 			goto deinit_uart_clk;
 		}
 	} else {
@@ -2376,14 +2476,14 @@
 		/* SPS connect for TX */
 		ret = msm_hs_spsconnect_tx(uport);
 		if (ret) {
-			pr_err("msm_serial_hs: SPS connect failed for TX");
+			MSM_HS_ERR("msm_serial_hs: SPS connect failed for TX");
 			goto unconfig_uart_gpios;
 		}
 
 		/* SPS connect for RX */
 		ret = msm_hs_spsconnect_rx(uport);
 		if (ret) {
-			pr_err("msm_serial_hs: SPS connect failed for RX");
+			MSM_HS_ERR("msm_serial_hs: SPS connect failed for RX");
 			goto sps_disconnect_tx;
 		}
 	}
@@ -2461,7 +2561,7 @@
 	if (use_low_power_wakeup(msm_uport)) {
 		ret = irq_set_irq_wake(msm_uport->wakeup.irq, 1);
 		if (unlikely(ret)) {
-			pr_err("%s():Err setting wakeup irq\n", __func__);
+			MSM_HS_ERR("%s():Err setting wakeup irq\n", __func__);
 			goto sps_disconnect_rx;
 		}
 	}
@@ -2469,7 +2569,7 @@
 	ret = request_irq(uport->irq, msm_hs_isr, IRQF_TRIGGER_HIGH,
 			  "msm_hs_uart", msm_uport);
 	if (unlikely(ret)) {
-		pr_err("%s():Error getting uart irq\n", __func__);
+		MSM_HS_ERR("%s():Error getting uart irq\n", __func__);
 		goto free_wake_irq;
 	}
 	if (use_low_power_wakeup(msm_uport)) {
@@ -2480,7 +2580,7 @@
 					"msm_hs_wakeup", msm_uport);
 
 		if (unlikely(ret)) {
-			pr_err("%s():Err getting uart wakeup_irq\n", __func__);
+			MSM_HS_ERR("%s():Err getting uart wakeup_irq\n", __func__);
 			goto free_uart_irq;
 		}
 		disable_irq(msm_uport->wakeup.irq);
@@ -2543,14 +2643,14 @@
 	rx->pool = dma_pool_create("rx_buffer_pool", uport->dev,
 				   UARTDM_RX_BUF_SIZE, 16, 0);
 	if (!rx->pool) {
-		pr_err("%s(): cannot allocate rx_buffer_pool", __func__);
+		MSM_HS_ERR("%s(): cannot allocate rx_buffer_pool", __func__);
 		ret = -ENOMEM;
 		goto exit_tasket_init;
 	}
 
 	rx->buffer = dma_pool_alloc(rx->pool, GFP_KERNEL, &rx->rbuffer);
 	if (!rx->buffer) {
-		pr_err("%s(): cannot allocate rx->buffer", __func__);
+		MSM_HS_ERR("%s(): cannot allocate rx->buffer", __func__);
 		ret = -ENOMEM;
 		goto free_pool;
 	}
@@ -2589,14 +2689,15 @@
 	/* Allocate the command pointer. Needs to be 64 bit aligned */
 	rx->command_ptr = kmalloc(sizeof(dmov_box), GFP_KERNEL | __GFP_DMA);
 	if (!rx->command_ptr) {
-		pr_err("%s(): cannot allocate rx->command_ptr", __func__);
+		MSM_HS_ERR("%s(): cannot allocate rx->command_ptr", __func__);
 		ret = -ENOMEM;
 		goto free_tx_command_ptr_ptr;
 	}
 
 	rx->command_ptr_ptr = kmalloc(sizeof(u32), GFP_KERNEL | __GFP_DMA);
 	if (!rx->command_ptr_ptr) {
-		pr_err("%s(): cannot allocate rx->command_ptr_ptr", __func__);
+		MSM_HS_ERR("%s(): cannot allocate rx->command_ptr_ptr",
+			 __func__);
 		ret = -ENOMEM;
 		goto free_rx_command_ptr;
 	}
@@ -2664,7 +2765,7 @@
 
 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata) {
-		pr_err("unable to allocate memory for platform data\n");
+		MSM_HS_ERR("unable to allocate memory for platform data\n");
 		return ERR_PTR(-ENOMEM);
 	}
 
@@ -2672,25 +2773,25 @@
 	pdata->uart_tx_gpio = of_get_named_gpio(node,
 					"qcom,tx-gpio", 0);
 	if (pdata->uart_tx_gpio < 0)
-		pr_debug("uart_tx_gpio is not available\n");
+		MSM_HS_DBG("uart_tx_gpio is not available\n");
 
 	/* UART RX GPIO */
 	pdata->uart_rx_gpio = of_get_named_gpio(node,
 					"qcom,rx-gpio", 0);
 	if (pdata->uart_rx_gpio < 0)
-		pr_debug("uart_rx_gpio is not available\n");
+		MSM_HS_DBG("uart_rx_gpio is not available\n");
 
 	/* UART CTS GPIO */
 	pdata->uart_cts_gpio = of_get_named_gpio(node,
 					"qcom,cts-gpio", 0);
 	if (pdata->uart_cts_gpio < 0)
-		pr_debug("uart_cts_gpio is not available\n");
+		MSM_HS_DBG("uart_cts_gpio is not available\n");
 
 	/* UART RFR GPIO */
 	pdata->uart_rfr_gpio = of_get_named_gpio(node,
 					"qcom,rfr-gpio", 0);
 	if (pdata->uart_rfr_gpio < 0)
-		pr_debug("uart_rfr_gpio is not available\n");
+		MSM_HS_DBG("uart_rfr_gpio is not available\n");
 
 	pdata->inject_rx_on_wakeup = of_property_read_bool(node,
 				"qcom,inject-rx-on-wakeup");
@@ -2699,7 +2800,7 @@
 		ret = of_property_read_u32(node, "qcom,rx-char-to-inject",
 						&rx_to_inject);
 		if (ret < 0) {
-			pr_err("Error: Rx_char_to_inject not specified.\n");
+			MSM_HS_ERR("Error: Rx_char_to_inject not specified.\n");
 			return ERR_PTR(ret);
 		}
 		pdata->rx_to_inject = (char)rx_to_inject;
@@ -2708,30 +2809,30 @@
 	ret = of_property_read_u32(node, "qcom,bam-tx-ep-pipe-index",
 				&pdata->bam_tx_ep_pipe_index);
 	if (ret < 0) {
-		pr_err("Error: Getting UART BAM TX EP Pipe Index.\n");
+		MSM_HS_ERR("Error: Getting UART BAM TX EP Pipe Index.\n");
 		return ERR_PTR(ret);
 	}
 
 	if (!(pdata->bam_tx_ep_pipe_index >= BAM_PIPE_MIN &&
 		pdata->bam_tx_ep_pipe_index <= BAM_PIPE_MAX)) {
-		pr_err("Error: Invalid UART BAM TX EP Pipe Index.\n");
+		MSM_HS_ERR("Error: Invalid UART BAM TX EP Pipe Index.\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	ret = of_property_read_u32(node, "qcom,bam-rx-ep-pipe-index",
 					&pdata->bam_rx_ep_pipe_index);
 	if (ret < 0) {
-		pr_err("Error: Getting UART BAM RX EP Pipe Index.\n");
+		MSM_HS_ERR("Error: Getting UART BAM RX EP Pipe Index.\n");
 		return ERR_PTR(ret);
 	}
 
 	if (!(pdata->bam_rx_ep_pipe_index >= BAM_PIPE_MIN &&
 		pdata->bam_rx_ep_pipe_index <= BAM_PIPE_MAX)) {
-		pr_err("Error: Invalid UART BAM RX EP Pipe Index.\n");
+		MSM_HS_ERR("Error: Invalid UART BAM RX EP Pipe Index.\n");
 		return ERR_PTR(-EINVAL);
 	}
 
-	pr_debug("tx_ep_pipe_index:%d rx_ep_pipe_index:%d\n"
+	MSM_HS_DBG("tx_ep_pipe_index:%d rx_ep_pipe_index:%d\n"
 		"tx_gpio:%d rx_gpio:%d rfr_gpio:%d cts_gpio:%d",
 		pdata->bam_tx_ep_pipe_index, pdata->bam_rx_ep_pipe_index,
 		pdata->uart_tx_gpio, pdata->uart_rx_gpio, pdata->uart_cts_gpio,
@@ -2787,7 +2888,7 @@
 	/* Allocate endpoint context */
 	sps_pipe_handle = sps_alloc_endpoint();
 	if (!sps_pipe_handle) {
-		pr_err("msm_serial_hs: sps_alloc_endpoint() failed!!\n"
+		MSM_HS_ERR("msm_serial_hs: sps_alloc_endpoint() failed!!\n"
 			"is_producer=%d", is_producer);
 		rc = -ENOMEM;
 		goto out;
@@ -2796,7 +2897,7 @@
 	/* Get default connection configuration for an endpoint */
 	rc = sps_get_config(sps_pipe_handle, sps_config);
 	if (rc) {
-		pr_err("msm_serial_hs: sps_get_config() failed!!\n"
+		MSM_HS_ERR("msm_serial_hs: sps_get_config() failed!!\n"
 		"pipe_handle=0x%x rc=%d", (u32)sps_pipe_handle, rc);
 		goto get_config_err;
 	}
@@ -2832,7 +2933,7 @@
 						GFP_KERNEL);
 	if (!sps_config->desc.base) {
 		rc = -ENOMEM;
-		pr_err("msm_serial_hs: dma_alloc_coherent() failed!!\n");
+		MSM_HS_ERR("msm_serial_hs: dma_alloc_coherent() failed!!\n");
 		goto get_config_err;
 	}
 	memset(sps_config->desc.base, 0x00, sps_config->desc.size);
@@ -2851,7 +2952,7 @@
 
 	/* Now save the sps pipe handle */
 	ep->pipe_handle = sps_pipe_handle;
-	pr_debug("msm_serial_hs: success !! %s: pipe_handle=0x%x\n"
+	MSM_HS_DBG("msm_serial_hs: success !! %s: pipe_handle=0x%x\n"
 		"desc_fifo.phys_base=0x%llx\n",
 		is_producer ? "READ" : "WRITE",
 		(u32) sps_pipe_handle, (u64) sps_config->desc.phys_base);
@@ -2895,18 +2996,18 @@
 		bam.irq = (u32)msm_uport->bam_irq;
 		bam.manage = SPS_BAM_MGR_DEVICE_REMOTE;
 
-		pr_debug("msm_serial_hs: bam physical base=0x%x\n",
+		MSM_HS_DBG("msm_serial_hs: bam physical base=0x%x\n",
 							(u32)bam.phys_addr);
-		pr_debug("msm_serial_hs: bam virtual base=0x%x\n",
+		MSM_HS_DBG("msm_serial_hs: bam virtual base=0x%x\n",
 							(u32)bam.virt_addr);
 
 		/* Register UART Peripheral BAM device to SPS driver */
 		rc = sps_register_bam_device(&bam, &bam_handle);
 		if (rc) {
-			pr_err("msm_serial_hs: BAM device register failed\n");
+			MSM_HS_ERR("msm_serial_hs: BAM device register failed\n");
 			return rc;
 		}
-		pr_info("msm_serial_hs: BAM device registered. bam_handle=0x%x",
+		MSM_HS_INFO("msm_serial_hs: BAM device registered. bam_handle=0x%x",
 							msm_uport->bam_handle);
 	}
 	msm_uport->bam_handle = bam_handle;
@@ -2914,14 +3015,14 @@
 	rc = msm_hs_sps_init_ep_conn(msm_uport, &msm_uport->rx.prod,
 				UART_SPS_PROD_PERIPHERAL);
 	if (rc) {
-		pr_err("%s: Failed to Init Producer BAM-pipe", __func__);
+		MSM_HS_ERR("%s: Failed to Init Producer BAM-pipe", __func__);
 		goto deregister_bam;
 	}
 
 	rc = msm_hs_sps_init_ep_conn(msm_uport, &msm_uport->tx.cons,
 				UART_SPS_CONS_PERIPHERAL);
 	if (rc) {
-		pr_err("%s: Failed to Init Consumer BAM-pipe", __func__);
+		MSM_HS_ERR("%s: Failed to Init Consumer BAM-pipe", __func__);
 		goto deinit_ep_conn_prod;
 	}
 	return 0;
@@ -2973,7 +3074,7 @@
 				if (deviceid[alias_num] == 0) {
 					pdev->id = alias_num;
 				} else {
-					pr_err("alias_num=%d already used\n",
+					MSM_HS_ERR("alias_num=%d already used\n",
 								alias_num);
 					return -EINVAL;
 				}
@@ -2986,7 +3087,7 @@
 	}
 
 	if (pdev->id < 0 || pdev->id >= UARTDM_NR) {
-		pr_err("Invalid plaform device ID = %d\n", pdev->id);
+		MSM_HS_ERR("Invalid plaform device ID = %d\n", pdev->id);
 		return -EINVAL;
 	}
 
@@ -3014,39 +3115,39 @@
 		wakeup_irqres = platform_get_irq_byname(pdev, "wakeup_irq");
 
 		if (!core_resource) {
-			pr_err("Invalid core HSUART Resources.\n");
+			MSM_HS_ERR("Invalid core HSUART Resources.\n");
 			return -ENXIO;
 		}
 
 		if (!bam_resource) {
-			pr_err("Invalid BAM HSUART Resources.\n");
+			MSM_HS_ERR("Invalid BAM HSUART Resources.\n");
 			return -ENXIO;
 		}
 
 		if (!core_irqres) {
-			pr_err("Invalid core irqres Resources.\n");
+			MSM_HS_ERR("Invalid core irqres Resources.\n");
 			return -ENXIO;
 		}
 		if (!bam_irqres) {
-			pr_err("Invalid bam irqres Resources.\n");
+			MSM_HS_ERR("Invalid bam irqres Resources.\n");
 			return -ENXIO;
 		}
 		if (!wakeup_irqres)
-			pr_debug("Wakeup irq not specified.\n");
+			MSM_HS_DBG("Wakeup irq not specified.\n");
 
 		uport->mapbase = core_resource->start;
 
 		uport->membase = ioremap(uport->mapbase,
 					resource_size(core_resource));
 		if (unlikely(!uport->membase)) {
-			pr_err("UART Resource ioremap Failed.\n");
+			MSM_HS_ERR("UART Resource ioremap Failed.\n");
 			return -ENOMEM;
 		}
 		msm_uport->bam_mem = bam_resource->start;
 		msm_uport->bam_base = ioremap(msm_uport->bam_mem,
 					resource_size(bam_resource));
 		if (unlikely(!msm_uport->bam_base)) {
-			pr_err("UART BAM Resource ioremap Failed.\n");
+			MSM_HS_ERR("UART BAM Resource ioremap Failed.\n");
 			iounmap(uport->membase);
 			return -ENOMEM;
 		}
@@ -3057,13 +3158,13 @@
 
 		msm_uport->bus_scale_table = msm_bus_cl_get_pdata(pdev);
 		if (!msm_uport->bus_scale_table) {
-			pr_err("BLSP UART: Bus scaling is disabled.\n");
+			MSM_HS_ERR("BLSP UART: Bus scaling is disabled.\n");
 		} else {
 			msm_uport->bus_perf_client =
 				msm_bus_scale_register_client
 					(msm_uport->bus_scale_table);
 			if (IS_ERR(&msm_uport->bus_perf_client)) {
-				pr_err("%s(): Bus client register failed.\n",
+				MSM_HS_ERR("%s(): Bus client register failed.\n",
 								__func__);
 				ret = -EINVAL;
 				goto unmap_memory;
@@ -3082,7 +3183,7 @@
 
 		uport->irq = platform_get_irq(pdev, 0);
 		if (unlikely((int)uport->irq < 0)) {
-			pr_err("UART IRQ Failed.\n");
+			MSM_HS_ERR("UART IRQ Failed.\n");
 			iounmap(uport->membase);
 			return -ENXIO;
 		}
@@ -3155,14 +3256,14 @@
 
 	ret = clk_set_rate(msm_uport->clk, uport->uartclk);
 	if (ret) {
-		printk(KERN_WARNING "Error setting clock rate on UART\n");
+		MSM_HS_WARN("Error setting clock rate on UART\n");
 		goto put_clk;
 	}
 
 	msm_uport->hsuart_wq = alloc_workqueue("k_hsuart",
 					WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
 	if (!msm_uport->hsuart_wq) {
-		pr_err("%s(): Unable to create workqueue hsuart_wq\n",
+		MSM_HS_ERR("%s(): Unable to create workqueue hsuart_wq\n",
 								__func__);
 		ret =  -ENOMEM;
 		goto put_clk;
@@ -3181,7 +3282,7 @@
 	if (is_blsp_uart(msm_uport)) {
 		ret = msm_hs_sps_init(msm_uport);
 		if (unlikely(ret)) {
-			pr_err("SPS Initialization failed ! err=%d", ret);
+			MSM_HS_ERR("SPS Initialization failed ! err=%d", ret);
 			goto destroy_mutex;
 		}
 	}
@@ -3254,28 +3355,33 @@
 	int ret;
 	int i;
 
+	ipc_msm_hs_log_ctxt = ipc_log_context_create(IPC_MSM_HS_LOG_PAGES,
+							"msm_serial_hs");
+	if (!ipc_msm_hs_log_ctxt)
+		MSM_HS_WARN("%s: error creating logging context", __func__);
+
 	/* Init all UARTS as non-configured */
 	for (i = 0; i < UARTDM_NR; i++)
 		q_uart_port[i].uport.type = PORT_UNKNOWN;
 
 	ret = uart_register_driver(&msm_hs_driver);
 	if (unlikely(ret)) {
-		printk(KERN_ERR "%s failed to load\n", __FUNCTION__);
+		MSM_HS_WARN("%s failed to load\n", __func__);
 		return ret;
 	}
 	debug_base = debugfs_create_dir("msm_serial_hs", NULL);
 	if (IS_ERR_OR_NULL(debug_base))
-		pr_info("msm_serial_hs: Cannot create debugfs dir\n");
+		MSM_HS_INFO("msm_serial_hs: Cannot create debugfs dir\n");
 
 	ret = platform_driver_register(&msm_serial_hs_platform_driver);
 	if (ret) {
-		printk(KERN_ERR "%s failed to load\n", __FUNCTION__);
+		MSM_HS_ERR("%s failed to load\n", __FUNCTION__);
 		debugfs_remove_recursive(debug_base);
 		uart_unregister_driver(&msm_hs_driver);
 		return ret;
 	}
 
-	printk(KERN_INFO "msm_serial_hs module loaded\n");
+	MSM_HS_INFO("msm_serial_hs module loaded\n");
 	return ret;
 }
 
@@ -3318,12 +3424,12 @@
 			ret = wait_event_timeout(msm_uport->tx.wait,
 				msm_uport->tx.flush == FLUSH_SHUTDOWN, 100);
 			if (!ret)
-				pr_err("%s():HSUART TX Stalls.\n", __func__);
+				MSM_HS_ERR("%s():HSUART TX Stalls.\n", __func__);
 		} else {
 			/* BAM Disconnect for TX */
 			ret = sps_disconnect(sps_pipe_handle);
 			if (ret)
-				pr_err("%s(): sps_disconnect failed\n",
+				MSM_HS_ERR("%s(): sps_disconnect failed\n",
 							__func__);
 		}
 	}
@@ -3378,7 +3484,7 @@
 
 static void __exit msm_serial_hs_exit(void)
 {
-	printk(KERN_INFO "msm_serial_hs module removed\n");
+	MSM_HS_INFO("msm_serial_hs module removed\n");
 	debugfs_remove_recursive(debug_base);
 	platform_driver_unregister(&msm_serial_hs_platform_driver);
 	uart_unregister_driver(&msm_hs_driver);
diff --git a/drivers/tty/serial/msm_serial_hs_lite.c b/drivers/tty/serial/msm_serial_hs_lite.c
index a4a4f28..0ff8ad7 100644
--- a/drivers/tty/serial/msm_serial_hs_lite.c
+++ b/drivers/tty/serial/msm_serial_hs_lite.c
@@ -523,6 +523,10 @@
 {
 	struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port);
 
+	if (port->suspended) {
+		pr_err("%s: System is in Suspend state\n", __func__);
+		return;
+	}
 	msm_hsl_port->imr |= UARTDM_ISR_TXLEV_BMSK;
 	msm_hsl_write(port, msm_hsl_port->imr,
 		regmap[msm_hsl_port->ver_id][UARTDM_IMR]);
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index c65ed25..877b944 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -1770,7 +1770,7 @@
 	struct fsg_common *common;
 	int err;
 	int i;
-	const char *name[2];
+	const char *name[3];
 
 	config = kzalloc(sizeof(struct mass_storage_function_config),
 								GFP_KERNEL);
diff --git a/drivers/usb/host/ehci-msm2.c b/drivers/usb/host/ehci-msm2.c
index dd04f49..7ae0a54 100644
--- a/drivers/usb/host/ehci-msm2.c
+++ b/drivers/usb/host/ehci-msm2.c
@@ -1063,7 +1063,7 @@
 
 	memset(kbuf, 0, 10);
 
-	if (copy_from_user(kbuf, buf, count > 10 ? 10 : count))
+	if (copy_from_user(kbuf, buf, min_t(size_t, sizeof(kbuf) - 1, count)))
 		return -EFAULT;
 
 	if (sscanf(kbuf, "%x", &data) != 1)
@@ -1088,7 +1088,7 @@
 
 	memset(kbuf, 0, 10);
 
-	if (copy_from_user(kbuf, buf, count > 10 ? 10 : count))
+	if (copy_from_user(kbuf, buf, min_t(size_t, sizeof(kbuf) - 1, count)))
 		return -EFAULT;
 
 	if (sscanf(kbuf, "%x", &temp) != 1)
diff --git a/drivers/usb/misc/diag_bridge.c b/drivers/usb/misc/diag_bridge.c
index 22e2a25..ccd48ca 100644
--- a/drivers/usb/misc/diag_bridge.c
+++ b/drivers/usb/misc/diag_bridge.c
@@ -464,12 +464,7 @@
 		pr_err("unable to allocate dev");
 		return -ENOMEM;
 	}
-	dev->pdev = platform_device_alloc("diag_bridge", devid);
-	if (!dev->pdev) {
-		pr_err("unable to allocate platform device");
-		kfree(dev);
-		return -ENOMEM;
-	}
+
 	__dev[devid] = dev;
 	dev->id = devid;
 
@@ -498,7 +493,13 @@
 
 	usb_set_intfdata(ifc, dev);
 	diag_bridge_debugfs_init();
-	platform_device_add(dev->pdev);
+	dev->pdev = platform_device_register_simple("diag_bridge", devid,
+						    NULL, 0);
+	if (IS_ERR(dev->pdev)) {
+		pr_err("unable to allocate platform device");
+		ret = PTR_ERR(dev->pdev);
+		goto error;
+	}
 
 	dev_dbg(&dev->ifc->dev, "%s: complete\n", __func__);
 
diff --git a/drivers/video/msm/mdss/Kconfig b/drivers/video/msm/mdss/Kconfig
index b49e08e..01edf92 100644
--- a/drivers/video/msm/mdss/Kconfig
+++ b/drivers/video/msm/mdss/Kconfig
@@ -28,3 +28,10 @@
 	  seconds) by sending Bus-Turn-Around (BTA) command. If DSI controller
 	  fails to acknowledge the BTA command, it sends PANEL_ALIVE=0 status
 	  to HAL layer to reset the controller.
+
+config FB_MSM_MDSS_MDP3
+	depends on FB_MSM_MDSS
+	bool "MDP3 display controller"
+	---help---
+	The MDP3 provides support for an older version display controller
+	included in latest display sub-system, known as MDSS.
diff --git a/drivers/video/msm/mdss/Makefile b/drivers/video/msm/mdss/Makefile
index 0fc6245..fd03b63 100644
--- a/drivers/video/msm/mdss/Makefile
+++ b/drivers/video/msm/mdss/Makefile
@@ -1,6 +1,6 @@
 mdss-mdp3-objs = mdp3.o mdp3_dma.o mdp3_ctrl.o
 mdss-mdp3-objs += mdp3_ppp.o mdp3_ppp_hwio.o mdp3_ppp_data.o
-obj-$(CONFIG_FB_MSM_MDSS) += mdss-mdp3.o
+obj-$(CONFIG_FB_MSM_MDSS_MDP3) += mdss-mdp3.o
 
 mdss-mdp-objs := mdss_mdp.o mdss_mdp_ctl.o mdss_mdp_pipe.o mdss_mdp_util.o
 mdss-mdp-objs += mdss_mdp_pp.o
@@ -17,7 +17,7 @@
 endif
 
 dsi-v2-objs = dsi_v2.o dsi_host_v2.o dsi_io_v2.o
-obj-$(CONFIG_FB_MSM_MDSS) += dsi-v2.o
+obj-$(CONFIG_FB_MSM_MDSS_MDP3) += dsi-v2.o
 
 mdss-dsi-objs := mdss_dsi.o mdss_dsi_host.o mdss_dsi_cmd.o
 mdss-dsi-objs += mdss_dsi_panel.o
@@ -42,4 +42,8 @@
 
 obj-$(CONFIG_FB_MSM_MDSS) += mdss_fb.o
 
+ifeq ($(CONFIG_FB_MSM_MDSS_MDP3),y)
+obj-$(CONFIG_FB_MSM_MDSS_DSI_CTRL_STATUS) += dsi_status_v2.o
+else
 obj-$(CONFIG_FB_MSM_MDSS_DSI_CTRL_STATUS) += mdss_dsi_status.o
+endif
diff --git a/drivers/video/msm/mdss/dsi_host_v2.c b/drivers/video/msm/mdss/dsi_host_v2.c
index aa41cb2..25ee3e4 100644
--- a/drivers/video/msm/mdss/dsi_host_v2.c
+++ b/drivers/video/msm/mdss/dsi_host_v2.c
@@ -78,6 +78,9 @@
 
 	if (status) {
 		MIPI_OUTP(ctrl_base + DSI_ACK_ERR_STATUS, status);
+
+		/* Writing of an extra 0 needed to clear error bits */
+		MIPI_OUTP(ctrl_base + DSI_ACK_ERR_STATUS, 0);
 		pr_err("%s: status=%x\n", __func__, status);
 	}
 }
@@ -220,6 +223,12 @@
 
 	spin_unlock(&ctrl->mdp_lock);
 
+	if (isr & DSI_INTR_BTA_DONE)
+		complete(&ctrl->bta_comp);
+
+	if (isr & DSI_INTR_CMD_MDP_DONE)
+		complete(&ctrl->mdp_comp);
+
 	return IRQ_HANDLED;
 }
 
@@ -261,6 +270,49 @@
 	}
 }
 
+static int msm_dsi_wait4mdp_done(struct mdss_dsi_ctrl_pdata *ctrl)
+{
+	int rc;
+	unsigned long flag;
+
+	spin_lock_irqsave(&ctrl->mdp_lock, flag);
+	INIT_COMPLETION(ctrl->mdp_comp);
+	msm_dsi_set_irq(ctrl, DSI_INTR_CMD_MDP_DONE_MASK);
+	spin_unlock_irqrestore(&ctrl->mdp_lock, flag);
+
+	rc = wait_for_completion_timeout(&ctrl->mdp_comp,
+			msecs_to_jiffies(VSYNC_PERIOD * 4));
+
+	if (rc == 0) {
+		pr_err("DSI wait 4 mdp done time out\n");
+		rc = -ETIME;
+	} else if (!IS_ERR_VALUE(rc)) {
+		rc = 0;
+	}
+
+	msm_dsi_clear_irq(ctrl, DSI_INTR_CMD_MDP_DONE_MASK);
+
+	return rc;
+}
+
+void msm_dsi_cmd_mdp_busy(struct mdss_dsi_ctrl_pdata *ctrl)
+{
+	int rc;
+	u32 dsi_status;
+	unsigned char *ctrl_base = dsi_host_private->dsi_base;
+
+	if (ctrl->panel_mode == DSI_VIDEO_MODE)
+		return;
+
+	dsi_status = MIPI_INP(ctrl_base + DSI_STATUS);
+	if (dsi_status & 0x04) {
+		pr_debug("dsi command engine is busy\n");
+		rc = msm_dsi_wait4mdp_done(ctrl);
+		if (rc)
+			pr_err("Timed out waiting for mdp done");
+	}
+}
+
 static int msm_dsi_wait4video_done(struct mdss_dsi_ctrl_pdata *ctrl)
 {
 	int rc;
@@ -883,17 +935,18 @@
 	if (req->cb)
 		req->cb(len);
 }
-void msm_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
+int msm_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
 {
 	struct dcs_cmd_req *req;
 	int dsi_on;
+	int ret = -EINVAL;
 
 	mutex_lock(&ctrl->mutex);
 	dsi_on = dsi_host_private->dsi_on;
 	mutex_unlock(&ctrl->mutex);
 	if (!dsi_on) {
 		pr_err("try to send DSI commands while dsi is off\n");
-		return;
+		return ret;
 	}
 
 	mutex_lock(&ctrl->cmd_mutex);
@@ -901,21 +954,20 @@
 
 	if (!req) {
 		mutex_unlock(&ctrl->cmd_mutex);
-		return;
+		return ret;
 	}
 
 	msm_dsi_clk_ctrl(&ctrl->panel_data, 1);
-	dsi_set_tx_power_mode(0);
 
 	if (req->flags & CMD_REQ_RX)
 		msm_dsi_cmdlist_rx(ctrl, req);
 	else
 		msm_dsi_cmdlist_tx(ctrl, req);
 
-	dsi_set_tx_power_mode(1);
 	msm_dsi_clk_ctrl(&ctrl->panel_data, 0);
 
 	mutex_unlock(&ctrl->cmd_mutex);
+	return 0;
 }
 
 static int msm_dsi_cal_clk_rate(struct mdss_panel_data *pdata,
@@ -1166,6 +1218,38 @@
 	return 0;
 }
 
+int msm_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
+{
+	int ret = 0;
+
+	if (ctrl_pdata == NULL) {
+		pr_err("%s: Invalid input data\n", __func__);
+		return 0;
+	}
+
+	mutex_lock(&ctrl_pdata->cmd_mutex);
+	msm_dsi_clk_ctrl(&ctrl_pdata->panel_data, 1);
+	msm_dsi_cmd_mdp_busy(ctrl_pdata);
+	msm_dsi_set_irq(ctrl_pdata, DSI_INTR_BTA_DONE_MASK);
+	INIT_COMPLETION(ctrl_pdata->bta_comp);
+
+	/* BTA trigger */
+	MIPI_OUTP(dsi_host_private->dsi_base + DSI_CMD_MODE_BTA_SW_TRIGGER,
+									0x01);
+	wmb();
+	ret = wait_for_completion_killable_timeout(&ctrl_pdata->bta_comp,
+									HZ/10);
+	msm_dsi_clear_irq(ctrl_pdata, DSI_INTR_BTA_DONE_MASK);
+	msm_dsi_clk_ctrl(&ctrl_pdata->panel_data, 0);
+	mutex_unlock(&ctrl_pdata->cmd_mutex);
+
+	if (ret <= 0)
+		pr_err("%s: DSI BTA error: %i\n", __func__, __LINE__);
+
+	pr_debug("%s: BTA done with ret: %d\n", __func__, ret);
+	return ret;
+}
+
 static void msm_dsi_debug_enable_clock(int on)
 {
 	if (dsi_host_private->debug_enable_clk)
@@ -1221,6 +1305,21 @@
 	return rc;
 }
 
+static struct device_node *dsi_pref_prim_panel(
+		struct platform_device *pdev)
+{
+	struct device_node *dsi_pan_node = NULL;
+
+	pr_debug("%s:%d: Select primary panel from dt\n",
+					__func__, __LINE__);
+	dsi_pan_node = of_parse_phandle(pdev->dev.of_node,
+					"qcom,dsi-pref-prim-pan", 0);
+	if (!dsi_pan_node)
+		pr_err("%s:can't find panel phandle\n", __func__);
+
+	return dsi_pan_node;
+}
+
 /**
  * dsi_find_panel_of_node(): find device node of dsi panel
  * @pdev: platform_device of the dsi ctrl node
@@ -1250,14 +1349,7 @@
 		/* no panel cfg chg, parse dt */
 		pr_debug("%s:%d: no cmd line cfg present\n",
 			 __func__, __LINE__);
-		dsi_pan_node = of_parse_phandle(
-			pdev->dev.of_node,
-			"qcom,dsi-pref-prim-pan", 0);
-		if (!dsi_pan_node) {
-			pr_err("%s:can't find panel phandle\n",
-			       __func__);
-			return NULL;
-		}
+		dsi_pan_node = dsi_pref_prim_panel(pdev);
 	} else {
 		if (panel_cfg[0] != '0') {
 			pr_err("%s:%d:ctrl id=[%d] not supported\n",
@@ -1285,7 +1377,7 @@
 		if (!dsi_pan_node) {
 			pr_err("%s: invalid pan node\n",
 			       __func__);
-			return NULL;
+			dsi_pan_node = dsi_pref_prim_panel(pdev);
 		}
 	}
 	return dsi_pan_node;
@@ -1329,6 +1421,7 @@
 {
 	init_completion(&ctrl->dma_comp);
 	init_completion(&ctrl->mdp_comp);
+	init_completion(&ctrl->bta_comp);
 	init_completion(&ctrl->video_comp);
 	spin_lock_init(&ctrl->irq_lock);
 	spin_lock_init(&ctrl->mdp_lock);
@@ -1339,6 +1432,7 @@
 	dsi_buf_alloc(&ctrl->rx_buf, SZ_4K);
 	ctrl->cmdlist_commit = msm_dsi_cmdlist_commit;
 	ctrl->panel_mode = ctrl->panel_data.panel_info.mipi.mode;
+	ctrl->check_status = msm_dsi_bta_status_check;
 }
 
 static int __devinit msm_dsi_probe(struct platform_device *pdev)
diff --git a/drivers/video/msm/mdss/dsi_host_v2.h b/drivers/video/msm/mdss/dsi_host_v2.h
index cec9774..b297452 100644
--- a/drivers/video/msm/mdss/dsi_host_v2.h
+++ b/drivers/video/msm/mdss/dsi_host_v2.h
@@ -17,6 +17,8 @@
 
 #define DSI_INTR_ERROR_MASK			BIT(25)
 #define DSI_INTR_ERROR				BIT(24)
+#define DSI_INTR_BTA_DONE_MASK			BIT(21)
+#define DSI_INTR_BTA_DONE			BIT(20)
 #define DSI_INTR_VIDEO_DONE_MASK		BIT(17)
 #define DSI_INTR_VIDEO_DONE			BIT(16)
 #define DSI_INTR_CMD_MDP_DONE_MASK		BIT(9)
@@ -24,6 +26,8 @@
 #define DSI_INTR_CMD_DMA_DONE_MASK		BIT(1)
 #define DSI_INTR_CMD_DMA_DONE			BIT(0)
 
+#define DSI_BTA_TERM				BIT(1)
+
 #define DSI_CTRL				0x0000
 #define DSI_STATUS				0x0004
 #define DSI_FIFO_STATUS			0x0008
diff --git a/drivers/video/msm/mdss/dsi_status_v2.c b/drivers/video/msm/mdss/dsi_status_v2.c
new file mode 100644
index 0000000..d62ddf3
--- /dev/null
+++ b/drivers/video/msm/mdss/dsi_status_v2.c
@@ -0,0 +1,188 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/notifier.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/iopoll.h>
+#include <linux/kobject.h>
+#include <linux/string.h>
+#include <linux/sysfs.h>
+
+#include "mdss_fb.h"
+#include "mdss_dsi.h"
+#include "mdss_panel.h"
+#include "mdp3_ctrl.h"
+
+#define STATUS_CHECK_INTERVAL 5000
+
+/**
+ * dsi_status_data - Stores all the data necessary for this module
+ * @fb_notif: Used to egister for the fb events
+ * @live_status: Delayed worker structure, used to associate the
+ * delayed worker function
+ * @mfd: Used to store the msm_fb_data_type received when the notifier
+ * call back happens
+ * @root: Stores the dir created by debuugfs
+ * @debugfs_reset_panel: The debugfs variable used to inject errors
+ */
+
+struct dsi_status_data {
+	struct notifier_block fb_notifier;
+	struct delayed_work check_status;
+	struct msm_fb_data_type *mfd;
+	uint32_t check_interval;
+};
+struct dsi_status_data *pstatus_data;
+static uint32_t interval = STATUS_CHECK_INTERVAL;
+
+void check_dsi_ctrl_status(struct work_struct *work)
+{
+	struct dsi_status_data *pdsi_status = NULL;
+	struct mdss_panel_data *pdata = NULL;
+	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+	struct mdp3_session_data *mdp3_session = NULL;
+	int ret = 0;
+
+	pdsi_status = container_of(to_delayed_work(work),
+		struct dsi_status_data, check_status);
+	if (!pdsi_status) {
+		pr_err("%s: DSI status data not available\n", __func__);
+		return;
+	}
+
+	pdata = dev_get_platdata(&pdsi_status->mfd->pdev->dev);
+	if (!pdata) {
+		pr_err("%s: Panel data not available\n", __func__);
+		return;
+	}
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+							panel_data);
+	if (!ctrl_pdata || !ctrl_pdata->check_status) {
+		pr_err("%s: DSI ctrl or status_check callback not avilable\n",
+								__func__);
+		return;
+	}
+	mdp3_session = pdsi_status->mfd->mdp.private1;
+	mutex_lock(&mdp3_session->lock);
+
+	ret = ctrl_pdata->check_status(ctrl_pdata);
+
+	mutex_unlock(&mdp3_session->lock);
+
+	if ((pdsi_status->mfd->panel_power_on)) {
+		if (ret > 0) {
+			schedule_delayed_work(&pdsi_status->check_status,
+				msecs_to_jiffies(pdsi_status->check_interval));
+		} else {
+			char *envp[2] = {"PANEL_ALIVE=0", NULL};
+			pdata->panel_info.panel_dead = true;
+			ret = kobject_uevent_env(
+				&pdsi_status->mfd->fbi->dev->kobj,
+							KOBJ_CHANGE, envp);
+			pr_err("%s: Panel has gone bad, sending uevent - %s\n",
+							__func__, envp[0]);
+		}
+	}
+}
+
+/**
+ * fb_notifier_callback() - Call back function for the fb_register_client()
+ * notifying events
+ * @self  : notifier block
+ * @event : The event that was triggered
+ * @data  : Of type struct fb_event
+ *
+ * - This function listens for FB_BLANK_UNBLANK and FB_BLANK_POWERDOWN events
+ * - Based on the event the delayed work is either scheduled again after
+ * PANEL_STATUS_CHECK_INTERVAL or cancelled
+ */
+static int fb_event_callback(struct notifier_block *self,
+				unsigned long event, void *data)
+{
+	struct fb_event *evdata = (struct fb_event *)data;
+	struct dsi_status_data *pdata = container_of(self,
+				struct dsi_status_data, fb_notifier);
+	pdata->mfd = (struct msm_fb_data_type *)evdata->info->par;
+
+	if (event == FB_EVENT_BLANK && evdata) {
+		int *blank = evdata->data;
+		switch (*blank) {
+		case FB_BLANK_UNBLANK:
+			schedule_delayed_work(&pdata->check_status,
+			msecs_to_jiffies(STATUS_CHECK_INTERVAL));
+			break;
+		case FB_BLANK_POWERDOWN:
+			cancel_delayed_work(&pdata->check_status);
+			break;
+		}
+	}
+	return 0;
+}
+
+int __init mdss_dsi_status_init(void)
+{
+	int rc;
+
+	pstatus_data = kzalloc(sizeof(struct dsi_status_data),	GFP_KERNEL);
+	if (!pstatus_data) {
+		pr_err("%s: can't alloc mem\n", __func__);
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	memset(pstatus_data, 0, sizeof(struct dsi_status_data));
+
+	pstatus_data->fb_notifier.notifier_call = fb_event_callback;
+
+	rc = fb_register_client(&pstatus_data->fb_notifier);
+	if (rc < 0) {
+		pr_err("%s: fb_register_client failed, returned with rc=%d\n",
+								__func__, rc);
+		kfree(pstatus_data);
+		return -EPERM;
+	}
+
+	pstatus_data->check_interval = interval;
+	pr_info("%s: DSI status check interval:%d\n", __func__, interval);
+
+	INIT_DELAYED_WORK(&pstatus_data->check_status, check_dsi_ctrl_status);
+
+	pr_debug("%s: DSI ctrl status thread initialized\n", __func__);
+
+	return rc;
+}
+
+void __exit mdss_dsi_status_exit(void)
+{
+	fb_unregister_client(&pstatus_data->fb_notifier);
+	cancel_delayed_work_sync(&pstatus_data->check_status);
+	kfree(pstatus_data);
+	pr_debug("%s: DSI ctrl status thread removed\n", __func__);
+}
+
+module_param(interval, uint, 0);
+MODULE_PARM_DESC(interval,
+	"Duration in milliseconds to send BTA command for checking"
+	"DSI status periodically");
+
+module_init(mdss_dsi_status_init);
+module_exit(mdss_dsi_status_exit);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c
index 3999db9..02bd7e9 100644
--- a/drivers/video/msm/mdss/mdp3.c
+++ b/drivers/video/msm/mdss/mdp3.c
@@ -186,6 +186,7 @@
 	int i = 0;
 	struct mdp3_hw_resource *mdata = (struct mdp3_hw_resource *)ptr;
 	u32 mdp_interrupt = 0;
+	u32 mdp_status = 0;
 
 	spin_lock(&mdata->irq_lock);
 	if (!mdata->irq_mask)
@@ -194,8 +195,8 @@
 	clk_enable(mdp3_res->clocks[MDP3_CLK_AHB]);
 	clk_enable(mdp3_res->clocks[MDP3_CLK_CORE]);
 
-	mdp_interrupt = MDP3_REG_READ(MDP3_REG_INTR_STATUS);
-	MDP3_REG_WRITE(MDP3_REG_INTR_CLEAR, mdp_interrupt);
+	mdp_status = MDP3_REG_READ(MDP3_REG_INTR_STATUS);
+	mdp_interrupt = mdp_status;
 	pr_debug("mdp3_irq_handler irq=%d\n", mdp_interrupt);
 
 	mdp_interrupt &= mdata->irq_mask;
@@ -206,6 +207,7 @@
 		mdp_interrupt = mdp_interrupt >> 1;
 		i++;
 	}
+	MDP3_REG_WRITE(MDP3_REG_INTR_CLEAR, mdp_status);
 
 	clk_disable(mdp3_res->clocks[MDP3_CLK_AHB]);
 	clk_disable(mdp3_res->clocks[MDP3_CLK_CORE]);
@@ -949,7 +951,7 @@
 {
 	char *t = NULL;
 	char pan_intf_str[MDSS_MAX_PANEL_LEN];
-	int rc, i;
+	int rc, i, panel_len;
 	char pan_name[MDSS_MAX_PANEL_LEN];
 
 	if (!pan_cfg)
@@ -986,6 +988,14 @@
 	strlcpy(&pan_cfg->arg_cfg[0], t, sizeof(pan_cfg->arg_cfg));
 	pr_debug("%s:%d: t=[%s] panel name=[%s]\n", __func__, __LINE__,
 		t, pan_cfg->arg_cfg);
+
+	panel_len = strlen(pan_cfg->arg_cfg);
+	if (!panel_len) {
+		pr_err("%s: Panel name is invalid\n", __func__);
+		pan_cfg->pan_intf = MDSS_PANEL_INTF_INVALID;
+		return -EINVAL;
+	}
+
 	rc = mdp3_get_pan_intf(pan_intf_str);
 	pan_cfg->pan_intf = (rc < 0) ?  MDSS_PANEL_INTF_INVALID : rc;
 	return 0;
@@ -1069,10 +1079,10 @@
 	of_node_put(chosen_node);
 
 	rc = mdp3_get_pan_cfg(pan_cfg);
-	if (!rc)
+	if (!rc) {
 		pan_cfg->init_done = true;
-
-	return rc;
+		return rc;
+	}
 
 get_dt_pan:
 	rc = mdp3_parse_dt_pan_intf(pdev);
@@ -1443,7 +1453,9 @@
 			ret = 0;
 		} else {
 			ret = PTR_ERR(iommu_meta);
-			goto out_unlock;
+			mutex_unlock(&mdp3_res->iommu_lock);
+			pr_err("%s: meta_create failed err=%d", __func__, ret);
+			return ret;
 		}
 	} else {
 		if (iommu_meta->flags != iommu_flags) {
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index 6219737..a6fc20d 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -613,9 +613,6 @@
 	panel = mdp3_session->panel;
 	mutex_lock(&mdp3_session->lock);
 
-	if (panel && panel->set_backlight)
-		panel->set_backlight(panel, 0);
-
 	if (!mdp3_session->status) {
 		pr_debug("fb%d is off already", mfd->index);
 		goto off_error;
@@ -838,6 +835,14 @@
 {
 	int rc = 0;
 	struct mdp3_session_data *mdp3_session = mfd->mdp.private1;
+	struct fb_var_screeninfo *var;
+	struct fb_fix_screeninfo *fix;
+	struct fb_info *fbi = mfd->fbi;
+	int stride;
+
+	fix = &fbi->fix;
+	var = &fbi->var;
+	stride = req->src.width * var->bits_per_pixel/8;
 
 	mutex_lock(&mdp3_session->lock);
 
@@ -846,6 +851,9 @@
 
 	mdp3_session->overlay = *req;
 	if (req->id == MSMFB_NEW_REQUEST) {
+		if (fix->line_length != stride)
+			mdp3_session->dma->config_stride(
+						mdp3_session->dma, stride);
 		mdp3_session->overlay.id = 1;
 		req->id = 1;
 	}
@@ -859,10 +867,15 @@
 {
 	int rc = 0;
 	struct mdp3_session_data *mdp3_session = mfd->mdp.private1;
+	struct fb_info *fbi = mfd->fbi;
+	struct fb_fix_screeninfo *fix;
 
+	fix = &fbi->fix;
 	mutex_lock(&mdp3_session->lock);
 
 	if (mdp3_session->overlay.id == ndx && ndx == 1) {
+		mdp3_session->dma->config_stride(mdp3_session->dma,
+							fix->line_length);
 		mdp3_session->overlay.id = MSMFB_NEW_REQUEST;
 		mdp3_bufq_deinit(&mdp3_session->bufq_in);
 	} else {
@@ -966,7 +979,7 @@
 		mdp3_bufq_push(&mdp3_session->bufq_out, data);
 	}
 
-	if (mdp3_bufq_count(&mdp3_session->bufq_out) > 2) {
+	if (mdp3_bufq_count(&mdp3_session->bufq_out) > 1) {
 		data = mdp3_bufq_pop(&mdp3_session->bufq_out);
 		mdp3_put_img(data, MDP3_CLIENT_DMA_P);
 	}
@@ -1708,14 +1721,14 @@
 	kobject_uevent(&dev->kobj, KOBJ_ADD);
 	pr_debug("vsync kobject_uevent(KOBJ_ADD)\n");
 
+	if (mdp3_get_cont_spash_en())
+		mdp3_session->clk_on = 1;
+
 	if (splash_mismatch) {
 		pr_err("splash memory mismatch, stop splash\n");
 		mdp3_ctrl_off(mfd);
 	}
 
-	if (mdp3_get_cont_spash_en())
-		mdp3_session->clk_on = 1;
-
 	mdp3_session->vsync_before_commit = true;
 init_done:
 	if (IS_ERR_VALUE(rc))
diff --git a/drivers/video/msm/mdss/mdp3_dma.c b/drivers/video/msm/mdss/mdp3_dma.c
index 3a2c94b..ae7598f 100644
--- a/drivers/video/msm/mdss/mdp3_dma.c
+++ b/drivers/video/msm/mdss/mdp3_dma.c
@@ -28,16 +28,22 @@
 {
 	struct mdp3_dma *dma = (struct mdp3_dma *)arg;
 	struct mdp3_vsync_notification vsync_client;
+	unsigned int wait_for_next_vs;
 
 	pr_debug("mdp3_vsync_intr_handler\n");
 	spin_lock(&dma->dma_lock);
 	vsync_client = dma->vsync_client;
-	complete(&dma->vsync_comp);
+	wait_for_next_vs = !dma->vsync_status;
+	dma->vsync_status = 0;
+	if (wait_for_next_vs)
+		complete(&dma->vsync_comp);
 	spin_unlock(&dma->dma_lock);
-	if (vsync_client.handler)
+	if (vsync_client.handler) {
 		vsync_client.handler(vsync_client.arg);
-	else
-		mdp3_irq_disable_nosync(type);
+	} else {
+		if (wait_for_next_vs)
+			mdp3_irq_disable_nosync(type);
+	}
 }
 
 static void mdp3_dma_done_intr_handler(int type, void *arg)
@@ -268,6 +274,23 @@
 	return 0;
 }
 
+static void mdp3_dma_stride_config(struct mdp3_dma *dma, int stride)
+{
+	struct mdp3_dma_source *source_config;
+	u32 dma_stride_offset;
+
+	if (dma->dma_sel == MDP3_DMA_P)
+		dma_stride_offset = MDP3_REG_DMA_P_IBUF_Y_STRIDE;
+	else
+		dma_stride_offset = MDP3_REG_DMA_S_IBUF_Y_STRIDE;
+
+	source_config = &dma->source_config;
+	source_config->stride = stride;
+	pr_debug("%s: Update the fb stride for DMA to %d", __func__,
+						(u32)source_config->stride);
+	MDP3_REG_WRITE(dma_stride_offset, source_config->stride);
+}
+
 static int mdp3_dmap_config(struct mdp3_dma *dma,
 			struct mdp3_dma_source *source_config,
 			struct mdp3_dma_output_config *output_config)
@@ -550,7 +573,9 @@
 		intf->start(intf);
 	}
 
-	wmb();
+	mb();
+	dma->vsync_status = MDP3_REG_READ(MDP3_REG_INTR_STATUS) &
+		(1 << MDP3_INTR_LCDC_START_OF_FRAME);
 	init_completion(&dma->vsync_comp);
 	spin_unlock_irqrestore(&dma->dma_lock, flag);
 
@@ -855,6 +880,7 @@
 		dma->vsync_enable = mdp3_dma_vsync_enable;
 		dma->start = mdp3_dma_start;
 		dma->stop = mdp3_dma_stop;
+		dma->config_stride = mdp3_dma_stride_config;
 		break;
 	case MDP3_DMA_S:
 		dma->dma_config = mdp3_dmas_config;
@@ -869,6 +895,7 @@
 		dma->vsync_enable = mdp3_dma_vsync_enable;
 		dma->start = mdp3_dma_start;
 		dma->stop = mdp3_dma_stop;
+		dma->config_stride = mdp3_dma_stride_config;
 		break;
 	case MDP3_DMA_E:
 	default:
diff --git a/drivers/video/msm/mdss/mdp3_dma.h b/drivers/video/msm/mdss/mdp3_dma.h
index 6983e55..6ad4c79 100644
--- a/drivers/video/msm/mdss/mdp3_dma.h
+++ b/drivers/video/msm/mdss/mdp3_dma.h
@@ -256,6 +256,7 @@
 	struct mdp3_dma_histogram_config histogram_config;
 	int histo_state;
 	struct mdp3_dma_histogram_data histo_data;
+	unsigned int vsync_status;
 
 	int (*dma_config)(struct mdp3_dma *dma,
 			struct mdp3_dma_source *source_config,
@@ -287,6 +288,8 @@
 
 	int (*histo_op)(struct mdp3_dma *dma, u32 op);
 
+	void (*config_stride)(struct mdp3_dma *dma, int stride);
+
 	void (*vsync_enable)(struct mdp3_dma *dma,
 			struct mdp3_vsync_notification *vsync_client);
 };
diff --git a/drivers/video/msm/mdss/mdp3_ppp.c b/drivers/video/msm/mdss/mdp3_ppp.c
index a64a6b4..d778af8 100644
--- a/drivers/video/msm/mdss/mdp3_ppp.c
+++ b/drivers/video/msm/mdss/mdp3_ppp.c
@@ -412,12 +412,47 @@
 	mdp3_ppp_kickoff();
 }
 
-static void mdp3_ppp_process_req(struct ppp_blit_op *blit_op,
+static int solid_fill_workaround(struct mdp_blit_req *req,
+						struct ppp_blit_op *blit_op)
+{
+	/* Make width 2 when there is a solid fill of width 1, and make
+	sure width does not become zero while trying to avoid odd width */
+	if (blit_op->dst.roi.width == 1) {
+		if (req->dst_rect.x + 2 > req->dst.width) {
+			pr_err("%s: Unable to handle solid fill of width 1",
+								__func__);
+			return -EINVAL;
+		}
+		blit_op->dst.roi.width = 2;
+	}
+	if (blit_op->src.roi.width == 1) {
+		if (req->src_rect.x + 2 > req->src.width) {
+			pr_err("%s: Unable to handle solid fill of width 1",
+								__func__);
+			return -EINVAL;
+		}
+		blit_op->src.roi.width = 2;
+	}
+
+	/* Avoid odd width, as it could hang ppp during solid fill */
+	blit_op->dst.roi.width = (blit_op->dst.roi.width / 2) * 2;
+	blit_op->src.roi.width = (blit_op->src.roi.width / 2) * 2;
+
+	/* Avoid RGBA format, as it could hang ppp during solid fill */
+	if (blit_op->src.color_fmt == MDP_RGBA_8888)
+		blit_op->src.color_fmt = MDP_RGBX_8888;
+	if (blit_op->dst.color_fmt == MDP_RGBA_8888)
+		blit_op->dst.color_fmt = MDP_RGBX_8888;
+	return 0;
+}
+
+static int mdp3_ppp_process_req(struct ppp_blit_op *blit_op,
 	struct mdp_blit_req *req, struct mdp3_img_data *src_data,
 	struct mdp3_img_data *dst_data)
 {
 	unsigned long srcp0_start, srcp0_len, dst_start, dst_len;
 	uint32_t dst_width, dst_height;
+	int ret = 0;
 
 	srcp0_start = (unsigned long) src_data->addr;
 	srcp0_len = (unsigned long) src_data->len;
@@ -510,24 +545,19 @@
 		blit_op->mdp_op |= MDPOP_ASCALE | MDPOP_BLUR;
 
 	if (req->flags & MDP_SOLID_FILL) {
-		blit_op->solid_fill = true;
+		ret = solid_fill_workaround(req, blit_op);
+		if (ret)
+			return ret;
 
-		/* Avoid odd width, as it could hang ppp during solid fill */
-		blit_op->dst.roi.width = (blit_op->dst.roi.width / 2) * 2;
-		blit_op->src.roi.width = (blit_op->src.roi.width / 2) * 2;
-
-		/* Avoid RGBA format, as it could hang ppp during solid fill */
-		if (blit_op->src.color_fmt == MDP_RGBA_8888)
-			blit_op->src.color_fmt = MDP_RGBX_8888;
-		if (blit_op->dst.color_fmt == MDP_RGBA_8888)
-			blit_op->dst.color_fmt = MDP_RGBX_8888;
 		blit_op->solid_fill_color = (req->const_color.g & 0xFF)|
 				(req->const_color.r & 0xFF) << 8 |
 				(req->const_color.b & 0xFF)  << 16 |
 				(req->const_color.alpha & 0xFF) << 24;
+		blit_op->solid_fill = true;
 	} else {
 		blit_op->solid_fill = false;
 	}
+	return ret;
 }
 
 static void mdp3_ppp_tile_workaround(struct ppp_blit_op *blit_op,
@@ -626,6 +656,7 @@
 	struct mdp3_img_data *dst_data)
 {
 	struct ppp_blit_op blit_op;
+	int ret = 0;
 
 	memset(&blit_op, 0, sizeof(blit_op));
 
@@ -639,7 +670,11 @@
 		return -EINVAL;
 	}
 
-	mdp3_ppp_process_req(&blit_op, req, src_data, dst_data);
+	ret = mdp3_ppp_process_req(&blit_op, req, src_data, dst_data);
+	if (ret) {
+		pr_err("%s: Failed to process the blit request", __func__);
+		return ret;
+	}
 
 	if (((blit_op.mdp_op & (MDPOP_TRANSP | MDPOP_ALPHAB)) ||
 	     (req->src.format == MDP_ARGB_8888) ||
diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c
index d33aefa..54c8a06 100644
--- a/drivers/video/msm/mdss/mdss_dsi.c
+++ b/drivers/video/msm/mdss/mdss_dsi.c
@@ -793,6 +793,21 @@
 	return rc;
 }
 
+static struct device_node *mdss_dsi_pref_prim_panel(
+		struct platform_device *pdev)
+{
+	struct device_node *dsi_pan_node = NULL;
+
+	pr_debug("%s:%d: Select primary panel from dt\n",
+					__func__, __LINE__);
+	dsi_pan_node = of_parse_phandle(pdev->dev.of_node,
+					"qcom,dsi-pref-prim-pan", 0);
+	if (!dsi_pan_node)
+		pr_err("%s:can't find panel phandle\n", __func__);
+
+	return dsi_pan_node;
+}
+
 /**
  * mdss_dsi_find_panel_of_node(): find device node of dsi panel
  * @pdev: platform_device of the dsi ctrl node
@@ -820,14 +835,7 @@
 		/* no panel cfg chg, parse dt */
 		pr_debug("%s:%d: no cmd line cfg present\n",
 			 __func__, __LINE__);
-		dsi_pan_node = of_parse_phandle(
-			pdev->dev.of_node,
-			"qcom,dsi-pref-prim-pan", 0);
-		if (!dsi_pan_node) {
-			pr_err("%s:can't find panel phandle\n",
-			       __func__);
-			return NULL;
-		}
+		dsi_pan_node = mdss_dsi_pref_prim_panel(pdev);
 	} else {
 		if (panel_cfg[0] == '0') {
 			pr_debug("%s:%d: DSI ctrl 1\n", __func__, __LINE__);
@@ -860,11 +868,12 @@
 		dsi_pan_node = of_find_node_by_name(mdss_node,
 						    panel_name);
 		if (!dsi_pan_node) {
-			pr_err("%s: invalid pan node\n",
+			pr_err("%s: invalid pan node, selecting prim panel\n",
 			       __func__);
-			return NULL;
+			dsi_pan_node = mdss_dsi_pref_prim_panel(pdev);
 		}
 	}
+
 	return dsi_pan_node;
 }
 
diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h
index d743c42..855ec6c 100644
--- a/drivers/video/msm/mdss/mdss_dsi.h
+++ b/drivers/video/msm/mdss/mdss_dsi.h
@@ -233,7 +233,7 @@
 	int (*off) (struct mdss_panel_data *pdata);
 	int (*partial_update_fnc) (struct mdss_panel_data *pdata);
 	int (*check_status) (struct mdss_dsi_ctrl_pdata *pdata);
-	void (*cmdlist_commit)(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp);
+	int (*cmdlist_commit)(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp);
 	struct mdss_panel_data panel_data;
 	unsigned char *ctrl_base;
 	int reg_size;
@@ -336,7 +336,7 @@
 void mdss_dsi_ctrl_init(struct mdss_dsi_ctrl_pdata *ctrl);
 void mdss_dsi_cmd_mdp_busy(struct mdss_dsi_ctrl_pdata *ctrl);
 void mdss_dsi_wait4video_done(struct mdss_dsi_ctrl_pdata *ctrl);
-void mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp);
+int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp);
 void mdss_dsi_cmdlist_kickoff(int intf);
 int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl);
 
diff --git a/drivers/video/msm/mdss/mdss_dsi_cmd.c b/drivers/video/msm/mdss/mdss_dsi_cmd.c
index 9a3e638..8fc1115c0 100644
--- a/drivers/video/msm/mdss/mdss_dsi_cmd.c
+++ b/drivers/video/msm/mdss/mdss_dsi_cmd.c
@@ -655,7 +655,7 @@
 {
 	struct dcs_cmd_req *req;
 	struct dcs_cmd_list *clist;
-	int ret = 0;
+	int ret = -EINVAL;
 
 	mutex_lock(&ctrl->cmd_mutex);
 	clist = &ctrl->cmdlist;
@@ -674,7 +674,6 @@
 	}
 	mutex_unlock(&ctrl->cmd_mutex);
 
-	ret++;
 	pr_debug("%s: tot=%d put=%d get=%d\n", __func__,
 		clist->tot, clist->put, clist->get);
 
@@ -682,7 +681,7 @@
 		if (!ctrl->cmdlist_commit)
 			pr_err("cmdlist_commit not implemented!\n");
 		else
-			ctrl->cmdlist_commit(ctrl, 0);
+			ret = ctrl->cmdlist_commit(ctrl, 0);
 	}
 	return ret;
 }
diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c
index 43065ec..65e6214 100644
--- a/drivers/video/msm/mdss/mdss_dsi_host.c
+++ b/drivers/video/msm/mdss/mdss_dsi_host.c
@@ -1147,44 +1147,63 @@
 		/* wait until DMA finishes the current job */
 		pr_debug("%s: pending pid=%d\n",
 				__func__, current->pid);
-		wait_for_completion(&ctrl->mdp_comp);
+		if (!wait_for_completion_timeout(&ctrl->mdp_comp,
+					msecs_to_jiffies(DMA_TX_TIMEOUT)))
+			pr_err("%s: timeout error\n", __func__);
 	}
 	pr_debug("%s: done pid=%d\n",
 				__func__, current->pid);
 }
 
-void mdss_dsi_cmdlist_tx(struct mdss_dsi_ctrl_pdata *ctrl,
+int mdss_dsi_cmdlist_tx(struct mdss_dsi_ctrl_pdata *ctrl,
 				struct dcs_cmd_req *req)
 {
-	int ret;
+	int ret, ret_val = -EINVAL;
 
 	ret = mdss_dsi_cmds_tx(ctrl, req->cmds, req->cmds_cnt);
 
+	if (!IS_ERR_VALUE(ret))
+		ret_val = 0;
+
 	if (req->cb)
 		req->cb(ret);
+
+	return ret_val;
 }
 
-void mdss_dsi_cmdlist_rx(struct mdss_dsi_ctrl_pdata *ctrl,
+int mdss_dsi_cmdlist_rx(struct mdss_dsi_ctrl_pdata *ctrl,
 				struct dcs_cmd_req *req)
 {
 	struct dsi_buf *rp;
-	int len = 0;
+	int len = 0, ret = -EINVAL;
 
 	if (req->rbuf) {
 		rp = &ctrl->rx_buf;
 		len = mdss_dsi_cmds_rx(ctrl, req->cmds, req->rlen);
 		memcpy(req->rbuf, rp->data, rp->len);
+		/*
+		 * For dual DSI cases, early return of controller - 0
+		 * is valid. Hence, for those cases the return value
+		 * is zero even though we don't send any commands.
+		 *
+		 */
+		if ((ctrl->shared_pdata.broadcast_enable &&
+			ctrl->ndx == DSI_CTRL_0) || (len != 0))
+			ret = 0;
 	} else {
 		pr_err("%s: No rx buffer provided\n", __func__);
 	}
 
 	if (req->cb)
 		req->cb(len);
+
+	return ret;
 }
 
-void mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
+int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
 {
 	struct dcs_cmd_req *req;
+	int ret = -EINVAL;
 
 	mutex_lock(&ctrl->cmd_mutex);
 	req = mdss_dsi_cmdlist_get(ctrl);
@@ -1209,9 +1228,9 @@
 	mdss_dsi_clk_ctrl(ctrl, 1);
 
 	if (req->flags & CMD_REQ_RX)
-		mdss_dsi_cmdlist_rx(ctrl, req);
+		ret = mdss_dsi_cmdlist_rx(ctrl, req);
 	else
-		mdss_dsi_cmdlist_tx(ctrl, req);
+		ret = mdss_dsi_cmdlist_tx(ctrl, req);
 
 	mdss_dsi_clk_ctrl(ctrl, 0);
 	mdss_bus_bandwidth_ctrl(0);
@@ -1222,6 +1241,7 @@
 		mdss_dsi_cmd_mdp_start(ctrl);
 
 	mutex_unlock(&ctrl->cmd_mutex);
+	return ret;
 }
 
 static void dsi_send_events(struct mdss_dsi_ctrl_pdata *ctrl, u32 events)
@@ -1311,6 +1331,8 @@
 
 	if (status) {
 		MIPI_OUTP(base + 0x0068, status);
+		/* Writing of an extra 0 needed to clear error bits */
+		MIPI_OUTP(base + 0x0068, 0);
 		pr_err("%s: status=%x\n", __func__, status);
 	}
 }
diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c
index f4d7b61..3c7d17c 100644
--- a/drivers/video/msm/mdss/mdss_dsi_panel.c
+++ b/drivers/video/msm/mdss/mdss_dsi_panel.c
@@ -19,7 +19,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/leds.h>
-#include <linux/pwm.h>
+#include <linux/qpnp/pwm.h>
 #include <linux/err.h>
 
 #include "mdss_dsi.h"
@@ -69,9 +69,9 @@
 		ctrl->pwm_enabled = 0;
 	}
 
-	ret = pwm_config(ctrl->pwm_bl, duty, ctrl->pwm_period);
+	ret = pwm_config_us(ctrl->pwm_bl, duty, ctrl->pwm_period);
 	if (ret) {
-		pr_err("%s: pwm_config() failed err=%d.\n", __func__, ret);
+		pr_err("%s: pwm_config_us() failed err=%d.\n", __func__, ret);
 		return;
 	}
 
@@ -422,7 +422,7 @@
 		if (dchdr->dlen > len) {
 			pr_err("%s: dtsi cmd=%x error, len=%d",
 				__func__, dchdr->dtype, dchdr->dlen);
-			return -ENOMEM;
+			goto exit_free;
 		}
 		bp += sizeof(*dchdr);
 		len -= sizeof(*dchdr);
@@ -434,14 +434,13 @@
 	if (len != 0) {
 		pr_err("%s: dcs_cmd=%x len=%d error!",
 				__func__, buf[0], blen);
-		kfree(buf);
-		return -ENOMEM;
+		goto exit_free;
 	}
 
 	pcmds->cmds = kzalloc(cnt * sizeof(struct dsi_cmd_desc),
 						GFP_KERNEL);
 	if (!pcmds->cmds)
-		return -ENOMEM;
+		goto exit_free;
 
 	pcmds->cmd_cnt = cnt;
 	pcmds->buf = buf;
@@ -460,7 +459,7 @@
 	}
 
 	data = of_get_property(np, link_key, NULL);
-	if (!strncmp(data, "dsi_hs_mode", 11))
+	if (data && !strcmp(data, "dsi_hs_mode"))
 		pcmds->link_state = DSI_HS_MODE;
 	else
 		pcmds->link_state = DSI_LP_MODE;
@@ -469,6 +468,10 @@
 		pcmds->buf[0], pcmds->blen, pcmds->cmd_cnt, pcmds->link_state);
 
 	return 0;
+
+exit_free:
+	kfree(buf);
+	return -ENOMEM;
 }
 
 
@@ -692,19 +695,24 @@
 	pdest = of_get_property(np,
 		"qcom,mdss-dsi-panel-destination", NULL);
 
-	if (strlen(pdest) != 9) {
-		pr_err("%s: Unknown pdest specified\n", __func__);
+	if (pdest) {
+		if (strlen(pdest) != 9) {
+			pr_err("%s: Unknown pdest specified\n", __func__);
+			return -EINVAL;
+		}
+		if (!strcmp(pdest, "display_1"))
+			pinfo->pdest = DISPLAY_1;
+		else if (!strcmp(pdest, "display_2"))
+			pinfo->pdest = DISPLAY_2;
+		else {
+			pr_debug("%s: pdest not specified. Set Default\n",
+								__func__);
+			pinfo->pdest = DISPLAY_1;
+		}
+	} else {
+		pr_err("%s: pdest not specified\n", __func__);
 		return -EINVAL;
 	}
-	if (!strncmp(pdest, "display_1", 9))
-		pinfo->pdest = DISPLAY_1;
-	else if (!strncmp(pdest, "display_2", 9))
-		pinfo->pdest = DISPLAY_2;
-	else {
-		pr_debug("%s: pdest not specified. Set Default\n",
-							__func__);
-		pinfo->pdest = DISPLAY_1;
-	}
 	rc = of_property_read_u32(np, "qcom,mdss-dsi-h-front-porch", &tmp);
 	pinfo->lcdc.h_front_porch = (!rc ? tmp : 6);
 	rc = of_property_read_u32(np, "qcom,mdss-dsi-h-back-porch", &tmp);
@@ -854,9 +862,9 @@
 		pinfo->mode_gpio_state = MODE_GPIO_NOT_VALID;
 	}
 
-	rc = of_property_read_u32(np, "qcom,mdss-dsi-panel-frame-rate", &tmp);
+	rc = of_property_read_u32(np, "qcom,mdss-dsi-panel-framerate", &tmp);
 	pinfo->mipi.frame_rate = (!rc ? tmp : 60);
-	rc = of_property_read_u32(np, "qcom,mdss-dsi-panel-clock-rate", &tmp);
+	rc = of_property_read_u32(np, "qcom,mdss-dsi-panel-clockrate", &tmp);
 	pinfo->clk_rate = (!rc ? tmp : 0);
 	data = of_get_property(np, "qcom,mdss-dsi-panel-timings", &len);
 	if ((!data) || (len != 12)) {
diff --git a/drivers/video/msm/mdss/mdss_edp.c b/drivers/video/msm/mdss/mdss_edp.c
index bb27e6b..6dbca10 100644
--- a/drivers/video/msm/mdss/mdss_edp.c
+++ b/drivers/video/msm/mdss/mdss_edp.c
@@ -23,7 +23,7 @@
 #include <linux/gpio.h>
 #include <linux/err.h>
 #include <linux/regulator/consumer.h>
-#include <linux/pwm.h>
+#include <linux/qpnp/pwm.h>
 #include <linux/clk.h>
 #include <linux/spinlock_types.h>
 #include <linux/kthread.h>
@@ -210,11 +210,11 @@
 		if (bl_level > bl_max)
 			bl_level = bl_max;
 
-		ret = pwm_config(edp_drv->bl_pwm,
+		ret = pwm_config_us(edp_drv->bl_pwm,
 				bl_level * edp_drv->pwm_period / bl_max,
 				edp_drv->pwm_period);
 		if (ret) {
-			pr_err("%s: pwm_config() failed err=%d.\n", __func__,
+			pr_err("%s: pwm_config_us() failed err=%d.\n", __func__,
 					ret);
 			return;
 		}
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 5408bc3..94b2cbd 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -1172,6 +1172,7 @@
 			pr_err("unable to start display thread %d\n",
 				mfd->index);
 			result = PTR_ERR(mfd->disp_thread);
+			mfd->disp_thread = NULL;
 			goto thread_error;
 		}
 
@@ -1191,6 +1192,7 @@
 
 blank_error:
 	kthread_stop(mfd->disp_thread);
+	mfd->disp_thread = NULL;
 
 thread_error:
 	if (pinfo && !pinfo->ref_cnt) {
@@ -1242,8 +1244,10 @@
 			pm_runtime_put(info->dev);
 		} while (release_all && pinfo->ref_cnt);
 
-		if (release_all)
+		if (release_all && mfd->disp_thread) {
 			kthread_stop(mfd->disp_thread);
+			mfd->disp_thread = NULL;
+		}
 
 		if (pinfo->ref_cnt == 0) {
 			list_del(&pinfo->list);
@@ -1281,7 +1285,10 @@
 	}
 
 	if (!mfd->ref_cnt) {
-		kthread_stop(mfd->disp_thread);
+		if (mfd->disp_thread) {
+			kthread_stop(mfd->disp_thread);
+			mfd->disp_thread = NULL;
+		}
 
 		ret = mdss_fb_blank_sub(FB_BLANK_POWERDOWN, info,
 			mfd->op_enable);
@@ -2180,6 +2187,7 @@
 	struct platform_device *fb_pdev, *mdss_pdev;
 	struct device_node *node;
 	int rc = 0;
+	bool master_panel = true;
 
 	if (!pdev || !pdev->dev.of_node) {
 		pr_err("Invalid device node\n");
@@ -2207,6 +2215,8 @@
 	fb_pdev = of_find_device_by_node(node);
 	if (fb_pdev) {
 		rc = mdss_fb_register_extra_panel(fb_pdev, pdata);
+		if (rc == 0)
+			master_panel = false;
 	} else {
 		pr_info("adding framebuffer device %s\n", dev_name(&pdev->dev));
 		fb_pdev = of_platform_device_create(node, NULL,
@@ -2214,7 +2224,7 @@
 		fb_pdev->dev.platform_data = pdata;
 	}
 
-	if (mdp_instance->panel_register_done)
+	if (master_panel && mdp_instance->panel_register_done)
 		mdp_instance->panel_register_done(pdata);
 
 mdss_notfound:
diff --git a/drivers/video/msm/mdss/mdss_hdmi_hdcp.c b/drivers/video/msm/mdss/mdss_hdmi_hdcp.c
index ca21b51..8ff9059 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_hdcp.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_hdcp.c
@@ -31,6 +31,8 @@
 #define HDCP_KEYS_STATE_PROD_AKSV	6
 #define HDCP_KEYS_STATE_RESERVED	7
 
+#define HDCP_INT_CLR (BIT(1) | BIT(5) | BIT(7) | BIT(9) | BIT(13))
+
 struct hdmi_hdcp_ctrl {
 	u32 auth_retries;
 	u32 tp_msgid;
@@ -1139,16 +1141,15 @@
 	}
 
 	/*
-	 * Need to set the state to inactive here so that any ongoing
-	 * reauth works will know that the HDCP session has been turned off
+	 * Disable HDCP interrupts.
+	 * Also, need to set the state to inactive here so that any ongoing
+	 * reauth works will know that the HDCP session has been turned off.
 	 */
 	mutex_lock(hdcp_ctrl->init_data.mutex);
+	DSS_REG_W(io, HDMI_HDCP_INT_CTRL, 0);
 	hdcp_ctrl->hdcp_state = HDCP_STATE_INACTIVE;
 	mutex_unlock(hdcp_ctrl->init_data.mutex);
 
-	/* Disable HDCP interrupts */
-	DSS_REG_W(io, HDMI_HDCP_INT_CTRL, 0);
-
 	/*
 	 * Cancel any pending auth/reauth attempts.
 	 * If one is ongoing, this will wait for it to finish.
@@ -1193,7 +1194,7 @@
 	if (HDCP_STATE_INACTIVE == hdcp_ctrl->hdcp_state) {
 		DEV_ERR("%s: HDCP inactive. Just clear int and return.\n",
 			__func__);
-		DSS_REG_W(io, HDMI_HDCP_INT_CTRL, hdcp_int_val);
+		DSS_REG_W(io, HDMI_HDCP_INT_CTRL, HDCP_INT_CLR);
 		return 0;
 	}
 
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index 4a51987..b45a446 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -1721,8 +1721,6 @@
 	} else {
 		msm_dss_enable_clk(power_data->clk_config,
 			power_data->num_clk, 0);
-		msm_dss_clk_set_rate(power_data->clk_config,
-			power_data->num_clk);
 		msm_dss_enable_gpio(power_data->gpio_config,
 			power_data->num_gpio, 0);
 		msm_dss_enable_vreg(power_data->vreg_config,
@@ -2479,12 +2477,6 @@
 
 	hdmi_tx_powerdown_phy(hdmi_ctrl);
 
-	/*
-	 * this is needed to avoid pll lock failure due to
-	 * clk framework's rate caching.
-	 */
-	hdmi_ctrl->pdata.power_data[HDMI_TX_CORE_PM].clk_config[0].rate = 0;
-
 	hdmi_cec_deconfig(hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC]);
 
 	hdmi_tx_core_off(hdmi_ctrl);
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index b218b1e..3269eec 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -1316,7 +1316,7 @@
 {
 	char *t = NULL;
 	char pan_intf_str[MDSS_MAX_PANEL_LEN];
-	int rc, i;
+	int rc, i, panel_len;
 	char pan_name[MDSS_MAX_PANEL_LEN];
 
 	if (!pan_cfg)
@@ -1353,6 +1353,14 @@
 	strlcpy(&pan_cfg->arg_cfg[0], t, sizeof(pan_cfg->arg_cfg));
 	pr_debug("%s:%d: t=[%s] panel name=[%s]\n", __func__, __LINE__,
 		t, pan_cfg->arg_cfg);
+
+	panel_len = strlen(pan_cfg->arg_cfg);
+	if (!panel_len) {
+		pr_err("%s: Panel name is invalid\n", __func__);
+		pan_cfg->pan_intf = MDSS_PANEL_INTF_INVALID;
+		return -EINVAL;
+	}
+
 	rc = mdss_mdp_get_pan_intf(pan_intf_str);
 	pan_cfg->pan_intf = (rc < 0) ?  MDSS_PANEL_INTF_INVALID : rc;
 	return 0;
@@ -1457,10 +1465,10 @@
 	of_node_put(chosen_node);
 
 	rc = mdss_mdp_get_pan_cfg(pan_cfg);
-	if (!rc)
+	if (!rc) {
 		pan_cfg->init_done = true;
-
-	return rc;
+		return rc;
+	}
 
 get_dt_pan:
 	rc = mdss_mdp_parse_dt_pan_intf(pdev);
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index 769f9b2..fad6b0c 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -289,6 +289,7 @@
 struct mdss_ad_info {
 	u8 num;
 	u8 calc_hw_num;
+	u32 ops;
 	u32 sts;
 	u32 reg_sts;
 	u32 state;
@@ -516,7 +517,7 @@
 int mdss_mdp_ctl_split_display_setup(struct mdss_mdp_ctl *ctl,
 		struct mdss_panel_data *pdata);
 int mdss_mdp_ctl_destroy(struct mdss_mdp_ctl *ctl);
-int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl);
+int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff);
 int mdss_mdp_ctl_stop(struct mdss_mdp_ctl *ctl);
 int mdss_mdp_ctl_intf_event(struct mdss_mdp_ctl *ctl, int event, void *arg);
 int mdss_mdp_perf_calc_pipe(struct mdss_mdp_pipe *pipe,
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 1fedd6e..f73b583 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -975,6 +975,8 @@
 
 	mixer->width = sctl->width;
 	mixer->height = sctl->height;
+	mixer->roi = (struct mdss_mdp_img_rect)
+				{0, 0, mixer->width, mixer->height};
 	sctl->mixer_left = mixer;
 
 	return mdss_mdp_set_split_ctl(ctl, sctl);
@@ -1060,26 +1062,34 @@
 	return rc;
 }
 
-static int mdss_mdp_ctl_start_sub(struct mdss_mdp_ctl *ctl)
+static int mdss_mdp_ctl_start_sub(struct mdss_mdp_ctl *ctl, bool handoff)
 {
 	struct mdss_mdp_mixer *mixer;
 	u32 outsize, temp;
 	int ret = 0;
 	int i, nmixers;
 
-	if (ctl->start_fnc)
-		ret = ctl->start_fnc(ctl);
-	else
-		pr_warn("no start function for ctl=%d type=%d\n", ctl->num,
-				ctl->panel_data->panel_info.type);
-
-	if (ret) {
-		pr_err("unable to start intf\n");
-		return ret;
-	}
-
 	pr_debug("ctl_num=%d\n", ctl->num);
 
+	/*
+	 * Need start_fnc in 2 cases:
+	 * (1) handoff
+	 * (2) continuous splash finished.
+	 */
+	if (handoff || !ctl->panel_data->panel_info.cont_splash_enabled) {
+		if (ctl->start_fnc)
+			ret = ctl->start_fnc(ctl);
+		else
+			pr_warn("no start function for ctl=%d type=%d\n",
+					ctl->num,
+					ctl->panel_data->panel_info.type);
+
+		if (ret) {
+			pr_err("unable to start intf\n");
+			return ret;
+		}
+	}
+
 	if (!ctl->panel_data->panel_info.cont_splash_enabled) {
 		nmixers = MDSS_MDP_INTF_MAX_LAYERMIXER +
 			MDSS_MDP_WB_MAX_LAYERMIXER;
@@ -1106,7 +1116,7 @@
 	return ret;
 }
 
-int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl)
+int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff)
 {
 	struct mdss_mdp_ctl *sctl;
 	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
@@ -1121,12 +1131,17 @@
 	if (ret)
 		return ret;
 
-
 	sctl = mdss_mdp_get_split_ctl(ctl);
 
 	mutex_lock(&ctl->lock);
 
-	ctl->power_on = true;
+	/*
+	 * keep power_on false during handoff to avoid unexpected
+	 * operations to overlay.
+	 */
+	if (!handoff)
+		ctl->power_on = true;
+
 	ctl->bus_ab_quota = 0;
 	ctl->bus_ib_quota = 0;
 	ctl->clk_rate = 0;
@@ -1139,10 +1154,10 @@
 		goto error;
 	}
 
-	ret = mdss_mdp_ctl_start_sub(ctl);
+	ret = mdss_mdp_ctl_start_sub(ctl, handoff);
 	if (ret == 0) {
 		if (sctl) { /* split display is available */
-			ret = mdss_mdp_ctl_start_sub(sctl);
+			ret = mdss_mdp_ctl_start_sub(sctl, handoff);
 			if (!ret)
 				mdss_mdp_ctl_split_display_enable(1, ctl, sctl);
 		} else if (ctl->mixer_right) {
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
index 1d302db..c4a0645 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
@@ -514,14 +514,14 @@
 
 	mdss_mdp_cmd_set_partial_roi(ctl);
 
+	mdss_mdp_cmd_clk_on(ctx);
+
 	/*
 	 * tx dcs command if had any
 	 */
 	mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_DSI_CMDLIST_KOFF,
 						(void *)&ctx->recovery);
 
-	mdss_mdp_cmd_clk_on(ctx);
-
 	INIT_COMPLETION(ctx->pp_comp);
 	mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num);
 	mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_START, 1);
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 14b486a..4c89064 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -859,7 +859,7 @@
 		mdss_hw_init(mdss_res);
 	}
 
-	rc = mdss_mdp_ctl_start(ctl);
+	rc = mdss_mdp_ctl_start(ctl, false);
 	if (rc == 0) {
 		atomic_inc(&ov_active_panels);
 
@@ -1580,8 +1580,8 @@
 		return -ENODEV;
 	if (!ctl->add_vsync_handler || !ctl->remove_vsync_handler)
 		return -EOPNOTSUPP;
-
-	if (!ctl->power_on) {
+	if (!ctl->panel_data->panel_info.cont_splash_enabled
+			&& !ctl->power_on) {
 		pr_debug("fb%d vsync pending first update en=%d\n",
 				mfd->index, en);
 		return -EPERM;
@@ -1698,7 +1698,9 @@
 	u64 vsync_ticks;
 	int ret;
 
-	if (!mdp5_data->ctl || !mdp5_data->ctl->power_on)
+	if (!mdp5_data->ctl ||
+		(!mdp5_data->ctl->panel_data->panel_info.cont_splash_enabled
+			&& !mdp5_data->ctl->power_on))
 		return -EAGAIN;
 
 	vsync_ticks = ktime_to_ns(mdp5_data->vsync_time);
@@ -2535,9 +2537,15 @@
 		mdp5_data->ctl = ctl;
 	}
 
-	rc = mdss_mdp_ctl_setup(ctl);
-	if (rc)
+	/*
+	 * vsync interrupt needs on during continuous splash, this is
+	 * to initialize necessary ctl members here.
+	 */
+	rc = mdss_mdp_ctl_start(ctl, true);
+	if (rc) {
+		pr_err("Failed to initialize ctl\n");
 		goto error;
+	}
 
 	ctl->clk_rate = mdss_mdp_get_clk_rate(MDSS_CLK_MDP_SRC);
 	pr_debug("Set the ctl clock rate to %d Hz\n", ctl->clk_rate);
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index 0dc61d0..d0d2157 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -205,6 +205,10 @@
 
 #define PP_AD_BAD_HW_NUM 255
 
+#define MDSS_SIDE_NONE	0
+#define MDSS_SIDE_LEFT	1
+#define MDSS_SIDE_RIGHT	2
+
 #define PP_AD_STATE_INIT	0x2
 #define PP_AD_STATE_CFG		0x4
 #define PP_AD_STATE_DATA	0x8
@@ -293,15 +297,15 @@
 	struct mdp_gamut_cfg_data gamut_disp_cfg[MDSS_BLOCK_DISP_NUM];
 	uint16_t gamut_tbl[MDSS_BLOCK_DISP_NUM][GAMUT_TOTAL_TABLE_SIZE];
 	u32 hist_data[MDSS_BLOCK_DISP_NUM][HIST_V_SIZE];
-	/* physical info */
 	struct pp_sts_type pp_disp_sts[MDSS_BLOCK_DISP_NUM];
+	/* physical info */
 	struct pp_hist_col_info dspp_hist[MDSS_MDP_MAX_DSPP];
 };
 
 static DEFINE_MUTEX(mdss_pp_mutex);
 static struct mdss_pp_res_type *mdss_pp_res;
 
-static void pp_hist_read(char __iomem *v_addr,
+static u32 pp_hist_read(char __iomem *v_addr,
 				struct pp_hist_col_info *hist_info);
 static int pp_histogram_setup(u32 *op, u32 block, struct mdss_mdp_mixer *mix);
 static int pp_histogram_disable(struct pp_hist_col_info *hist_info,
@@ -340,8 +344,9 @@
 static void pp_dither_config(char __iomem *addr,
 				struct pp_sts_type *pp_sts,
 				struct mdp_dither_cfg_data *dither_cfg);
-static void pp_dspp_opmode_config(struct pp_sts_type *pp_sts, u32 *opmode,
-				int mdp_rev);
+static void pp_dspp_opmode_config(struct mdss_mdp_ctl *ctl, u32 num,
+					struct pp_sts_type *pp_sts, int mdp_rev,
+					u32 *opmode);
 static void pp_sharp_config(char __iomem *addr,
 				struct pp_sts_type *pp_sts,
 				struct mdp_sharp_cfg *sharp_config);
@@ -375,11 +380,15 @@
 			struct mdss_ad_info *ad, struct mdss_mdp_ctl *ctl);
 static void pp_ad_input_write(struct mdss_mdp_ad *ad_hw,
 						struct mdss_ad_info *ad);
-static void pp_ad_bypass_config(struct mdss_ad_info *ad, u32 *opmode);
 static int pp_ad_setup_hw_nums(struct msm_fb_data_type *mfd,
 						struct mdss_ad_info *ad);
+static void pp_ad_bypass_config(struct mdss_ad_info *ad,
+				struct mdss_mdp_ctl *ctl, u32 num, u32 *opmode);
 static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd);
 static void pp_ad_cfg_lut(char __iomem *addr, u32 *data);
+static int pp_num_to_side(struct mdss_mdp_ctl *ctl, u32 num);
+static inline bool pp_sts_is_enabled(u32 sts, int side);
+static inline void pp_sts_set_split_bits(u32 *sts, u32 bits);
 
 static u32 last_sts, last_state;
 
@@ -511,6 +520,7 @@
 		pp_sts->gamut_sts &= ~PP_STS_ENABLE;
 	else if (gamut_cfg->flags & MDP_PP_OPS_ENABLE)
 		pp_sts->gamut_sts |= PP_STS_ENABLE;
+	pp_sts_set_split_bits(&pp_sts->gamut_sts, gamut_cfg->flags);
 }
 
 static void pp_pa_config(unsigned long flags, char __iomem *addr,
@@ -679,6 +689,7 @@
 	if (pa_v2_config->flags & MDP_PP_PA_SIX_ZONE_VAL_MASK)
 		pp_sts->pa_sts |= PP_STS_PA_SIX_ZONE_VAL_MASK;
 
+	pp_sts_set_split_bits(&pp_sts->pa_sts, pa_v2_config->flags);
 }
 
 static void pp_pcc_config(unsigned long flags, char __iomem *addr,
@@ -693,6 +704,7 @@
 			pp_sts->pcc_sts &= ~PP_STS_ENABLE;
 		else if (pcc_config->ops & MDP_PP_OPS_ENABLE)
 			pp_sts->pcc_sts |= PP_STS_ENABLE;
+		pp_sts_set_split_bits(&pp_sts->pcc_sts, pcc_config->ops);
 	}
 }
 
@@ -720,6 +732,7 @@
 			pp_sts->igc_sts &= ~PP_STS_ENABLE;
 		else if (igc_config->ops & MDP_PP_OPS_ENABLE)
 			pp_sts->igc_sts |= PP_STS_ENABLE;
+		pp_sts_set_split_bits(&pp_sts->igc_sts, igc_config->ops);
 	}
 }
 
@@ -1324,12 +1337,20 @@
 		pp_sts->dither_sts &= ~PP_STS_ENABLE;
 	else if (dither_cfg->flags & MDP_PP_OPS_ENABLE)
 		pp_sts->dither_sts |= PP_STS_ENABLE;
+	pp_sts_set_split_bits(&pp_sts->dither_sts, dither_cfg->flags);
 }
 
-static void pp_dspp_opmode_config(struct pp_sts_type *pp_sts, u32 *opmode,
-			int mdp_rev)
+static void pp_dspp_opmode_config(struct mdss_mdp_ctl *ctl, u32 num,
+					struct pp_sts_type *pp_sts, int mdp_rev,
+					u32 *opmode)
 {
-	if (pp_sts->pa_sts & PP_STS_ENABLE)
+	int side;
+	side = pp_num_to_side(ctl, num);
+
+	if (side < 0)
+		return;
+
+	if (pp_sts_is_enabled(pp_sts->pa_sts, side))
 		*opmode |= MDSS_MDP_DSPP_OP_PA_EN; /* PA_EN */
 	if (mdp_rev >= MDSS_MDP_HW_REV_103) {
 		if (pp_sts->pa_sts & PP_STS_PA_HUE_MASK)
@@ -1357,10 +1378,10 @@
 		if (pp_sts->pa_sts & PP_STS_PA_SIX_ZONE_VAL_MASK)
 			*opmode |= MDSS_MDP_DSPP_OP_PA_SIX_ZONE_VAL_MASK;
 	}
-	if (pp_sts->pcc_sts & PP_STS_ENABLE)
+	if (pp_sts_is_enabled(pp_sts->pcc_sts, side))
 		*opmode |= MDSS_MDP_DSPP_OP_PCC_EN; /* PCC_EN */
 
-	if (pp_sts->igc_sts & PP_STS_ENABLE) {
+	if (pp_sts_is_enabled(pp_sts->igc_sts, side)) {
 		*opmode |= MDSS_MDP_DSPP_OP_IGC_LUT_EN | /* IGC_LUT_EN */
 			      (pp_sts->igc_tbl_idx << 1);
 	}
@@ -1368,14 +1389,14 @@
 		*opmode |= MDSS_MDP_DSPP_OP_HIST_LUTV_EN | /* HIST_LUT_EN */
 				  MDSS_MDP_DSPP_OP_PA_EN; /* PA_EN */
 	}
-	if (pp_sts->dither_sts & PP_STS_ENABLE)
+	if (pp_sts_is_enabled(pp_sts->dither_sts, side))
 		*opmode |= MDSS_MDP_DSPP_OP_DST_DITHER_EN; /* DITHER_EN */
-	if (pp_sts->gamut_sts & PP_STS_ENABLE) {
+	if (pp_sts_is_enabled(pp_sts->gamut_sts, side)) {
 		*opmode |= MDSS_MDP_DSPP_OP_GAMUT_EN; /* GAMUT_EN */
 		if (pp_sts->gamut_sts & PP_STS_GAMUT_FIRST)
 			*opmode |= MDSS_MDP_DSPP_OP_GAMUT_PCC_ORDER;
 	}
-	if (pp_sts->pgc_sts & PP_STS_ENABLE)
+	if (pp_sts_is_enabled(pp_sts->pgc_sts, side))
 		*opmode |= MDSS_MDP_DSPP_OP_ARGC_LUT_EN;
 }
 
@@ -1481,6 +1502,7 @@
 			pp_sts->pgc_sts &= ~PP_STS_ENABLE;
 		else if (pgc_config->flags & MDP_PP_OPS_ENABLE)
 			pp_sts->pgc_sts |= PP_STS_ENABLE;
+		pp_sts_set_split_bits(&pp_sts->pgc_sts, pgc_config->flags);
 	}
 
 	if (ad_hw) {
@@ -1492,12 +1514,12 @@
 			pp_ad_init_write(ad_hw, ad, ctl);
 		if (ad_flags & PP_AD_STS_DIRTY_CFG)
 			pp_ad_cfg_write(ad_hw, ad);
-		pp_ad_bypass_config(ad, &ad_bypass);
+		pp_ad_bypass_config(ad, ctl, ad_hw->num, &ad_bypass);
 		writel_relaxed(ad_bypass, ad_hw->base);
 		mutex_unlock(&ad->lock);
 	}
 
-	pp_dspp_opmode_config(pp_sts, &opmode, mdata->mdp_rev);
+	pp_dspp_opmode_config(ctl, dspp_num, pp_sts, mdata->mdp_rev, &opmode);
 flush_exit:
 	writel_relaxed(opmode, base + MDSS_MDP_REG_DSPP_OP_MODE);
 	ctl->flush_bits |= BIT(13 + dspp_num);
@@ -1836,6 +1858,12 @@
 		(config->block >= MDP_BLOCK_MAX))
 		return -EINVAL;
 
+	if ((config->pa_v2_data.flags & MDSS_PP_SPLIT_MASK) ==
+							MDSS_PP_SPLIT_MASK) {
+		pr_warn("Can't set both split bits\n");
+		return -EINVAL;
+	}
+
 	mutex_lock(&mdss_pp_mutex);
 	disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
 
@@ -2119,6 +2147,11 @@
 		(config->block >= MDP_BLOCK_MAX))
 		return -EINVAL;
 
+	if ((config->ops & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) {
+		pr_warn("Can't set both split bits\n");
+		return -EINVAL;
+	}
+
 	mutex_lock(&mdss_pp_mutex);
 	disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
 
@@ -2238,6 +2271,11 @@
 	if (config->len != IGC_LUT_ENTRIES)
 		return -EINVAL;
 
+	if ((config->ops & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) {
+		pr_warn("Can't set both split bits\n");
+		return -EINVAL;
+	}
+
 	mutex_lock(&mdss_pp_mutex);
 	disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
 
@@ -2437,6 +2475,11 @@
 		(PP_BLOCK(config->block) >= MDP_BLOCK_MAX))
 		return -EINVAL;
 
+	if ((config->flags & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) {
+		pr_warn("Can't set both split bits\n");
+		return -EINVAL;
+	}
+
 	mutex_lock(&mdss_pp_mutex);
 
 	disp_num = PP_BLOCK(config->block) - MDP_LOGICAL_BLOCK_DISP_0;
@@ -2608,6 +2651,11 @@
 	if (config->flags & MDP_PP_OPS_READ)
 		return -ENOTSUPP;
 
+	if ((config->flags & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) {
+		pr_warn("Can't set both split bits\n");
+		return -EINVAL;
+	}
+
 	mutex_lock(&mdss_pp_mutex);
 	disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
 	mdss_pp_res->dither_disp_cfg[disp_num] = *config;
@@ -2657,6 +2705,11 @@
 	if (pp_gm_has_invalid_lut_size(config))
 		return -EINVAL;
 
+	if ((config->flags & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) {
+		pr_warn("Can't set both split bits\n");
+		return -EINVAL;
+	}
+
 	mutex_lock(&mdss_pp_mutex);
 	disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
 
@@ -2773,19 +2826,27 @@
 	mutex_unlock(&mdss_pp_mutex);
 	return ret;
 }
-static void pp_hist_read(char __iomem *v_addr,
+
+static u32 pp_hist_read(char __iomem *v_addr,
 				struct pp_hist_col_info *hist_info)
 {
 	int i, i_start;
+	u32 sum = 0;
 	u32 data;
 	data = readl_relaxed(v_addr);
 	i_start = data >> 24;
 	hist_info->data[i_start] = data & 0xFFFFFF;
-	for (i = i_start + 1; i < HIST_V_SIZE; i++)
+	sum += hist_info->data[i_start];
+	for (i = i_start + 1; i < HIST_V_SIZE; i++) {
 		hist_info->data[i] = readl_relaxed(v_addr) & 0xFFFFFF;
-	for (i = 0; i < i_start - 1; i++)
+		sum += hist_info->data[i];
+	}
+	for (i = 0; i < i_start; i++) {
 		hist_info->data[i] = readl_relaxed(v_addr) & 0xFFFFFF;
+		sum += hist_info->data[i];
+	}
 	hist_info->hist_cnt_read++;
+	return sum;
 }
 
 /* Assumes that relevant clocks are enabled */
@@ -3168,10 +3229,10 @@
 
 static int pp_hist_collect(struct mdp_histogram_data *hist,
 				struct pp_hist_col_info *hist_info,
-				char __iomem *ctl_base)
+				char __iomem *ctl_base, u32 expect_sum)
 {
 	int wait_ret, ret = 0;
-	u32 timeout;
+	u32 timeout, sum;
 	char __iomem *v_base;
 	unsigned long flag;
 	struct mdss_pipe_pp_res *res;
@@ -3238,10 +3299,13 @@
 		spin_unlock_irqrestore(&hist_info->hist_lock, flag);
 		v_base = ctl_base + 0x1C;
 		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
-		pp_hist_read(v_base, hist_info);
+		sum = pp_hist_read(v_base, hist_info);
 		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
 		spin_lock_irqsave(&hist_info->hist_lock, flag);
-		hist_info->read_request = false;
+		if (!expect_sum || sum == expect_sum)
+			hist_info->read_request = false;
+		else
+			ret = -ENODATA;
 		hist_info->col_state = HIST_IDLE;
 	}
 	spin_unlock_irqrestore(&hist_info->hist_lock, flag);
@@ -3261,6 +3325,7 @@
 	u32 *hist_data_addr;
 	u32 pipe_cnt = 0;
 	u32 pipe_num = MDSS_MDP_SSPP_VIG0;
+	u32 exp_sum = 0;
 	struct mdss_mdp_pipe *pipe;
 	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
 
@@ -3290,7 +3355,10 @@
 			hist_info = &mdss_pp_res->dspp_hist[dspp_num];
 			ctl_base = mdss_mdp_get_dspp_addr_off(dspp_num) +
 				MDSS_MDP_REG_DSPP_HIST_CTL_BASE;
-			ret = pp_hist_collect(hist, hist_info, ctl_base);
+			exp_sum = (mdata->mixer_intf[dspp_num].width *
+					mdata->mixer_intf[dspp_num].height);
+			ret = pp_hist_collect(hist, hist_info, ctl_base,
+								exp_sum);
 			if (ret)
 				goto hist_collect_exit;
 		}
@@ -3359,7 +3427,8 @@
 			hist_info = &pipe->pp_res.hist;
 			ctl_base = pipe->base +
 				MDSS_MDP_REG_VIG_HIST_CTL_BASE;
-			ret = pp_hist_collect(hist, hist_info, ctl_base);
+			ret = pp_hist_collect(hist, hist_info, ctl_base,
+								exp_sum);
 			mdss_mdp_pipe_unmap(pipe);
 			if (ret)
 				goto hist_collect_exit;
@@ -3490,6 +3559,53 @@
 	return out;
 }
 
+static int pp_num_to_side(struct mdss_mdp_ctl *ctl, u32 num)
+{
+	u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];
+	u32 mixer_num;
+
+	if (!ctl || !ctl->mfd)
+		return -EINVAL;
+	mixer_num = mdss_mdp_get_ctl_mixers(ctl->mfd->index, mixer_id);
+	if (mixer_num < 2)
+		return MDSS_SIDE_NONE;
+	else if (mixer_id[1] == num)
+		return MDSS_SIDE_RIGHT;
+	else if (mixer_id[0] == num)
+		return MDSS_SIDE_LEFT;
+	else
+		pr_err("invalid, not on any side");
+	return -EINVAL;
+}
+
+static inline void pp_sts_set_split_bits(u32 *sts, u32 bits)
+{
+	u32 tmp = *sts;
+	tmp &= ~MDSS_PP_SPLIT_MASK;
+	tmp |= bits & MDSS_PP_SPLIT_MASK;
+	*sts = tmp;
+}
+
+static inline bool pp_sts_is_enabled(u32 sts, int side)
+{
+	bool ret = false;
+	/*
+	 * If there are no sides, or if there are no split mode bits set, the
+	 * side can't be disabled via split mode.
+	 *
+	 * Otherwise, if the side being checked opposes the split mode
+	 * configuration, the side is disabled.
+	 */
+	if ((side == MDSS_SIDE_NONE) || !(sts & MDSS_PP_SPLIT_MASK))
+		ret = true;
+	else if ((sts & MDSS_PP_SPLIT_RIGHT_ONLY) && (side == MDSS_SIDE_RIGHT))
+		ret = true;
+	else if ((sts & MDSS_PP_SPLIT_LEFT_ONLY) && (side == MDSS_SIDE_LEFT))
+		ret = true;
+
+	return ret && (sts & PP_STS_ENABLE);
+}
+
 static int mdss_ad_init_checks(struct msm_fb_data_type *mfd)
 {
 	u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];
@@ -3586,7 +3702,7 @@
 	struct mdss_mdp_ctl *ctl;
 	struct msm_fb_data_type *bl_mfd;
 	int lin_ret = -1, inv_ret = -1, ret = 0;
-	u32 ratio_temp, shift = 0;
+	u32 ratio_temp, shift = 0, last_ops;
 
 	ret = mdss_mdp_get_ad(mfd, &ad);
 	if (ret)
@@ -3599,6 +3715,11 @@
 		bl_mfd = mfd;
 	}
 
+	if ((init_cfg->ops & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) {
+		pr_warn("Can't set both split bits\n");
+		return -EINVAL;
+	}
+
 	mutex_lock(&ad->lock);
 	if (init_cfg->ops & MDP_PP_AD_INIT) {
 		memcpy(&ad->init, &init_cfg->params.init,
@@ -3638,6 +3759,22 @@
 		ad->sts |= PP_AD_STS_DIRTY_CFG;
 	}
 
+	last_ops = ad->ops & MDSS_PP_SPLIT_MASK;
+	ad->ops = init_cfg->ops & MDSS_PP_SPLIT_MASK;
+	/*
+	 *  if there is a change in the split mode config, the init values
+	 *  need to be re-written to hardware (if they have already been
+	 *  written or if there is data pending to be written). Check for
+	 *  pending data (DIRTY_INIT) is not checked here since it will not
+	 *  affect the outcome of this conditional (i.e. if init hasn't
+	 *  already been written (*_STATE_INIT is set), this conditional will
+	 *  only evaluate to true (and set the DIRTY bit) if the DIRTY bit has
+	 *  already been set).
+	 */
+	if ((last_ops ^ ad->ops) && (ad->state & PP_AD_STATE_INIT))
+		ad->sts |= PP_AD_STS_DIRTY_INIT;
+
+
 	if (!ret && (init_cfg->ops & MDP_PP_OPS_DISABLE)) {
 		ad->sts &= ~PP_STS_ENABLE;
 		mutex_unlock(&ad->lock);
@@ -3792,8 +3929,9 @@
 	u32 temp;
 	u32 frame_start, frame_end, procs_start, procs_end, tile_ctrl;
 	u32 num;
+	int side;
 	char __iomem *base;
-	bool is_calc, is_dual_pipe;
+	bool is_calc, is_dual_pipe, split_mode;
 	u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];
 	u32 mixer_num;
 	mixer_num = mdss_mdp_get_ctl_mixers(ctl->mfd->index, mixer_id);
@@ -3804,6 +3942,7 @@
 
 	base = ad_hw->base;
 	is_calc = ad->calc_hw_num == ad_hw->num;
+	split_mode = !!(ad->ops & MDSS_PP_SPLIT_MASK);
 
 	writel_relaxed(ad->init.i_control[0] & 0x1F,
 				base + MDSS_MDP_REG_AD_CON_CTRL_0);
@@ -3829,7 +3968,10 @@
 	writel_relaxed(ad->init.format, base + MDSS_MDP_REG_AD_CTRL_0);
 	writel_relaxed(ad->init.auto_size, base + MDSS_MDP_REG_AD_CTRL_1);
 
-	temp = ad->init.frame_w << 16;
+	if (split_mode)
+		temp = mdata->mixer_intf[ad_hw->num].width << 16;
+	else
+		temp = ad->init.frame_w << 16;
 	temp |= ad->init.frame_h & 0xFFFF;
 	writel_relaxed(temp, base + MDSS_MDP_REG_AD_FRAME_SIZE);
 
@@ -3841,17 +3983,26 @@
 	pp_ad_cfg_lut(base + MDSS_MDP_REG_AD_LUT_CC, ad->init.color_corr_lut);
 
 	if (mdata->mdp_rev >= MDSS_MDP_HW_REV_103) {
-		if (is_dual_pipe) {
+		if (is_dual_pipe && !split_mode) {
 			num = ad_hw->num;
+			side = pp_num_to_side(ctl, num);
 			tile_ctrl = 0x5;
-			if (is_calc) {
+			if ((ad->calc_hw_num + 1) == num)
+				tile_ctrl |= 0x10;
+
+			if (side <= MDSS_SIDE_NONE) {
+				WARN(1, "error finding sides, %d", side);
+				frame_start = 0;
+				procs_start = frame_start;
+				frame_end = 0;
+				procs_end = frame_end;
+			} else if (side == MDSS_SIDE_LEFT) {
 				frame_start = 0;
 				procs_start = 0;
 				frame_end = mdata->mixer_intf[num].width +
 							MDSS_AD_MERGED_WIDTH;
 				procs_end = mdata->mixer_intf[num].width;
 			} else {
-				tile_ctrl |= 0x10;
 				procs_start = ad->init.frame_w -
 					(mdata->mixer_intf[num].width);
 				procs_end = ad->init.frame_w;
@@ -3866,8 +4017,13 @@
 			frame_end = 0xFFFF;
 			procs_start = 0x0;
 			procs_end = 0xFFFF;
-			tile_ctrl = 0x1;
+			if (split_mode)
+				tile_ctrl = 0x0;
+			else
+				tile_ctrl = 0x1;
 		}
+
+
 		writel_relaxed(frame_start, base + MDSS_MDP_REG_AD_FRAME_START);
 		writel_relaxed(frame_end, base + MDSS_MDP_REG_AD_FRAME_END);
 		writel_relaxed(procs_start, base + MDSS_MDP_REG_AD_PROCS_START);
@@ -3931,12 +4087,17 @@
 }
 
 #define MDSS_PP_AD_BYPASS_DEF 0x101
-static void pp_ad_bypass_config(struct mdss_ad_info *ad, u32 *opmode)
+static void pp_ad_bypass_config(struct mdss_ad_info *ad,
+				struct mdss_mdp_ctl *ctl, u32 num, u32 *opmode)
 {
-	if (ad->reg_sts & PP_STS_ENABLE)
+	int side = pp_num_to_side(ctl, num);
+
+	if (pp_sts_is_enabled(ad->reg_sts | (ad->ops & MDSS_PP_SPLIT_MASK),
+								side)) {
 		*opmode = 0;
-	else
+	} else {
 		*opmode = MDSS_PP_AD_BYPASS_DEF;
+	}
 }
 
 static int pp_ad_setup_hw_nums(struct msm_fb_data_type *mfd,
@@ -3951,6 +4112,8 @@
 
 	/* default to left mixer */
 	ad->calc_hw_num = mixer_id[0];
+	if ((mixer_num > 1) && (ad->ops & MDSS_PP_SPLIT_RIGHT_ONLY))
+		ad->calc_hw_num = mixer_id[1];
 	return 0;
 }
 
@@ -4258,6 +4421,7 @@
 		mdata->ad_off[i].base = mdata->mdp_base + ad_offsets[i];
 		mdata->ad_off[i].num = i;
 		mdata->ad_cfgs[i].num = i;
+		mdata->ad_cfgs[i].ops = 0;
 		mdata->ad_cfgs[i].reg_sts = 0;
 		mdata->ad_cfgs[i].calc_itr = 0;
 		mdata->ad_cfgs[i].last_str = 0xFFFFFFFF;
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
old mode 100644
new mode 100755
index f66a034..4640d3b
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -99,7 +99,6 @@
 header-y += connector.h
 header-y += const.h
 header-y += cramfs_fs.h
-header-y += csdio.h
 header-y += cuda.h
 header-y += cyclades.h
 header-y += cycx_cfm.h
@@ -325,6 +324,7 @@
 header-y += ptrace.h
 header-y += qnx4_fs.h
 header-y += qnxtypes.h
+header-y += qrng.h
 header-y += quota.h
 header-y += radeonfb.h
 header-y += random.h
@@ -453,3 +453,4 @@
 header-y += msm_audio_amrwbplus.h
 header-y += avtimer.h
 header-y += msm_ipa.h
+header-y += msm_thermal_ioctl.h
diff --git a/include/linux/csdio.h b/include/linux/csdio.h
deleted file mode 100644
index 260c49d..0000000
--- a/include/linux/csdio.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef CSDIO_H
-#define CSDIO_H
-
-#include <linux/ioctl.h>
-
-#define CSDIO_IOC_MAGIC  'm'
-
-#define CSDIO_IOC_ENABLE_HIGHSPEED_MODE      _IO(CSDIO_IOC_MAGIC, 0)
-#define CSDIO_IOC_SET_DATA_TRANSFER_CLOCKS   _IO(CSDIO_IOC_MAGIC, 1)
-#define CSDIO_IOC_SET_OP_CODE                _IO(CSDIO_IOC_MAGIC, 2)
-#define CSDIO_IOC_FUNCTION_SET_BLOCK_SIZE    _IO(CSDIO_IOC_MAGIC, 3)
-#define CSDIO_IOC_SET_BLOCK_MODE             _IO(CSDIO_IOC_MAGIC, 4)
-#define CSDIO_IOC_CONNECT_ISR                _IO(CSDIO_IOC_MAGIC, 5)
-#define CSDIO_IOC_DISCONNECT_ISR             _IO(CSDIO_IOC_MAGIC, 6)
-#define CSDIO_IOC_CMD52                      _IO(CSDIO_IOC_MAGIC, 7)
-#define CSDIO_IOC_CMD53                      _IO(CSDIO_IOC_MAGIC, 8)
-#define CSDIO_IOC_ENABLE_ISR                 _IO(CSDIO_IOC_MAGIC, 9)
-#define CSDIO_IOC_DISABLE_ISR                _IO(CSDIO_IOC_MAGIC, 10)
-#define CSDIO_IOC_SET_VDD                    _IO(CSDIO_IOC_MAGIC, 11)
-#define CSDIO_IOC_GET_VDD                    _IO(CSDIO_IOC_MAGIC, 12)
-
-#define CSDIO_IOC_MAXNR   12
-
-struct csdio_cmd53_ctrl_t {
-	uint32_t    m_block_mode;   /* data tran. byte(0)/block(1) mode */
-	uint32_t    m_op_code;      /* address auto increment flag */
-	uint32_t    m_address;
-} __attribute__ ((packed));
-
-struct csdio_cmd52_ctrl_t {
-	uint32_t    m_write;
-	uint32_t    m_address;
-	uint32_t    m_data;
-	uint32_t    m_ret;
-} __attribute__ ((packed));
-
-#endif
diff --git a/include/linux/ion.h b/include/linux/ion.h
index f36298b..7131da3 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -22,6 +22,8 @@
 #include <linux/types.h>
 
 struct ion_handle;
+typedef struct ion_handle *ion_user_handle_t;
+
 /**
  * enum ion_heap_types - list of all possible types of heaps
  * @ION_HEAP_TYPE_SYSTEM:	 memory allocated via vmalloc
@@ -350,7 +352,7 @@
 	size_t align;
 	unsigned int heap_mask;
 	unsigned int flags;
-	struct ion_handle *handle;
+	ion_user_handle_t handle;
 };
 
 /**
@@ -364,7 +366,7 @@
  * provides the file descriptor and the kernel returns the handle.
  */
 struct ion_fd_data {
-	struct ion_handle *handle;
+	ion_user_handle_t handle;
 	int fd;
 };
 
@@ -373,7 +375,7 @@
  * @handle:	a handle
  */
 struct ion_handle_data {
-	struct ion_handle *handle;
+	ion_user_handle_t handle;
 };
 
 /**
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 1bcfd28..43aebb5 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -392,7 +392,7 @@
 	unsigned int		idle_timeout;
 	struct notifier_block        reboot_notify;
 	bool issue_long_pon;
-	u8 cached_ext_csd;
+	u8 *cached_ext_csd;
 };
 
 /*
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index e1dbd21..bff056d 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -300,6 +300,7 @@
 
 #define MMC_CAP2_HS400_1_8V	(1 << 21)        /* can support */
 #define MMC_CAP2_HS400_1_2V	(1 << 22)        /* can support */
+#define MMC_CAP2_CORE_PM	(1 << 23)       /* use PM framework */
 #define MMC_CAP2_HS400		(MMC_CAP2_HS400_1_8V | \
 				 MMC_CAP2_HS400_1_2V)
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
@@ -572,4 +573,9 @@
 	return host->caps2 & MMC_CAP2_CORE_RUNTIME_PM;
 }
 
+static inline int mmc_use_core_pm(struct mmc_host *host)
+{
+	return host->caps2 & MMC_CAP2_CORE_PM;
+}
+
 #endif /* LINUX_MMC_HOST_H */
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index 724e573..4903939 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -802,6 +802,10 @@
 	DCM_BLANK,
 };
 
+#define MDSS_PP_SPLIT_LEFT_ONLY		0x10000000
+#define MDSS_PP_SPLIT_RIGHT_ONLY	0x20000000
+#define MDSS_PP_SPLIT_MASK		0x30000000
+
 #define MDSS_MAX_BL_BRIGHTNESS 255
 #define AD_BL_LIN_LEN 256
 
diff --git a/include/linux/msm_thermal.h b/include/linux/msm_thermal.h
index 2ca9900..25b5363 100644
--- a/include/linux/msm_thermal.h
+++ b/include/linux/msm_thermal.h
@@ -19,22 +19,30 @@
 	uint32_t poll_ms;
 	int32_t limit_temp_degC;
 	int32_t temp_hysteresis_degC;
-	uint32_t freq_step;
-	uint32_t freq_control_mask;
+	uint32_t bootup_freq_step;
+	uint32_t bootup_freq_control_mask;
 	int32_t core_limit_temp_degC;
 	int32_t core_temp_hysteresis_degC;
 	int32_t hotplug_temp_degC;
 	int32_t hotplug_temp_hysteresis_degC;
 	uint32_t core_control_mask;
+	uint32_t freq_mitig_temp_degc;
+	uint32_t freq_mitig_temp_hysteresis_degc;
+	uint32_t freq_mitig_control_mask;
+	uint32_t freq_limit;
 	int32_t vdd_rstr_temp_degC;
 	int32_t vdd_rstr_temp_hyst_degC;
 	int32_t psm_temp_degC;
 	int32_t psm_temp_hyst_degC;
+	int32_t ocr_temp_degC;
+	int32_t ocr_temp_hyst_degC;
 };
 
 #ifdef CONFIG_THERMAL_MONITOR
 extern int msm_thermal_init(struct msm_thermal_data *pdata);
 extern int msm_thermal_device_init(void);
+extern int msm_thermal_set_frequency(uint32_t cpu, uint32_t freq,
+	bool is_max);
 #else
 static inline int msm_thermal_init(struct msm_thermal_data *pdata)
 {
@@ -44,6 +52,11 @@
 {
 	return -ENOSYS;
 }
+static inline int msm_thermal_set_frequency(uint32_t cpu, uint32_t freq,
+	bool is_max)
+{
+	return -ENOSYS;
+}
 #endif
 
 #endif /*__MSM_THERMAL_H*/
diff --git a/include/linux/msm_thermal_ioctl.h b/include/linux/msm_thermal_ioctl.h
new file mode 100644
index 0000000..7b36493
--- /dev/null
+++ b/include/linux/msm_thermal_ioctl.h
@@ -0,0 +1,41 @@
+#ifndef _MSM_THERMAL_IOCTL_H
+#define _MSM_THERMAL_IOCTL_H
+
+#include <linux/ioctl.h>
+
+#define MSM_THERMAL_IOCTL_NAME "msm_thermal_query"
+
+struct __attribute__((__packed__)) cpu_freq_arg {
+	uint32_t cpu_num;
+	uint32_t freq_req;
+};
+
+struct __attribute__((__packed__)) msm_thermal_ioctl {
+	uint32_t size;
+	union {
+		struct cpu_freq_arg cpu_freq;
+	};
+};
+
+enum {
+	/*Set CPU Frequency*/
+	MSM_SET_CPU_MAX_FREQ = 0x00,
+	MSM_SET_CPU_MIN_FREQ = 0x01,
+
+	MSM_CMD_MAX_NR,
+};
+
+#define MSM_THERMAL_MAGIC_NUM 0xCA /*Unique magic number*/
+
+#define MSM_THERMAL_SET_CPU_MAX_FREQUENCY _IOW(MSM_THERMAL_MAGIC_NUM,\
+		MSM_SET_CPU_MAX_FREQ, struct msm_thermal_ioctl)
+
+#define MSM_THERMAL_SET_CPU_MIN_FREQUENCY _IOW(MSM_THERMAL_MAGIC_NUM,\
+		MSM_SET_CPU_MIN_FREQ, struct msm_thermal_ioctl)
+
+#ifdef __KERNEL__
+extern int msm_thermal_ioctl_init(void);
+extern void msm_thermal_ioctl_cleanup(void);
+#endif
+
+#endif
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 22b004e..0065203 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -105,6 +105,7 @@
 	POWER_SUPPLY_PROP_CURRENT_MAX,
 	POWER_SUPPLY_PROP_INPUT_CURRENT_MAX,
 	POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM,
+	POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
 	POWER_SUPPLY_PROP_CURRENT_NOW,
 	POWER_SUPPLY_PROP_CURRENT_AVG,
 	POWER_SUPPLY_PROP_POWER_NOW,
diff --git a/include/linux/qpnp/pwm.h b/include/linux/qpnp/pwm.h
index bf7908b..50fb2e5 100644
--- a/include/linux/qpnp/pwm.h
+++ b/include/linux/qpnp/pwm.h
@@ -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
@@ -146,6 +146,12 @@
 int pwm_lut_config(struct pwm_device *pwm, int period_us,
 		int duty_pct[], struct lut_params lut_params);
 
+/*
+ * support microsecond level configuration
+ */
+int pwm_config_us(struct pwm_device *pwm,
+		int duty_us, int period_us);
+
 /* Standard APIs supported */
 /*
  * pwm_request - request a PWM device
@@ -161,8 +167,8 @@
 /*
  * pwm_config - change a PWM device configuration
  * @pwm: the PWM device
- * @period_us: period in microsecond
- * @duty_us: duty cycle in microsecond
+ * @period_ns: period in nanosecond
+ * @duty_ns: duty cycle in nanosecond
  */
 
 /*
diff --git a/include/linux/qrng.h b/include/linux/qrng.h
new file mode 100644
index 0000000..35708e3
--- /dev/null
+++ b/include/linux/qrng.h
@@ -0,0 +1,12 @@
+#ifndef __QRNG_H_
+#define __QRNG_H_
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define QRNG_IOC_MAGIC    0x100
+
+#define QRNG_IOCTL_RESET_BUS_BANDWIDTH\
+	_IO(QRNG_IOC_MAGIC, 1)
+
+#endif /* __QRNG_H_ */
diff --git a/include/linux/qseecom.h b/include/linux/qseecom.h
index 6d2db8f3..a45c34c 100644
--- a/include/linux/qseecom.h
+++ b/include/linux/qseecom.h
@@ -163,6 +163,13 @@
 	QSEOS_UNPROTECT_PROTECTED_BUFFER,
 };
 
+enum qseecom_bandwidth_request_mode {
+	INACTIVE = 0,
+	LOW,
+	MEDIUM,
+	HIGH,
+};
+
 /*
  * struct qseecom_send_modfd_resp - for send command ioctl request
  * @req_len - command buffer length
@@ -177,7 +184,6 @@
 	enum qseecom_buffer_protection protection_mode; /* in */
 };
 
-
 #define QSEECOM_IOC_MAGIC    0x97
 
 
@@ -246,4 +252,8 @@
 
 #define QSEECOM_IOCTL_UNPROTECT_BUF \
 	_IOWR(QSEECOM_IOC_MAGIC, 22, int)
+
+#define QSEECOM_IOCTL_SET_BUS_SCALING_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 23, int)
+
 #endif /* __QSEECOM_H_ */
diff --git a/include/linux/regulator/cpr-regulator.h b/include/linux/regulator/cpr-regulator.h
index 6387913..624860e 100644
--- a/include/linux/regulator/cpr-regulator.h
+++ b/include/linux/regulator/cpr-regulator.h
@@ -16,7 +16,7 @@
 
 #include <linux/regulator/machine.h>
 
-#define CPR_REGULATOR_DRIVER_NAME	"qcom,cpr-regulator"
+#define CPR_REGULATOR_DRIVER_NAME	"qti,cpr-regulator"
 
 #define CPR_PVS_EFUSE_BITS_MAX		5
 #define CPR_PVS_EFUSE_BINS_MAX		(1 << CPR_PVS_EFUSE_BITS_MAX)
diff --git a/include/linux/slimbus/slimbus.h b/include/linux/slimbus/slimbus.h
index cba4394..c940091 100644
--- a/include/linux/slimbus/slimbus.h
+++ b/include/linux/slimbus/slimbus.h
@@ -1077,7 +1077,7 @@
 extern int slim_register_board_info(struct slim_boardinfo const *info,
 					unsigned n);
 #else
-int slim_register_board_info(struct slim_boardinfo const *info,
+static inline int slim_register_board_info(struct slim_boardinfo const *info,
 					unsigned n)
 {
 	return 0;
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 560accb..bfafe00 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1904,6 +1904,9 @@
 	V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY = 1,
 };
 
+#define V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP (V4L2_CID_MPEG_MSM_VIDC_BASE + 36)
+#define V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP (V4L2_CID_MPEG_MSM_VIDC_BASE + 37)
+
 /*  Camera class control IDs */
 #define V4L2_CID_CAMERA_CLASS_BASE 	(V4L2_CTRL_CLASS_CAMERA | 0x900)
 #define V4L2_CID_CAMERA_CLASS 		(V4L2_CTRL_CLASS_CAMERA | 1)
diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h
index cccf851..a01dd9a 100644
--- a/include/media/msm_cam_sensor.h
+++ b/include/media/msm_cam_sensor.h
@@ -571,6 +571,8 @@
 
 struct msm_camera_led_cfg_t {
 	enum msm_camera_led_config_t cfgtype;
+	uint32_t torch_current;
+	uint32_t flash_current[2];
 };
 
 #define VIDIOC_MSM_SENSOR_CFG \
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index 75fe3a2..2c969cd 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -7172,5 +7172,7 @@
 #define US_POINT_EPOS_FORMAT_V2 0x0001272D
 #define US_RAW_FORMAT_V2        0x0001272C
 #define US_PROX_FORMAT_V2       0x0001272E
+#define US_RAW_SYNC_FORMAT      0x0001272F
+#define US_GES_SYNC_FORMAT      0x00012730
 
 #endif /*_APR_AUDIO_V2_H_ */
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index 9a459b8..b00cfc9 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -67,6 +67,8 @@
 /* Enable Sample_Rate/Channel_Mode notification event from Decoder */
 #define SR_CM_NOTIFY_ENABLE	0x0004
 
+#define TUN_WRITE_IO_MODE 0x0008 /* tunnel read write mode */
+#define TUN_READ_IO_MODE  0x0004 /* tunnel read write mode */
 #define SYNC_IO_MODE	0x0001
 #define ASYNC_IO_MODE	0x0002
 #define COMPRESSED_IO	0x0040
@@ -218,6 +220,9 @@
 			uint32_t rd_format,
 			uint32_t wr_format);
 
+int q6asm_open_loopback_v2(struct audio_client *ac,
+			   uint16_t bits_per_sample);
+
 int q6asm_write(struct audio_client *ac, uint32_t len, uint32_t msw_ts,
 				uint32_t lsw_ts, uint32_t flags);
 int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts,
diff --git a/include/sound/soc.h b/include/sound/soc.h
index ecfba67..278ada3 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -563,6 +563,7 @@
 #endif
 
 struct snd_soc_jack {
+	struct mutex mutex;
 	struct snd_jack *jack;
 	struct snd_soc_codec *codec;
 	struct list_head pins;
diff --git a/kernel/cpu.c b/kernel/cpu.c
index d5ab2e6..2db91f9 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -77,6 +77,10 @@
 	if (cpu_hotplug.active_writer == current)
 		return;
 	mutex_lock(&cpu_hotplug.lock);
+
+	if (WARN_ON(!cpu_hotplug.refcount))
+		cpu_hotplug.refcount++; /* try to fix things up */
+
 	if (!--cpu_hotplug.refcount && unlikely(cpu_hotplug.active_writer))
 		wake_up_process(cpu_hotplug.active_writer);
 	mutex_unlock(&cpu_hotplug.lock);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 89a5395..954a8c4 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4931,7 +4931,7 @@
 
 	touch_all_softlockup_watchdogs();
 
-#ifdef CONFIG_SCHED_DEBUG
+#ifdef CONFIG_SYSRQ_SCHED_DEBUG
 	sysrq_sched_debug_show();
 #endif
 	rcu_read_unlock();
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index 09acaa1..c00829e 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -374,10 +374,12 @@
 	return 0;
 }
 
+#ifdef CONFIG_SYSRQ_SCHED_DEBUG
 void sysrq_sched_debug_show(void)
 {
 	sched_debug_show(NULL, NULL);
 }
+#endif
 
 static int sched_debug_open(struct inode *inode, struct file *filp)
 {
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 55f6d9c..c0288a6 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -872,7 +872,9 @@
 
 #endif
 
+#ifdef CONFIG_SYSRQ_SCHED_DEBUG
 extern void sysrq_sched_debug_show(void);
+#endif
 extern void sched_init_granularity(void);
 extern void update_max_interval(void);
 extern void update_group_power(struct sched_domain *sd, int cpu);
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index b9060a1..5160a45 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -291,6 +291,15 @@
 	  that can help debug the scheduler. The runtime overhead of this
 	  option is minimal.
 
+config SYSRQ_SCHED_DEBUG
+	bool "Print scheduling debugging info from sysrq-trigger"
+	depends on SCHED_DEBUG
+	default y
+	help
+	  If you say Y here, the "show-task-states(T)" and
+	  "show-blocked-tasks(W)" sysrq-triggers will print additional
+	  scheduling statistics.
+
 config SCHEDSTATS
 	bool "Collect scheduler statistics"
 	depends on DEBUG_KERNEL && PROC_FS
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c
index 6d22836..955a47b 100644
--- a/lib/spinlock_debug.c
+++ b/lib/spinlock_debug.c
@@ -108,7 +108,7 @@
 static void __spin_lock_debug(raw_spinlock_t *lock)
 {
 	u64 i;
-	u64 loops = (loops_per_jiffy * HZ) >> 1;
+	u64 loops = (loops_per_jiffy * HZ);
 
 	for (i = 0; i < loops; i++) {
 		if (arch_spin_trylock(&lock->raw_lock))
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index e174693..fa8a793 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -184,36 +184,6 @@
 	return ret;
 }
 
-#ifdef ENABLE_VMALLOC_SAVING
-int is_vmalloc_addr(const void *x)
-{
-	struct rb_node *n;
-	struct vmap_area *va;
-	int ret = 0;
-
-	spin_lock(&vmap_area_lock);
-
-	for (n = rb_first(vmap_area_root); n; rb_next(n)) {
-		va = rb_entry(n, struct vmap_area, rb_node);
-		if (x >= va->va_start && x < va->va_end) {
-			ret = 1;
-			break;
-		}
-	}
-
-	spin_unlock(&vmap_area_lock);
-	return ret;
-}
-#else
-int is_vmalloc_addr(const void *x)
-{
-	unsigned long addr = (unsigned long)x;
-
-	return addr >= VMALLOC_START && addr < VMALLOC_END;
-}
-#endif
-EXPORT_SYMBOL(is_vmalloc_addr);
-
 int is_vmalloc_or_module_addr(const void *x)
 {
 	/*
@@ -302,6 +272,47 @@
 
 static unsigned long vmap_area_pcpu_hole;
 
+#ifdef CONFIG_ENABLE_VMALLOC_SAVING
+int is_vmalloc_addr(const void *x)
+{
+	struct vmap_area *va;
+	int ret = 0;
+
+	spin_lock(&vmap_area_lock);
+	list_for_each_entry(va, &vmap_area_list, list) {
+		if (va->flags & (VM_LAZY_FREE | VM_LAZY_FREEING))
+			continue;
+
+		if (!(va->flags & VM_VM_AREA))
+			continue;
+
+		if (va->vm == NULL)
+			continue;
+
+		if (va->vm->flags & VM_LOWMEM)
+			continue;
+
+		if ((unsigned long)x >= va->va_start &&
+		    (unsigned long)x < va->va_end) {
+			ret = 1;
+			break;
+		}
+	}
+	spin_unlock(&vmap_area_lock);
+	return ret;
+}
+#else
+int is_vmalloc_addr(const void *x)
+{
+	unsigned long addr = (unsigned long)x;
+
+	return addr >= VMALLOC_START && addr < VMALLOC_END;
+}
+#endif
+EXPORT_SYMBOL(is_vmalloc_addr);
+
+
+
 static struct vmap_area *__find_vmap_area(unsigned long addr)
 {
 	struct rb_node *n = vmap_area_root.rb_node;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 9962c88..6c78c0c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1457,7 +1457,7 @@
 		head = p; id++;
 	}
 
-	sprintf(hdev->name, "hci%d", id);
+	snprintf(hdev->name, sizeof(hdev->name), "hci%d", id);
 	hdev->id = id;
 	list_add(&hdev->list, head);
 
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index e598400..04cfc69 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -191,7 +191,7 @@
 	size = SKB_DATA_ALIGN(size);
 	size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 	data = kmalloc_node_track_caller(size, gfp_mask, node);
-	if (!data)
+	if (unlikely(ZERO_OR_NULL_PTR(data)))
 		goto nodata;
 	/* kmalloc(size) might give us more room than requested.
 	 * Put skb_shared_info exactly at the end of allocated zone,
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 2628937..b2b0e99 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3443,10 +3443,7 @@
 			tcp_done(sk);
 			bh_unlock_sock(sk);
 			local_bh_enable();
-			if (!sock_flag(sk, SOCK_DEAD)) {
-				sock_orphan(sk);
-				sock_put(sk);
-			}
+			sock_put(sk);
 
 			goto restart;
 		}
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 487ac6f..9a11f9f 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -55,6 +55,7 @@
 static unsigned int table_size, table_cnt;
 static int all_symbols = 0;
 static char symbol_prefix_char = '\0';
+static unsigned long long kernel_start_addr = 0;
 
 int token_profit[0x10000];
 
@@ -65,7 +66,10 @@
 
 static void usage(void)
 {
-	fprintf(stderr, "Usage: kallsyms [--all-symbols] [--symbol-prefix=<prefix char>] < in.map > out.S\n");
+	fprintf(stderr, "Usage: kallsyms [--all-symbols] "
+			"[--symbol-prefix=<prefix char>] "
+			"[--page-offset=<CONFIG_PAGE_OFFSET>] "
+			"< in.map > out.S\n");
 	exit(1);
 }
 
@@ -194,6 +198,9 @@
 	int i;
 	int offset = 1;
 
+	if (s->addr < kernel_start_addr)
+		return 0;
+
 	/* skip prefix char */
 	if (symbol_prefix_char && *(s->sym + 1) == symbol_prefix_char)
 		offset++;
@@ -646,6 +653,9 @@
 				if ((*p == '"' && *(p+2) == '"') || (*p == '\'' && *(p+2) == '\''))
 					p++;
 				symbol_prefix_char = *p;
+			} else if (strncmp(argv[i], "--page-offset=", 14) == 0) {
+				const char *p = &argv[i][14];
+				kernel_start_addr = strtoull(p, NULL, 16);
 			} else
 				usage();
 		}
diff --git a/sound/soc/codecs/msm8x10-wcd.c b/sound/soc/codecs/msm8x10-wcd.c
index 55fec32..1962ff0 100644
--- a/sound/soc/codecs/msm8x10-wcd.c
+++ b/sound/soc/codecs/msm8x10-wcd.c
@@ -1396,7 +1396,10 @@
 	switch (decimator) {
 	case 1:
 	case 2:
-			adc_dmic_sel = 0x0;
+			if ((dec_mux == 3) || (dec_mux == 4))
+				adc_dmic_sel = 0x1;
+			else
+				adc_dmic_sel = 0x0;
 		break;
 	default:
 		dev_err(codec->dev, "%s: Invalid Decimator = %u\n",
diff --git a/sound/soc/codecs/msm_hdmi_codec_rx.c b/sound/soc/codecs/msm_hdmi_codec_rx.c
index ae6bfbe..73c9547e 100644
--- a/sound/soc/codecs/msm_hdmi_codec_rx.c
+++ b/sound/soc/codecs/msm_hdmi_codec_rx.c
@@ -21,6 +21,8 @@
 
 #define MSM_HDMI_PCM_RATES	SNDRV_PCM_RATE_48000
 
+static int msm_hdmi_audio_codec_return_value;
+
 struct msm_hdmi_audio_codec_rx_data {
 	struct platform_device *hdmi_core_pdev;
 	struct msm_hdmi_audio_codec_ops hdmi_ops;
@@ -54,8 +56,8 @@
 	int rc;
 
 	codec_data = snd_soc_codec_get_drvdata(codec);
-	rc = codec_data->hdmi_ops.get_audio_edid_blk(codec_data->hdmi_core_pdev,
-						     &edid_blk);
+	rc = codec_data->hdmi_ops.get_audio_edid_blk(
+			codec_data->hdmi_core_pdev, &edid_blk);
 
 	if (!IS_ERR_VALUE(rc)) {
 		memcpy(ucontrol->value.bytes.data, edid_blk.audio_data_blk,
@@ -80,6 +82,24 @@
 	},
 };
 
+static int msm_hdmi_audio_codec_rx_dai_startup(
+		struct snd_pcm_substream *substream,
+		struct snd_soc_dai *dai)
+{
+	struct msm_hdmi_audio_codec_rx_data *codec_data =
+			dev_get_drvdata(dai->codec->dev);
+
+	msm_hdmi_audio_codec_return_value =
+		codec_data->hdmi_ops.hdmi_cable_status(
+		codec_data->hdmi_core_pdev, 1);
+	if (IS_ERR_VALUE(msm_hdmi_audio_codec_return_value)) {
+		dev_err(dai->dev,
+			"%s() HDMI core is not ready\n", __func__);
+	}
+
+	return msm_hdmi_audio_codec_return_value;
+}
+
 static int msm_hdmi_audio_codec_rx_dai_hw_params(
 		struct snd_pcm_substream *substream,
 		struct snd_pcm_hw_params *params,
@@ -89,11 +109,18 @@
 	u32 level_shift  = 0; /* 0dB */
 	bool down_mix = 0;
 	u32 num_channels = params_channels(params);
+	int rc = 0;
 
 	struct msm_hdmi_audio_codec_rx_data *codec_data =
 			dev_get_drvdata(dai->codec->dev);
 
 	/*refer to HDMI spec CEA-861-E: Table 28 Audio InfoFrame Data Byte 4*/
+	if (IS_ERR_VALUE(msm_hdmi_audio_codec_return_value)) {
+		dev_err(dai->dev,
+			"%s() HDMI core is not ready\n", __func__);
+		return msm_hdmi_audio_codec_return_value;
+	}
+
 	switch (num_channels) {
 	case 2:
 		channel_allocation  = 0;
@@ -121,19 +148,47 @@
 		return -EINVAL;
 	}
 
-	dev_dbg(dai->dev, "%s() num_ch %u  samplerate %u channel_allocation = %u\n",
+	dev_dbg(dai->dev,
+		"%s() num_ch %u  samplerate %u channel_allocation = %u\n",
 		__func__, num_channels, params_rate(params),
 		channel_allocation);
 
-	codec_data->hdmi_ops.audio_info_setup(codec_data->hdmi_core_pdev,
-			params_rate(params), num_channels, channel_allocation,
-			level_shift, down_mix);
+	rc = codec_data->hdmi_ops.audio_info_setup(
+			codec_data->hdmi_core_pdev,
+			params_rate(params), num_channels,
+			channel_allocation, level_shift, down_mix);
+	if (IS_ERR_VALUE(rc)) {
+		dev_err(dai->dev,
+			"%s() HDMI core is not ready\n", __func__);
+	}
 
-	return 0;
+	return rc;
+}
+
+static void msm_hdmi_audio_codec_rx_dai_shutdown(
+		struct snd_pcm_substream *substream,
+		struct snd_soc_dai *dai)
+{
+	int rc;
+
+	struct msm_hdmi_audio_codec_rx_data *codec_data =
+			dev_get_drvdata(dai->codec->dev);
+
+	rc = codec_data->hdmi_ops.hdmi_cable_status(
+			codec_data->hdmi_core_pdev, 0);
+	if (IS_ERR_VALUE(rc)) {
+		dev_err(dai->dev,
+			"%s() HDMI core had problems releasing HDMI audio flag\n",
+			__func__);
+	}
+
+	return;
 }
 
 static struct snd_soc_dai_ops msm_hdmi_audio_codec_rx_dai_ops = {
+	.startup	= msm_hdmi_audio_codec_rx_dai_startup,
 	.hw_params	= msm_hdmi_audio_codec_rx_dai_hw_params,
+	.shutdown	= msm_hdmi_audio_codec_rx_dai_shutdown
 };
 
 static int msm_hdmi_audio_codec_rx_probe(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c
index 6de310a..4912cf04a 100644
--- a/sound/soc/codecs/wcd9306.c
+++ b/sound/soc/codecs/wcd9306.c
@@ -1327,6 +1327,9 @@
 static const struct soc_enum rx4_mix1_inp2_chain_enum =
 	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_RX4_B1_CTL, 4, 13, rx_3_4_mix1_text);
 
+static const struct soc_enum rx4_mix1_inp3_chain_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_RX4_B2_CTL, 0, 13, rx_3_4_mix1_text);
+
 static const struct soc_enum rx1_mix2_inp1_chain_enum =
 	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_RX1_B3_CTL, 0, 5, rx_mix2_text);
 
@@ -1422,6 +1425,9 @@
 static const struct snd_kcontrol_new rx4_mix1_inp2_mux =
 	SOC_DAPM_ENUM("RX4 MIX1 INP2 Mux", rx4_mix1_inp2_chain_enum);
 
+static const struct snd_kcontrol_new rx4_mix1_inp3_mux =
+	SOC_DAPM_ENUM("RX4 MIX1 INP3 Mux", rx4_mix1_inp3_chain_enum);
+
 static const struct snd_kcontrol_new rx1_mix2_inp1_mux =
 	SOC_DAPM_ENUM("RX1 MIX2 INP1 Mux", rx1_mix2_inp1_chain_enum);
 
@@ -4277,7 +4283,7 @@
 	SND_SOC_DAPM_MUX("RX4 MIX1 INP2", SND_SOC_NOPM, 0, 0,
 		&rx4_mix1_inp2_mux),
 	SND_SOC_DAPM_MUX("RX4 MIX1 INP3", SND_SOC_NOPM, 0, 0,
-		&rx4_mix1_inp2_mux),
+		&rx4_mix1_inp3_mux),
 
 	/* RX4 MIX2 mux inputs */
 	SND_SOC_DAPM_MUX("RX4 MIX2 INP1", SND_SOC_NOPM, 0, 0,
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 6dc2ec0..c62f875 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -260,6 +260,8 @@
 
 #define TAIKO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
 
+#define TAIKO_SLIM_PGD_PORT_INT_TX_EN0 (TAIKO_SLIM_PGD_PORT_INT_EN0 + 2)
+
 enum {
 	AIF1_PB = 0,
 	AIF1_CAP,
@@ -4884,6 +4886,46 @@
 	return ret;
 }
 
+static void taiko_codec_enable_int_port(struct wcd9xxx_codec_dai_data *dai,
+					  struct snd_soc_codec *codec)
+{
+	struct wcd9xxx_ch *ch;
+	int port_num = 0;
+	unsigned short reg = 0;
+	u8 val = 0;
+	if (!dai || !codec) {
+		pr_err("%s: Invalid params\n", __func__);
+		return;
+	}
+	list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
+		if (ch->port >= TAIKO_RX_PORT_START_NUMBER) {
+			port_num = ch->port - TAIKO_RX_PORT_START_NUMBER;
+			reg = TAIKO_SLIM_PGD_PORT_INT_EN0 + (port_num / 8);
+			val = wcd9xxx_interface_reg_read(codec->control_data,
+				reg);
+			if (!(val & (1 << (port_num % 8)))) {
+				val |= (1 << (port_num % 8));
+				wcd9xxx_interface_reg_write(
+					codec->control_data, reg, val);
+				val = wcd9xxx_interface_reg_read(
+					codec->control_data, reg);
+			}
+		} else {
+			port_num = ch->port;
+			reg = TAIKO_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8);
+			val = wcd9xxx_interface_reg_read(codec->control_data,
+				reg);
+			if (!(val & (1 << (port_num % 8)))) {
+				val |= (1 << (port_num % 8));
+				wcd9xxx_interface_reg_write(codec->control_data,
+					reg, val);
+				val = wcd9xxx_interface_reg_read(
+					codec->control_data, reg);
+			}
+		}
+	}
+}
+
 static int taiko_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
 				     struct snd_kcontrol *kcontrol,
 				     int event)
@@ -4910,6 +4952,7 @@
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
+		taiko_codec_enable_int_port(dai, codec);
 		(void) taiko_codec_enable_slim_chmask(dai, true);
 		ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
 					      dai->rate, dai->bit_width,
@@ -4974,6 +5017,7 @@
 		/*Enable spkr VI clocks*/
 		snd_soc_update_bits(codec,
 		TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL, 0xC, 0xC);
+		taiko_codec_enable_int_port(dai, codec);
 		(void) taiko_codec_enable_slim_chmask(dai, true);
 		ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
 					dai->rate, dai->bit_width,
@@ -5021,6 +5065,7 @@
 	dai = &taiko_p->dai[w->shift];
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
+		taiko_codec_enable_int_port(dai, codec);
 		(void) taiko_codec_enable_slim_chmask(dai, true);
 		ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
 					      dai->rate, dai->bit_width,
@@ -5629,8 +5674,9 @@
 	unsigned long status = 0;
 	int i, j, port_id, k;
 	u32 bit;
-	u8 val;
+	u8 val, int_val = 0;
 	bool tx, cleared;
+	unsigned short reg = 0;
 
 	for (i = TAIKO_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0;
 	     i <= TAIKO_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) {
@@ -5645,12 +5691,28 @@
 					TAIKO_SLIM_PGD_PORT_INT_RX_SOURCE0 + j);
 		if (val & TAIKO_SLIM_IRQ_OVERFLOW)
 			pr_err_ratelimited(
-			    "%s: overflow error on %s port %d, value %x\n",
-			    __func__, (tx ? "TX" : "RX"), port_id, val);
+			   "%s: overflow error on %s port %d, value %x\n",
+			   __func__, (tx ? "TX" : "RX"), port_id, val);
 		if (val & TAIKO_SLIM_IRQ_UNDERFLOW)
 			pr_err_ratelimited(
-			    "%s: underflow error on %s port %d, value %x\n",
-			    __func__, (tx ? "TX" : "RX"), port_id, val);
+			   "%s: underflow error on %s port %d, value %x\n",
+			   __func__, (tx ? "TX" : "RX"), port_id, val);
+		if ((val & TAIKO_SLIM_IRQ_OVERFLOW) ||
+			(val & TAIKO_SLIM_IRQ_UNDERFLOW)) {
+			if (!tx)
+				reg = TAIKO_SLIM_PGD_PORT_INT_EN0 +
+					(port_id / 8);
+			else
+				reg = TAIKO_SLIM_PGD_PORT_INT_TX_EN0 +
+					(port_id / 8);
+			int_val = wcd9xxx_interface_reg_read(
+				codec->control_data, reg);
+			if (int_val & (1 << (port_id % 8))) {
+				int_val = int_val ^ (1 << (port_id % 8));
+				wcd9xxx_interface_reg_write(codec->control_data,
+					reg, int_val);
+			}
+		}
 		if (val & TAIKO_SLIM_IRQ_PORT_CLOSED) {
 			/*
 			 * INT SOURCE register starts from RX to TX
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index 28d4c84..14218d8 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -213,7 +213,6 @@
 /* called under codec_resource_lock acquisition */
 static void wcd9xxx_start_hs_polling(struct wcd9xxx_mbhc *mbhc)
 {
-	s16 v_brh, v_b1_hu;
 	struct snd_soc_codec *codec = mbhc->codec;
 	int mbhc_state = mbhc->mbhc_state;
 
@@ -254,17 +253,6 @@
 		/* set to max */
 		snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL, 0x7F);
 		snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL, 0xFF);
-
-		v_brh = wcd9xxx_get_current_v(mbhc, WCD9XXX_CURRENT_V_BR_H);
-		snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
-			      (v_brh >> 8) & 0xFF);
-		snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL,
-			      v_brh & 0xFF);
-		v_b1_hu = wcd9xxx_get_current_v(mbhc, WCD9XXX_CURRENT_V_B1_HU);
-		snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL,
-			      v_b1_hu & 0xFF);
-		snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
-			      (v_b1_hu >> 8) & 0xFF);
 	}
 
 	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x1);
@@ -325,22 +313,32 @@
 			snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B2_CTL,
 				      (d->v_ins_hu[MBHC_V_IDX_VDDIO] >> 8) &
 				      0xFF);
-			/* Threshods for button press */
-			snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL,
-				      d->v_b1_hu[MBHC_V_IDX_VDDIO] & 0xFF);
-			snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
-				      (d->v_b1_hu[MBHC_V_IDX_VDDIO] >> 8) &
-				      0xFF);
-			snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL,
-				      d->v_b1_h[MBHC_V_IDX_VDDIO] & 0xFF);
-			snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL,
-				      (d->v_b1_h[MBHC_V_IDX_VDDIO] >> 8) &
-				      0xFF);
-			/* Threshods for button release */
-			snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL,
-				      d->v_brh[MBHC_V_IDX_VDDIO] & 0xFF);
-			snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
-				      (d->v_brh[MBHC_V_IDX_VDDIO] >> 8) & 0xFF);
+
+			if (mbhc->mbhc_state != MBHC_STATE_POTENTIAL_RECOVERY) {
+				/* Threshods for button press */
+				snd_soc_write(codec,
+					WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL,
+					d->v_b1_hu[MBHC_V_IDX_VDDIO] & 0xFF);
+				snd_soc_write(codec,
+					WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
+					(d->v_b1_hu[MBHC_V_IDX_VDDIO] >> 8) &
+					0xFF);
+				snd_soc_write(codec,
+					WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL,
+					d->v_b1_h[MBHC_V_IDX_VDDIO] & 0xFF);
+				snd_soc_write(codec,
+					WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL,
+					(d->v_b1_h[MBHC_V_IDX_VDDIO] >> 8) &
+					0xFF);
+				/* Threshods for button release */
+				snd_soc_write(codec,
+					WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL,
+					d->v_brh[MBHC_V_IDX_VDDIO] & 0xFF);
+				snd_soc_write(codec,
+					WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
+					(d->v_brh[MBHC_V_IDX_VDDIO] >> 8) &
+					0xFF);
+			}
 			pr_debug("%s: Programmed MBHC thresholds to VDDIO\n",
 				 __func__);
 		}
@@ -376,22 +374,31 @@
 			snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B2_CTL,
 					(d->v_ins_hu[MBHC_V_IDX_CFILT] >> 8) &
 					0xFF);
-			/* Revert threshods for button press */
-			snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL,
-				      d->v_b1_hu[MBHC_V_IDX_CFILT] & 0xFF);
-			snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
-				      (d->v_b1_hu[MBHC_V_IDX_CFILT] >> 8) &
-				      0xFF);
-			snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL,
-				      d->v_b1_h[MBHC_V_IDX_CFILT] & 0xFF);
-			snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL,
-				      (d->v_b1_h[MBHC_V_IDX_CFILT] >> 8) &
-				      0xFF);
-			/* Revert threshods for button release */
-			snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL,
-				      d->v_brh[MBHC_V_IDX_CFILT] & 0xFF);
-			snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
-				      (d->v_brh[MBHC_V_IDX_CFILT] >> 8) & 0xFF);
+			if (mbhc->mbhc_state != MBHC_STATE_POTENTIAL_RECOVERY) {
+				/* Revert threshods for button press */
+				snd_soc_write(codec,
+					WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL,
+					d->v_b1_hu[MBHC_V_IDX_CFILT] & 0xFF);
+				snd_soc_write(codec,
+					WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
+					(d->v_b1_hu[MBHC_V_IDX_CFILT] >> 8) &
+					0xFF);
+				snd_soc_write(codec,
+					WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL,
+					d->v_b1_h[MBHC_V_IDX_CFILT] & 0xFF);
+				snd_soc_write(codec,
+					WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL,
+					(d->v_b1_h[MBHC_V_IDX_CFILT] >> 8) &
+					0xFF);
+				/* Revert threshods for button release */
+				snd_soc_write(codec,
+					WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL,
+					d->v_brh[MBHC_V_IDX_CFILT] & 0xFF);
+				snd_soc_write(codec,
+					WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
+					(d->v_brh[MBHC_V_IDX_CFILT] >> 8) &
+					0xFF);
+			}
 			pr_debug("%s: Programmed MBHC thresholds to MICBIAS\n",
 					__func__);
 		}
@@ -489,19 +496,25 @@
 	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B1_CTL, v_ins_hu & 0xFF);
 	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B2_CTL,
 		      (v_ins_hu >> 8) & 0xFF);
-	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL, v_b1_hu & 0xFF);
-	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
-		      (v_b1_hu >> 8) & 0xFF);
-	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL, v_b1_h & 0xFF);
-	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL,
-		      (v_b1_h >> 8) & 0xFF);
-	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL, v_brh & 0xFF);
-	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
-		      (v_brh >> 8) & 0xFF);
-	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B11_CTL,
-		      mbhc->mbhc_data.v_brl & 0xFF);
-	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B12_CTL,
-		      (mbhc->mbhc_data.v_brl >> 8) & 0xFF);
+
+	if (mbhc->mbhc_state != MBHC_STATE_POTENTIAL_RECOVERY) {
+		snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL, v_b1_hu &
+				0xFF);
+		snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
+				(v_b1_hu >> 8) & 0xFF);
+		snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL, v_b1_h &
+				0xFF);
+		snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL,
+				(v_b1_h >> 8) & 0xFF);
+		snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL, v_brh &
+				0xFF);
+		snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
+				(v_brh >> 8) & 0xFF);
+		snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B11_CTL,
+				mbhc->mbhc_data.v_brl & 0xFF);
+		snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B12_CTL,
+				(mbhc->mbhc_data.v_brl >> 8) & 0xFF);
+	}
 }
 
 static void wcd9xxx_codec_switch_cfilt_mode(struct wcd9xxx_mbhc *mbhc,
@@ -3148,15 +3161,22 @@
 	mv = ceilmv + btn_det->v_btn_press_delta_cic;
 	pr_debug("%s: reprogram vb1hu/vbrh to %dmv\n", __func__, mv);
 
-	/* update LSB first so mbhc hardware block doesn't see too low value */
-	v_b1_hu = wcd9xxx_codec_v_sta_dce(mbhc, STA, mv, false);
-	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL, v_b1_hu & 0xFF);
-	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
-		      (v_b1_hu >> 8) & 0xFF);
-	v_brh = wcd9xxx_codec_v_sta_dce(mbhc, DCE, mv, false);
-	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL, v_brh & 0xFF);
-	snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
-		      (v_brh >> 8) & 0xFF);
+	if (mbhc->mbhc_state != MBHC_STATE_POTENTIAL_RECOVERY) {
+		/*
+		 * update LSB first so mbhc hardware block
+		 * doesn't see too low value.
+		 */
+		v_b1_hu = wcd9xxx_codec_v_sta_dce(mbhc, STA, mv, false);
+		snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL, v_b1_hu &
+				0xFF);
+		snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
+				(v_b1_hu >> 8) & 0xFF);
+		v_brh = wcd9xxx_codec_v_sta_dce(mbhc, DCE, mv, false);
+		snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL, v_brh &
+				0xFF);
+		snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
+				(v_brh >> 8) & 0xFF);
+	}
 	return 0;
 }
 
diff --git a/sound/soc/msm/apq8074.c b/sound/soc/msm/apq8074.c
index 3a055e2..5b12b9c 100644
--- a/sound/soc/msm/apq8074.c
+++ b/sound/soc/msm/apq8074.c
@@ -19,18 +19,22 @@
 #include <linux/mfd/pm8xxx/pm8921.h>
 #include <linux/qpnp/clkdiv.h>
 #include <linux/regulator/consumer.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
 #include <sound/pcm.h>
 #include <sound/jack.h>
 #include <sound/q6afe-v2.h>
-#include <asm/mach-types.h>
-#include <mach/socinfo.h>
 #include <sound/pcm_params.h>
+#include <asm/mach-types.h>
+#include <mach/subsystem_notif.h>
+#include <mach/socinfo.h>
+
 #include "qdsp6v2/msm-pcm-routing-v2.h"
+#include "qdsp6v2/q6core.h"
+#include "../codecs/wcd9xxx-common.h"
 #include "../codecs/wcd9320.h"
-#include <linux/io.h>
 
 #define DRV_NAME "apq8074-asoc-taiko"
 
@@ -82,6 +86,10 @@
 
 #define NUM_OF_AUXPCM_GPIOS 4
 
+static void *adsp_state_notifier;
+
+#define ADSP_STATE_READY_TIMEOUT_MS 3000
+
 static inline int param_is_mask(int p)
 {
 	return ((p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
@@ -1230,6 +1238,101 @@
 	return true;
 }
 
+static int msm_afe_set_config(struct snd_soc_codec *codec)
+{
+	int rc;
+	void *config_data;
+
+	pr_debug("%s: enter\n", __func__);
+	config_data = taiko_get_afe_config(codec, AFE_CDC_REGISTERS_CONFIG);
+	rc = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0);
+	if (rc) {
+		pr_err("%s: Failed to set codec registers config %d\n",
+		       __func__, rc);
+		return rc;
+	}
+
+	config_data = taiko_get_afe_config(codec, AFE_SLIMBUS_SLAVE_CONFIG);
+	rc = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0);
+	if (rc) {
+		pr_err("%s: Failed to set slimbus slave config %d\n", __func__,
+		       rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+static void msm_afe_clear_config(void)
+{
+	afe_clear_config(AFE_CDC_REGISTERS_CONFIG);
+	afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG);
+}
+
+static int  msm8974_adsp_state_callback(struct notifier_block *nb,
+		unsigned long value, void *priv)
+{
+	if (value == SUBSYS_BEFORE_SHUTDOWN) {
+		pr_debug("%s: ADSP is about to shutdown. Clearing AFE config\n",
+			 __func__);
+		msm_afe_clear_config();
+	} else if (value == SUBSYS_AFTER_POWERUP) {
+		pr_debug("%s: ADSP is up\n", __func__);
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block adsp_state_notifier_block = {
+	.notifier_call = msm8974_adsp_state_callback,
+	.priority = -INT_MAX,
+};
+
+static int msm8974_taiko_codec_up(struct snd_soc_codec *codec)
+{
+	int err;
+	unsigned long timeout;
+	int adsp_ready = 0;
+
+	timeout = jiffies +
+		msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS);
+
+	do {
+		if (!q6core_is_adsp_ready()) {
+			pr_err("%s: ADSP Audio isn't ready\n", __func__);
+		} else {
+			pr_debug("%s: ADSP Audio is ready\n", __func__);
+			adsp_ready = 1;
+			break;
+		}
+	} while (time_after(timeout, jiffies));
+
+	if (!adsp_ready) {
+		pr_err("%s: timed out waiting for ADSP Audio\n", __func__);
+		return -ETIMEDOUT;
+	}
+
+	err = msm_afe_set_config(codec);
+	if (err)
+		pr_err("%s: Failed to set AFE config. err %d\n",
+				__func__, err);
+	return err;
+}
+
+static int apq8074_taiko_event_cb(struct snd_soc_codec *codec,
+		enum wcd9xxx_codec_event codec_event)
+{
+	switch (codec_event) {
+	case WCD9XXX_CODEC_EVENT_CODEC_UP:
+		return msm8974_taiko_codec_up(codec);
+		break;
+	default:
+		pr_err("%s: UnSupported codec event %d\n",
+				__func__, codec_event);
+		return -EINVAL;
+	}
+}
+
 static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
 {
 	int err;
@@ -1291,19 +1394,9 @@
 				    tx_ch, ARRAY_SIZE(rx_ch), rx_ch);
 
 
-	config_data = taiko_get_afe_config(codec, AFE_CDC_REGISTERS_CONFIG);
-	err = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0);
+	err = msm_afe_set_config(codec);
 	if (err) {
-		pr_err("%s: Failed to set codec registers config %d\n",
-		       __func__, err);
-		goto out;
-	}
-
-	config_data = taiko_get_afe_config(codec, AFE_SLIMBUS_SLAVE_CONFIG);
-	err = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0);
-	if (err) {
-		pr_err("%s: Failed to set slimbus slave config %d\n", __func__,
-		       err);
+		pr_err("%s: Failed to set AFE config %d\n", __func__, err);
 		goto out;
 	}
 
@@ -1340,12 +1433,23 @@
 		err = taiko_hs_detect(codec, &mbhc_cfg);
 		if (err)
 			goto out;
-		else
-			return err;
 	} else {
 		err = -ENOMEM;
 		goto out;
 	}
+	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__);
+		err = -EFAULT;
+		taiko_hs_detect_exit(codec);
+		goto out;
+	}
+
+	taiko_event_register(apq8074_taiko_event_cb, rtd->codec);
+	return 0;
 out:
 	clk_put(codec_clk);
 	return err;
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 39cb470..6f94d99 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -422,6 +422,30 @@
 	},
 	{
 		.playback = {
+			.stream_name = "INT_HFP_BT Hostless Playback",
+			.aif_name = "INTHFP_DL_HL",
+			.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 2,
+			.rate_min =     8000,
+			.rate_max =     16000,
+		},
+		.capture = {
+			.stream_name = "INT_HFP_BT Hostless Capture",
+			.aif_name = "INTHFP_UL_HL",
+			.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 2,
+			.rate_min =     8000,
+			.rate_max =     16000,
+		},
+		.ops = &msm_fe_dai_ops,
+		.name = "INT_HFP_BT_HOSTLESS",
+	},
+	{
+		.playback = {
 			.stream_name = "AFE-PROXY Playback",
 			.aif_name = "PCM_RX",
 			.rates = (SNDRV_PCM_RATE_8000 |
diff --git a/sound/soc/msm/msm8226.c b/sound/soc/msm/msm8226.c
index ceea3d2..b4ae0a4 100644
--- a/sound/soc/msm/msm8226.c
+++ b/sound/soc/msm/msm8226.c
@@ -1420,6 +1420,21 @@
 		.codec_name = "snd-soc-dummy",
 		.be_id = MSM_FRONTEND_DAI_LSM1,
 	},
+	{
+		.name = "MSM8226 Compr8",
+		.stream_name = "COMPR8",
+		.cpu_dai_name	= "MultiMedia8",
+		.platform_name  = "msm-compr-dsp",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			 SND_SOC_DPCM_TRIGGER_POST},
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		 /* this dainlink has playback support */
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA8,
+	},
 	/* Backend BT/FM DAI Links */
 	{
 		.name = LPASS_BE_INT_BT_SCO_RX,
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index c120e0c..69a6671 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -2203,6 +2203,37 @@
 		.codec_name = "snd-soc-dummy",
 	},
 	{
+		.name = "INT_HFP_BT Hostless",
+		.stream_name = "INT_HFP_BT Hostless",
+		.cpu_dai_name   = "INT_HFP_BT_HOSTLESS",
+		.platform_name  = "msm-pcm-hostless",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			    SND_SOC_DPCM_TRIGGER_POST},
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		/* this dai link has playback support */
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
+	{
+		.name = "MSM8974 HFP TX",
+		.stream_name = "MultiMedia6",
+		.cpu_dai_name = "MultiMedia6",
+		.platform_name  = "msm-pcm-loopback",
+		.dynamic = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			    SND_SOC_DPCM_TRIGGER_POST},
+		.ignore_suspend = 1,
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA6,
+	},
+	{
 		.name = LPASS_BE_SLIMBUS_4_TX,
 		.stream_name = "Slimbus4 Capture",
 		.cpu_dai_name = "msm-dai-q6-dev.16393",
diff --git a/sound/soc/msm/msm8x10.c b/sound/soc/msm/msm8x10.c
index 408ec03..c1ba26a 100644
--- a/sound/soc/msm/msm8x10.c
+++ b/sound/soc/msm/msm8x10.c
@@ -163,6 +163,8 @@
 	SND_SOC_DAPM_MIC("Handset Mic", NULL),
 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
 	SND_SOC_DAPM_MIC("Secondary Mic", NULL),
+	SND_SOC_DAPM_MIC("Digital Mic1", NULL),
+	SND_SOC_DAPM_MIC("Digital Mic2", NULL),
 };
 static int msm8x10_ext_spk_power_amp_init(void)
 {
diff --git a/sound/soc/msm/qdsp6v2/Makefile b/sound/soc/msm/qdsp6v2/Makefile
index ea16f47..f0f5db6 100644
--- a/sound/soc/msm/qdsp6v2/Makefile
+++ b/sound/soc/msm/qdsp6v2/Makefile
@@ -3,7 +3,8 @@
 			msm-multi-ch-pcm-q6-v2.o msm-pcm-lpa-v2.o \
 			msm-pcm-afe-v2.o msm-pcm-voip-v2.o \
 			msm-pcm-voice-v2.o msm-dai-q6-hdmi-v2.o \
-			msm-lsm-client.o msm-audio-effects-q6-v2.o
+			msm-lsm-client.o msm-audio-effects-q6-v2.o \
+			msm-pcm-loopback-v2.o
 obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o msm-pcm-dtmf-v2.o \
 				 msm-dai-stub-v2.o
 obj-$(CONFIG_DOLBY_DAP) += msm-dolby-dap-config.o
diff --git a/sound/soc/msm/qdsp6v2/audio_acdb.c b/sound/soc/msm/qdsp6v2/audio_acdb.c
index 58c3cdf..4e04bef 100644
--- a/sound/soc/msm/qdsp6v2/audio_acdb.c
+++ b/sound/soc/msm/qdsp6v2/audio_acdb.c
@@ -405,9 +405,9 @@
 
 done:
 	mutex_unlock(&acdb_data.acdb_mutex);
-ret:
 	pr_debug("ACDB=> %s: Path = %d samplerate = %u usec = %u status %d\n",
 		 __func__, path, entry->sample_rate, entry->delay_usec, result);
+ret:
 	return result;
 }
 
diff --git a/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.c b/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.c
index 307d63e..63ac5d3 100644
--- a/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.c
+++ b/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.c
@@ -179,13 +179,13 @@
 		 DOLBY_ENDDEP_PARAM_VMB_OFFSET},
 		{-320, -320, 144}
 	},
-	{REMOTE_SUBMIX,	2, DOLBY_ENDP_EXT_SPEAKERS,
+	{REMOTE_SUBMIX,	2, DOLBY_ENDP_HDMI,
 		{DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
 		{DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
 		 DOLBY_ENDDEP_PARAM_VMB_LENGTH},
 		{DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
 		 DOLBY_ENDDEP_PARAM_VMB_OFFSET},
-		{-320, -320, 144}
+		{-496, -496, 0}
 	},
 	{ANC_HEADSET, 2, DOLBY_ENDP_HEADPHONES,
 		{DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
@@ -211,13 +211,13 @@
 		 DOLBY_ENDDEP_PARAM_VMB_OFFSET},
 		{-320, -320, 144}
 	},
-	{FM, 2, DOLBY_ENDP_EXT_SPEAKERS,
+	{FM, 2, DOLBY_ENDP_HDMI,
 		{DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
 		{DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
 		 DOLBY_ENDDEP_PARAM_VMB_LENGTH},
 		{DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
 		 DOLBY_ENDDEP_PARAM_VMB_OFFSET},
-		{-320, -320, 144}
+		{-496, -496, 0}
 	},
 	{FM_TX,	2, DOLBY_ENDP_EXT_SPEAKERS,
 		{DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c
new file mode 100644
index 0000000..57fc268
--- /dev/null
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c
@@ -0,0 +1,441 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 and
+* only version 2 as published by the Free Software Foundation.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*/
+
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <sound/apr_audio-v2.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/q6asm-v2.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+#include <sound/control.h>
+#include <sound/tlv.h>
+#include <asm/dma.h>
+
+#include "msm-pcm-routing-v2.h"
+
+#define LOOPBACK_VOL_MAX_STEPS 0x2000
+
+static const DECLARE_TLV_DB_LINEAR(loopback_rx_vol_gain, 0,
+				LOOPBACK_VOL_MAX_STEPS);
+
+struct msm_pcm_loopback {
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
+
+	int instance;
+
+	struct mutex lock;
+
+	uint32_t samp_rate;
+	uint32_t channel_mode;
+
+	int playback_start;
+	int capture_start;
+	int session_id;
+	struct audio_client *audio_client;
+	int volume;
+};
+
+static void stop_pcm(struct msm_pcm_loopback *pcm);
+
+static const struct snd_pcm_hardware dummy_pcm_hardware = {
+	.formats                = 0xffffffff,
+	.channels_min           = 1,
+	.channels_max           = UINT_MAX,
+
+	/* Random values to keep userspace happy when checking constraints */
+	.info                   = SNDRV_PCM_INFO_INTERLEAVED |
+				  SNDRV_PCM_INFO_BLOCK_TRANSFER,
+	.buffer_bytes_max       = 128*1024,
+	.period_bytes_min       = 1024,
+	.period_bytes_max       = 1024*2,
+	.periods_min            = 2,
+	.periods_max            = 128,
+};
+
+static void msm_pcm_route_event_handler(enum msm_pcm_routing_event event,
+					void *priv_data)
+{
+	struct msm_pcm_loopback *pcm = priv_data;
+
+	BUG_ON(!pcm);
+
+	pr_debug("%s: event %x\n", __func__, event);
+
+	switch (event) {
+	case MSM_PCM_RT_EVT_DEVSWITCH:
+		q6asm_cmd(pcm->audio_client, CMD_PAUSE);
+		q6asm_cmd(pcm->audio_client, CMD_FLUSH);
+		q6asm_run(pcm->audio_client, 0, 0, 0);
+	default:
+		break;
+	}
+}
+
+static void msm_pcm_loopback_event_handler(uint32_t opcode, uint32_t token,
+					   uint32_t *payload, void *priv)
+{
+	pr_debug("%s\n", __func__);
+	switch (opcode) {
+	case APR_BASIC_RSP_RESULT: {
+		switch (payload[0]) {
+			break;
+		default:
+			break;
+		}
+	}
+		break;
+	default:
+		pr_err("Not Supported Event opcode[0x%x]\n", opcode);
+		break;
+	}
+}
+
+static int pcm_loopback_set_volume(struct msm_pcm_loopback *prtd, int volume)
+{
+	int rc = -EINVAL;
+
+	pr_debug("%s Setting volume 0x%x\n", __func__, volume);
+
+	if (prtd && prtd->audio_client) {
+		rc = q6asm_set_volume(prtd->audio_client, volume);
+		if (rc < 0) {
+			pr_err("%s: Send Volume command failed rc = %d\n",
+				__func__, rc);
+			return rc;
+		}
+		prtd->volume = volume;
+	}
+	return rc;
+}
+
+static int msm_pcm_open(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+	struct msm_pcm_loopback *pcm;
+	int ret = 0;
+	uint16_t bits_per_sample = 16;
+	struct msm_pcm_routing_evt event;
+
+	pcm = dev_get_drvdata(rtd->platform->dev);
+	mutex_lock(&pcm->lock);
+
+	snd_soc_set_runtime_hwparams(substream, &dummy_pcm_hardware);
+	pcm->volume = 0x2000;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		pcm->playback_substream = substream;
+	else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+		pcm->capture_substream = substream;
+
+	pcm->instance++;
+	dev_dbg(rtd->platform->dev, "%s: pcm out open: %d,%d\n", __func__,
+			pcm->instance, substream->stream);
+	if (pcm->instance == 2) {
+		struct snd_soc_pcm_runtime *soc_pcm_rx =
+				pcm->playback_substream->private_data;
+		struct snd_soc_pcm_runtime *soc_pcm_tx =
+				pcm->capture_substream->private_data;
+		if (pcm->audio_client != NULL)
+			stop_pcm(pcm);
+
+		pcm->audio_client = q6asm_audio_client_alloc(
+				(app_cb)msm_pcm_loopback_event_handler, pcm);
+		if (!pcm->audio_client) {
+			dev_err(rtd->platform->dev,
+				"%s: Could not allocate memory\n", __func__);
+			mutex_unlock(&pcm->lock);
+			return -ENOMEM;
+		}
+		pcm->session_id = pcm->audio_client->session;
+		pcm->audio_client->perf_mode = false;
+		ret = q6asm_open_loopback_v2(pcm->audio_client,
+					     bits_per_sample);
+		if (ret < 0) {
+			dev_err(rtd->platform->dev,
+				"%s: pcm out open failed\n", __func__);
+			q6asm_audio_client_free(pcm->audio_client);
+			mutex_unlock(&pcm->lock);
+			return -ENOMEM;
+		}
+		event.event_func = msm_pcm_route_event_handler;
+		event.priv_data = (void *) pcm;
+		msm_pcm_routing_reg_phy_stream(soc_pcm_tx->dai_link->be_id,
+			pcm->audio_client->perf_mode,
+			pcm->session_id, pcm->capture_substream->stream);
+		msm_pcm_routing_reg_phy_stream_v2(soc_pcm_rx->dai_link->be_id,
+			pcm->audio_client->perf_mode,
+			pcm->session_id, pcm->playback_substream->stream,
+			event);
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+			pcm->playback_substream = substream;
+			ret = pcm_loopback_set_volume(pcm, pcm->volume);
+			if (ret < 0)
+				dev_err(rtd->platform->dev,
+					"Error %d setting volume", ret);
+		}
+	}
+	dev_info(rtd->platform->dev, "%s: Instance = %d, Stream ID = %s\n",
+			__func__ , pcm->instance, substream->pcm->id);
+	runtime->private_data = pcm;
+
+	mutex_unlock(&pcm->lock);
+
+	return 0;
+}
+
+static void stop_pcm(struct msm_pcm_loopback *pcm)
+{
+	struct snd_soc_pcm_runtime *soc_pcm_rx =
+		pcm->playback_substream->private_data;
+	struct snd_soc_pcm_runtime *soc_pcm_tx =
+		pcm->capture_substream->private_data;
+
+	if (pcm->audio_client == NULL)
+		return;
+	q6asm_cmd(pcm->audio_client, CMD_CLOSE);
+
+	msm_pcm_routing_dereg_phy_stream(soc_pcm_rx->dai_link->be_id,
+			SNDRV_PCM_STREAM_PLAYBACK);
+	msm_pcm_routing_dereg_phy_stream(soc_pcm_tx->dai_link->be_id,
+			SNDRV_PCM_STREAM_CAPTURE);
+	q6asm_audio_client_free(pcm->audio_client);
+	pcm->audio_client = NULL;
+}
+
+static int msm_pcm_close(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct msm_pcm_loopback *pcm = runtime->private_data;
+	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+	int ret = 0;
+
+	mutex_lock(&pcm->lock);
+
+	dev_dbg(rtd->platform->dev, "%s: end pcm call:%d\n",
+		__func__, substream->stream);
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		pcm->playback_start = 0;
+	else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+		pcm->capture_start = 0;
+
+	pcm->instance--;
+	if (!pcm->playback_start || !pcm->capture_start) {
+		dev_dbg(rtd->platform->dev, "%s: end pcm call\n", __func__);
+		stop_pcm(pcm);
+	}
+
+	mutex_unlock(&pcm->lock);
+	return ret;
+}
+
+static int msm_pcm_prepare(struct snd_pcm_substream *substream)
+{
+	int ret = 0;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct msm_pcm_loopback *pcm = runtime->private_data;
+	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+
+	mutex_lock(&pcm->lock);
+
+	dev_dbg(rtd->platform->dev, "%s: ASM loopback stream:%d\n",
+		__func__, substream->stream);
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		if (!pcm->playback_start)
+			pcm->playback_start = 1;
+	} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+		if (!pcm->capture_start)
+			pcm->capture_start = 1;
+	}
+	mutex_unlock(&pcm->lock);
+
+	return ret;
+}
+
+static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct msm_pcm_loopback *pcm = runtime->private_data;
+	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		dev_dbg(rtd->platform->dev,
+			"%s: playback_start:%d,capture_start:%d\n", __func__,
+			pcm->playback_start, pcm->capture_start);
+		if (pcm->playback_start && pcm->capture_start)
+			q6asm_run_nowait(pcm->audio_client, 0, 0, 0);
+		break;
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+	case SNDRV_PCM_TRIGGER_STOP:
+		dev_dbg(rtd->platform->dev,
+			"%s:Pause/Stop - playback_start:%d,capture_start:%d\n",
+			__func__, pcm->playback_start, pcm->capture_start);
+		if (pcm->playback_start && pcm->capture_start)
+			q6asm_cmd_nowait(pcm->audio_client, CMD_PAUSE);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
+			     struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+
+	dev_dbg(rtd->platform->dev, "%s: ASM loopback\n", __func__);
+
+	return snd_pcm_lib_alloc_vmalloc_buffer(substream,
+		params_buffer_bytes(params));
+}
+
+static int msm_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+	return snd_pcm_lib_free_vmalloc_buffer(substream);
+}
+
+static struct snd_pcm_ops msm_pcm_ops = {
+	.open           = msm_pcm_open,
+	.hw_params      = msm_pcm_hw_params,
+	.hw_free        = msm_pcm_hw_free,
+	.close          = msm_pcm_close,
+	.prepare        = msm_pcm_prepare,
+	.trigger        = msm_pcm_trigger,
+};
+
+static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	int rc = 0;
+	struct snd_pcm_volume *vol = kcontrol->private_data;
+	struct snd_pcm_substream *substream = vol->pcm->streams[0].substream;
+	struct msm_pcm_loopback *prtd = substream->runtime->private_data;
+	int volume = ucontrol->value.integer.value[0];
+
+	rc = pcm_loopback_set_volume(prtd, volume);
+	return rc;
+}
+
+static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_pcm *pcm = rtd->pcm->streams[0].pcm;
+	struct snd_pcm_volume *volume_info;
+	struct snd_kcontrol *kctl;
+	int ret = 0;
+
+	dev_dbg(rtd->dev, "%s, Volume cntrl add\n", __func__);
+	ret = snd_pcm_add_volume_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+				      NULL, 1,
+				      rtd->dai_link->be_id,
+				      &volume_info);
+	if (ret < 0)
+		return ret;
+	kctl = volume_info->kctl;
+	kctl->put = msm_pcm_volume_ctl_put;
+	kctl->tlv.p = loopback_rx_vol_gain;
+	return 0;
+}
+
+static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_card *card = rtd->card->snd_card;
+	int ret = 0;
+
+	if (!card->dev->coherent_dma_mask)
+		card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
+
+	ret = msm_pcm_add_controls(rtd);
+	if (ret)
+		dev_err(rtd->dev, "%s, kctl add failed\n", __func__);
+	return ret;
+}
+
+static struct snd_soc_platform_driver msm_soc_platform = {
+	.ops            = &msm_pcm_ops,
+	.pcm_new        = msm_asoc_pcm_new,
+};
+
+static __devinit int msm_pcm_probe(struct platform_device *pdev)
+{
+	struct msm_pcm_loopback *pcm;
+
+	dev_set_name(&pdev->dev, "%s", "msm-pcm-loopback");
+	dev_dbg(&pdev->dev, "%s: dev name %s\n",
+		__func__, dev_name(&pdev->dev));
+
+	pcm = kzalloc(sizeof(struct msm_pcm_loopback), GFP_KERNEL);
+	if (!pcm) {
+		dev_err(&pdev->dev, "%s Failed to allocate memory for pcm\n",
+			__func__);
+		return -ENOMEM;
+	} else {
+		mutex_init(&pcm->lock);
+		dev_set_drvdata(&pdev->dev, pcm);
+	}
+	return snd_soc_register_platform(&pdev->dev,
+				   &msm_soc_platform);
+}
+
+static int msm_pcm_remove(struct platform_device *pdev)
+{
+	struct msm_pcm_loopback *pcm;
+
+	pcm = dev_get_drvdata(&pdev->dev);
+	mutex_destroy(&pcm->lock);
+	kfree(pcm);
+
+	snd_soc_unregister_platform(&pdev->dev);
+	return 0;
+}
+
+static const struct of_device_id msm_pcm_loopback_dt_match[] = {
+	{.compatible = "qti,msm-pcm-loopback"},
+	{}
+};
+
+static struct platform_driver msm_pcm_driver = {
+	.driver = {
+		.name = "msm-pcm-loopback",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_pcm_loopback_dt_match,
+	},
+	.probe = msm_pcm_probe,
+	.remove = __devexit_p(msm_pcm_remove),
+};
+
+static int __init msm_soc_platform_init(void)
+{
+	return platform_driver_register(&msm_pcm_driver);
+}
+module_init(msm_soc_platform_init);
+
+static void __exit msm_soc_platform_exit(void)
+{
+	platform_driver_unregister(&msm_pcm_driver);
+}
+module_exit(msm_soc_platform_exit);
+
+MODULE_DESCRIPTION("PCM loopback platform driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index dc41948..f25f746 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -109,6 +109,25 @@
 	.mask = 0,
 };
 
+static void msm_pcm_route_event_handler(enum msm_pcm_routing_event event,
+					void *priv_data)
+{
+	struct msm_audio *prtd = priv_data;
+
+	BUG_ON(!prtd);
+
+	pr_debug("%s: event %x\n", __func__, event);
+
+	switch (event) {
+	case MSM_PCM_RT_EVT_BUF_RECFG:
+		q6asm_cmd(prtd->audio_client, CMD_PAUSE);
+		q6asm_cmd(prtd->audio_client, CMD_FLUSH);
+		q6asm_run(prtd->audio_client, 0, 0, 0);
+	default:
+		break;
+	}
+}
+
 static void event_handler(uint32_t opcode,
 		uint32_t token, uint32_t *payload, void *priv)
 {
@@ -151,18 +170,31 @@
 		pr_debug("token = 0x%08x\n", token);
 		in_frame_info[token][0] = payload[4];
 		in_frame_info[token][1] = payload[5];
-		prtd->pcm_irq_pos += in_frame_info[token][0];
-		pr_debug("pcm_irq_pos=%d\n", prtd->pcm_irq_pos);
-		if (atomic_read(&prtd->start))
-			snd_pcm_period_elapsed(substream);
-		if (atomic_read(&prtd->in_count) <= prtd->periods)
-			atomic_inc(&prtd->in_count);
-		wake_up(&the_locks.read_wait);
-		if (prtd->mmap_flag
-			&& q6asm_is_cpu_buf_avail_nolock(OUT,
+		/* assume data size = 0 during flushing */
+		if (in_frame_info[token][0]) {
+			prtd->pcm_irq_pos += in_frame_info[token][0];
+			pr_debug("pcm_irq_pos=%d\n", prtd->pcm_irq_pos);
+			if (atomic_read(&prtd->start))
+				snd_pcm_period_elapsed(substream);
+			if (atomic_read(&prtd->in_count) <= prtd->periods)
+				atomic_inc(&prtd->in_count);
+			wake_up(&the_locks.read_wait);
+			if (prtd->mmap_flag &&
+			    q6asm_is_cpu_buf_avail_nolock(OUT,
 				prtd->audio_client,
 				&size, &idx))
-			q6asm_read_nolock(prtd->audio_client);
+				q6asm_read_nolock(prtd->audio_client);
+		} else {
+			pr_debug("%s: reclaim flushed buf in_count %x\n",
+				__func__, atomic_read(&prtd->in_count));
+			atomic_inc(&prtd->in_count);
+			if (atomic_read(&prtd->in_count) == prtd->periods) {
+				pr_info("%s: reclaimed all bufs\n", __func__);
+				if (atomic_read(&prtd->start))
+					snd_pcm_period_elapsed(substream);
+				wake_up(&the_locks.read_wait);
+			}
+		}
 		break;
 	}
 	case APR_BASIC_RSP_RESULT: {
@@ -681,6 +713,7 @@
 	int dir, ret;
 	struct msm_plat_data *pdata;
 	uint16_t bits_per_sample = 16;
+	struct msm_pcm_routing_evt event;
 
 	pdata = (struct msm_plat_data *)
 				dev_get_drvdata(soc_prtd->platform->dev);
@@ -737,9 +770,12 @@
 		pr_debug("%s: session ID %d\n",
 				__func__, prtd->audio_client->session);
 		prtd->session_id = prtd->audio_client->session;
-		msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->be_id,
+		event.event_func = msm_pcm_route_event_handler;
+		event.priv_data = (void *) prtd;
+		msm_pcm_routing_reg_phy_stream_v2(soc_prtd->dai_link->be_id,
 				prtd->audio_client->perf_mode,
-				prtd->session_id, substream->stream);
+				prtd->session_id, substream->stream,
+				event);
 	}
 
 	ret = q6asm_audio_client_buf_alloc_contiguous(dir,
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 8a9a877..711291da 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -50,10 +50,21 @@
 	unsigned int  format;
 };
 
+struct msm_pcm_routing_fdai_data {
+	u16 be_srate; /* track prior backend sample rate for flushing purpose */
+	int strm_id; /* ASM stream ID */
+	struct msm_pcm_routing_evt event_info;
+};
+
 #define INVALID_SESSION -1
 #define SESSION_TYPE_RX 0
 #define SESSION_TYPE_TX 1
 
+#define EC_PORT_ID_PRIMARY_MI2S_TX    1
+#define EC_PORT_ID_SECONDARY_MI2S_TX  2
+#define EC_PORT_ID_TERTIARY_MI2S_TX   3
+#define EC_PORT_ID_QUATERNARY_MI2S_TX 4
+
 static struct mutex routing_lock;
 
 static int fm_switch_enable;
@@ -63,6 +74,7 @@
 static int slim0_rx_aanc_fb_port;
 static int msm_route_ec_ref_rx = 3; /* NONE */
 static uint32_t voc_session_id = ALL_SESSION_VSID;
+static int msm_route_ext_ec_ref = AFE_PORT_INVALID;
 
 enum {
 	MADNONE,
@@ -244,25 +256,35 @@
 
 
 /* Track ASM playback & capture sessions of DAI */
-static int fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = {
+static struct msm_pcm_routing_fdai_data
+	fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = {
 	/* MULTIMEDIA1 */
-	{INVALID_SESSION, INVALID_SESSION},
+	{{0, INVALID_SESSION, {NULL, NULL} },
+	{0, INVALID_SESSION, {NULL, NULL} } },
 	/* MULTIMEDIA2 */
-	{INVALID_SESSION, INVALID_SESSION},
+	{{0, INVALID_SESSION, {NULL, NULL} },
+	{0, INVALID_SESSION, {NULL, NULL} } },
 	/* MULTIMEDIA3 */
-	{INVALID_SESSION, INVALID_SESSION},
+	{{0, INVALID_SESSION, {NULL, NULL} },
+	{0, INVALID_SESSION, {NULL, NULL} } },
 	/* MULTIMEDIA4 */
-	{INVALID_SESSION, INVALID_SESSION},
+	{{0, INVALID_SESSION, {NULL, NULL} },
+	{0, INVALID_SESSION,  {NULL, NULL} } },
 	/* MULTIMEDIA5 */
-	{INVALID_SESSION, INVALID_SESSION},
+	{{0, INVALID_SESSION, {NULL, NULL} },
+	{0, INVALID_SESSION, {NULL, NULL} } },
 	/* MULTIMEDIA6 */
-	{INVALID_SESSION, INVALID_SESSION},
-	/* MULTIMEDIA7 */
-	{INVALID_SESSION, INVALID_SESSION},
+	{{0, INVALID_SESSION, {NULL, NULL} },
+	{0, INVALID_SESSION, {NULL, NULL} } },
+	/* MULTIMEDIA7*/
+	{{0, INVALID_SESSION, {NULL, NULL} },
+	{0, INVALID_SESSION, {NULL, NULL} } },
 	/* MULTIMEDIA8 */
-	{INVALID_SESSION, INVALID_SESSION},
+	{{0, INVALID_SESSION, {NULL, NULL} },
+	{0, INVALID_SESSION, {NULL, NULL} } },
 	/* MULTIMEDIA9 */
-	{INVALID_SESSION, INVALID_SESSION},
+	{{0, INVALID_SESSION, {NULL, NULL} },
+	{0, INVALID_SESSION, {NULL, NULL} } },
 };
 
 /* Track performance mode of all front-end multimedia sessions.
@@ -328,7 +350,7 @@
 
 	mutex_lock(&routing_lock);
 
-	fe_dai_map[fedai_id][session_type] = dspst_id;
+	fe_dai_map[fedai_id][session_type].strm_id = dspst_id;
 	for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
 		if (!is_be_dai_extproc(i) &&
 		    (afe_get_port_type(msm_bedais[i].port_id) == port_type) &&
@@ -370,7 +392,7 @@
 	mutex_lock(&routing_lock);
 
 	payload.num_copps = 0; /* only RX needs to use payload */
-	fe_dai_map[fedai_id][session_type] = dspst_id;
+	fe_dai_map[fedai_id][session_type].strm_id = dspst_id;
 	fe_dai_perf_mode[fedai_id][session_type] = perf_mode;
 
 	/* re-enable EQ if active */
@@ -429,6 +451,19 @@
 	mutex_unlock(&routing_lock);
 }
 
+void msm_pcm_routing_reg_phy_stream_v2(int fedai_id, bool perf_mode,
+				       int dspst_id, int stream_type,
+				       struct msm_pcm_routing_evt event_info)
+{
+	msm_pcm_routing_reg_phy_stream(fedai_id, perf_mode, dspst_id,
+				       stream_type);
+
+	if (stream_type == SNDRV_PCM_STREAM_PLAYBACK)
+		fe_dai_map[fedai_id][SESSION_TYPE_RX].event_info = event_info;
+	else
+		fe_dai_map[fedai_id][SESSION_TYPE_TX].event_info = event_info;
+}
+
 void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type)
 {
 	int i, port_type, session_type, path_type, topology;
@@ -464,8 +499,8 @@
 		}
 	}
 
-	fe_dai_map[fedai_id][session_type] = INVALID_SESSION;
-
+	fe_dai_map[fedai_id][session_type].strm_id = INVALID_SESSION;
+	fe_dai_map[fedai_id][session_type].be_srate = 0;
 	mutex_unlock(&routing_lock);
 }
 
@@ -491,6 +526,7 @@
 	int session_type, path_type, port_id, topology;
 	u32 channels;
 	uint16_t bits_per_sample = 16;
+	struct msm_pcm_routing_fdai_data *fdai;
 
 	pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
 
@@ -517,10 +553,23 @@
 			(msm_bedais[reg].port_id == VOICE2_PLAYBACK_TX)))
 			voc_start_playback(set, msm_bedais[reg].port_id);
 		set_bit(val, &msm_bedais[reg].fe_sessions);
-		if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
+		fdai = &fe_dai_map[val][session_type];
+		if (msm_bedais[reg].active && fdai->strm_id !=
 			INVALID_SESSION) {
 
 			channels = msm_bedais[reg].channel;
+			if (session_type == SESSION_TYPE_TX &&
+			    fdai->be_srate &&
+			    (fdai->be_srate != msm_bedais[reg].sample_rate)) {
+				pr_debug("%s: flush strm %d diff BE rates\n",
+					__func__, fdai->strm_id);
+
+				if (fdai->event_info.event_func)
+					fdai->event_info.event_func(
+						MSM_PCM_RT_EVT_BUF_RECFG,
+						fdai->event_info.priv_data);
+				fdai->be_srate = 0; /* might not need it */
+			}
 			if (msm_bedais[reg].format == SNDRV_PCM_FORMAT_S24_LE)
 				bits_per_sample = 24;
 
@@ -543,8 +592,14 @@
 				msm_bedais[reg].sample_rate, channels,
 				topology, false, bits_per_sample);
 
+			if (session_type == SESSION_TYPE_RX &&
+			    fdai->event_info.event_func)
+				fdai->event_info.event_func(
+					MSM_PCM_RT_EVT_DEVSWITCH,
+					fdai->event_info.priv_data);
+
 			msm_pcm_routing_build_matrix(val,
-				fe_dai_map[val][session_type], path_type,
+				fdai->strm_id, path_type,
 				fe_dai_perf_mode[val][session_type]);
 			port_id = srs_port_id = msm_bedais[reg].port_id;
 			srs_send_params(srs_port_id, 1, 0);
@@ -560,7 +615,8 @@
 			(msm_bedais[reg].port_id == VOICE2_PLAYBACK_TX)))
 			voc_start_playback(set, msm_bedais[reg].port_id);
 		clear_bit(val, &msm_bedais[reg].fe_sessions);
-		if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
+		fdai = &fe_dai_map[val][session_type];
+		if (msm_bedais[reg].active && fdai->strm_id !=
 			INVALID_SESSION) {
 			adm_close(msm_bedais[reg].port_id,
 				  fe_dai_perf_mode[val][session_type]);
@@ -568,7 +624,7 @@
 			    (fe_dai_perf_mode[val][session_type] == false))
 				dolby_dap_deinit(msm_bedais[reg].port_id);
 			msm_pcm_routing_build_matrix(val,
-				fe_dai_map[val][session_type], path_type,
+				fdai->strm_id, path_type,
 				fe_dai_perf_mode[val][session_type]);
 		}
 	}
@@ -1197,12 +1253,12 @@
 static void msm_send_eq_values(int eq_idx)
 {
 	int result;
-	struct audio_client *ac =
-		q6asm_get_audio_client(fe_dai_map[eq_idx][SESSION_TYPE_RX]);
+	struct audio_client *ac = q6asm_get_audio_client(
+				  fe_dai_map[eq_idx][SESSION_TYPE_RX].strm_id);
 
 	if (ac == NULL) {
 		pr_err("%s: Could not get audio client for session: %d\n",
-		      __func__, fe_dai_map[eq_idx][SESSION_TYPE_RX]);
+		      __func__, fe_dai_map[eq_idx][SESSION_TYPE_RX].strm_id);
 		goto done;
 	}
 
@@ -1369,6 +1425,76 @@
 		     msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put),
 };
 
+static int msm_routing_ext_ec_get(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s: ext_ec_ref_rx  = %x\n", __func__, msm_route_ext_ec_ref);
+
+	mutex_lock(&routing_lock);
+	ucontrol->value.integer.value[0] = msm_route_ext_ec_ref;
+	mutex_unlock(&routing_lock);
+	return 0;
+}
+
+static int msm_routing_ext_ec_put(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
+	int mux = ucontrol->value.enumerated.item[0];
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	int ret = 0;
+	bool state = false;
+
+	pr_debug("%s: msm_route_ec_ref_rx = %d value = %ld\n",
+		 __func__, msm_route_ext_ec_ref,
+		 ucontrol->value.integer.value[0]);
+
+	mutex_lock(&routing_lock);
+	switch (ucontrol->value.integer.value[0]) {
+	case EC_PORT_ID_PRIMARY_MI2S_TX:
+		msm_route_ext_ec_ref = AFE_PORT_ID_PRIMARY_MI2S_TX;
+		state = true;
+		break;
+	case EC_PORT_ID_SECONDARY_MI2S_TX:
+		msm_route_ext_ec_ref = AFE_PORT_ID_SECONDARY_MI2S_TX;
+		state = true;
+		break;
+	case EC_PORT_ID_TERTIARY_MI2S_TX:
+		msm_route_ext_ec_ref = AFE_PORT_ID_TERTIARY_MI2S_TX;
+		state = true;
+		break;
+	case EC_PORT_ID_QUATERNARY_MI2S_TX:
+		msm_route_ext_ec_ref = AFE_PORT_ID_QUATERNARY_MI2S_TX;
+		state = true;
+		break;
+	default:
+		msm_route_ext_ec_ref = AFE_PORT_INVALID;
+		break;
+	}
+	if (voc_set_ext_ec_ref(msm_route_ext_ec_ref, state)) {
+		mutex_unlock(&routing_lock);
+		snd_soc_dapm_mux_update_power(widget, kcontrol, 1, mux, e);
+	} else {
+		ret = -EINVAL;
+		mutex_unlock(&routing_lock);
+	}
+	return ret;
+}
+
+static const char * const ext_ec_ref_rx[] = {"NONE", "PRI_MI2S_TX",
+					     "SEC_MI2S_TX", "TERT_MI2S_TX",
+					     "QUAT_MI2S_TX"};
+
+static const struct soc_enum msm_route_ext_ec_ref_rx_enum[] = {
+	SOC_ENUM_SINGLE_EXT(5, ext_ec_ref_rx),
+};
+
+static const struct snd_kcontrol_new voc_ext_ec_mux =
+	SOC_DAPM_ENUM_EXT("VOC_EXT_EC MUX Mux", msm_route_ext_ec_ref_rx_enum[0],
+			  msm_routing_ext_ec_get, msm_routing_ext_ec_put);
+
+
 static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = {
 	SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_I2S_RX ,
 	MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
@@ -1958,6 +2084,15 @@
 };
 
 
+static const struct snd_kcontrol_new mmul6_mixer_controls[] = {
+	SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+};
+
 static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = {
 	SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_PRI_I2S_RX,
 	MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
@@ -2964,6 +3099,7 @@
 	SND_SOC_DAPM_AIF_OUT("MM_UL4", "MultiMedia4 Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("MM_UL5", "MultiMedia5 Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("MM_UL9", "MultiMedia9 Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("CS-VOICE_DL1", "CS-VOICE Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("CS-VOICE_UL1", "CS-VOICE Capture", 0, 0, 0, 0),
@@ -2992,6 +3128,10 @@
 		0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture",
 		0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_IN("INTHFP_DL_HL", "INT_HFP_BT_HOSTLESS Playback",
+		0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("INTHFP_UL_HL", "INT_HFP_BT_HOSTLESS Capture",
+		0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("HDMI_DL_HL", "HDMI_HOSTLESS Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("SEC_I2S_DL_HL", "SEC_I2S_RX_HOSTLESS Playback",
 		0, 0, 0, 0),
@@ -3142,6 +3282,8 @@
 	mmul5_mixer_controls, ARRAY_SIZE(mmul5_mixer_controls)),
 	SND_SOC_DAPM_MIXER("MultiMedia8 Mixer", SND_SOC_NOPM, 0, 0,
 	mmul8_mixer_controls, ARRAY_SIZE(mmul8_mixer_controls)),
+	SND_SOC_DAPM_MIXER("MultiMedia6 Mixer", SND_SOC_NOPM, 0, 0,
+	mmul6_mixer_controls, ARRAY_SIZE(mmul6_mixer_controls)),
 	SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
 	auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)),
 	SND_SOC_DAPM_MIXER("SEC_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
@@ -3263,6 +3405,8 @@
 
 	SND_SOC_DAPM_MUX("SLIM0_RX_VI_FB_LCH_MUX", SND_SOC_NOPM, 0, 0,
 				&slim0_rx_vi_fb_lch_mux),
+	SND_SOC_DAPM_MUX("VOC_EXT_EC MUX", SND_SOC_NOPM, 0, 0,
+			 &voc_ext_ec_mux),
 
 };
 
@@ -3396,6 +3540,7 @@
 	{"MultiMedia2 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
 	{"MultiMedia1 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
 	{"MultiMedia1 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+	{"MultiMedia6 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
 
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
@@ -3406,6 +3551,7 @@
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia9", "MM_DL9"},
+	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia6", "MM_UL6"},
 	{"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"},
 
 	{"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -3438,6 +3584,7 @@
 	{"MultiMedia4 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
 	{"MultiMedia5 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
 	{"MultiMedia8 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
+	{"MultiMedia6 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
 
 	{"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"},
 	{"MultiMedia4 Mixer", "AFE_PCM_TX", "PCM_TX"},
@@ -3449,6 +3596,7 @@
 	{"MM_UL4", NULL, "MultiMedia4 Mixer"},
 	{"MM_UL5", NULL, "MultiMedia5 Mixer"},
 	{"MM_UL8", NULL, "MultiMedia8 Mixer"},
+	{"MM_UL6", NULL, "MultiMedia6 Mixer"},
 
 	{"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
@@ -3563,6 +3711,12 @@
 	{"MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"},
 	{"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"},
 
+	{"VOC_EXT_EC MUX", "PRI_MI2S_TX" , "PRI_MI2S_TX"},
+	{"VOC_EXT_EC MUX", "SEC_MI2S_TX" , "SEC_MI2S_TX"},
+	{"VOC_EXT_EC MUX", "TERT_MI2S_TX" , "TERT_MI2S_TX"},
+	{"VOC_EXT_EC MUX", "QUAT_MI2S_TX" , "QUAT_MI2S_TX"},
+	{"CS-VOICE_UL1", NULL, "VOC_EXT_EC MUX"},
+
 	{"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"},
 	{"Voice_Tx Mixer", "PRI_MI2S_TX_Voice", "PRI_MI2S_TX"},
 	{"Voice_Tx Mixer", "MI2S_TX_Voice", "MI2S_TX"},
@@ -3632,6 +3786,8 @@
 
 	{"INT_FM_RX", NULL, "INTFM_DL_HL"},
 	{"INTFM_UL_HL", NULL, "INT_FM_TX"},
+	{"INTHFP_UL_HL", NULL, "INT_BT_SCO_TX"},
+	{"INT_BT_SCO_RX", NULL, "MM_DL6"},
 	{"AUX_PCM_RX", NULL, "AUXPCM_DL_HL"},
 	{"AUXPCM_UL_HL", NULL, "AUX_PCM_TX"},
 	{"MI2S_RX", NULL, "MI2S_DL_HL"},
@@ -3797,7 +3953,9 @@
 	mutex_lock(&routing_lock);
 	topology = get_topology(path_type);
 	for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) {
-		if (fe_dai_map[i][session_type] != INVALID_SESSION) {
+		if (fe_dai_map[i][session_type].strm_id != INVALID_SESSION) {
+			fe_dai_map[i][session_type].be_srate =
+				bedai->sample_rate;
 			adm_close(bedai->port_id,
 				  fe_dai_perf_mode[i][session_type]);
 			srs_port_id = -1;
@@ -3824,6 +3982,7 @@
 	u32 channels;
 	bool playback, capture;
 	uint16_t bits_per_sample = 16;
+	struct msm_pcm_routing_fdai_data *fdai;
 
 	if (be_id >= MSM_BACKEND_DAI_MAX) {
 		pr_err("%s: unexpected be_id %d\n", __func__, be_id);
@@ -3855,8 +4014,21 @@
 	capture = substream->stream == SNDRV_PCM_STREAM_CAPTURE;
 
 	for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) {
-		if (fe_dai_map[i][session_type] != INVALID_SESSION) {
+		fdai = &fe_dai_map[i][session_type];
+		if (fdai->strm_id != INVALID_SESSION) {
+			if (session_type == SESSION_TYPE_TX &&
+			    fdai->be_srate &&
+			    (fdai->be_srate != bedai->sample_rate)) {
+				pr_debug("%s: flush strm %d diff BE rates\n",
+					__func__,
+					fdai->strm_id);
 
+				if (fdai->event_info.event_func)
+					fdai->event_info.event_func(
+						MSM_PCM_RT_EVT_BUF_RECFG,
+						fdai->event_info.priv_data);
+				fdai->be_srate = 0; /* might not need it */
+			}
 			channels = bedai->channel;
 			if (bedai->format == SNDRV_PCM_FORMAT_S24_LE)
 				bits_per_sample = 24;
@@ -3883,7 +4055,7 @@
 			}
 
 			msm_pcm_routing_build_matrix(i,
-				fe_dai_map[i][session_type], path_type,
+				fdai->strm_id, path_type,
 				fe_dai_perf_mode[i][session_type]);
 			port_id = srs_port_id = bedai->port_id;
 			srs_send_params(srs_port_id, 1, 0);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
index 10be150..4f7c4e3 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
@@ -133,6 +133,12 @@
 	MSM_BACKEND_DAI_MAX,
 };
 
+enum msm_pcm_routing_event {
+	MSM_PCM_RT_EVT_BUF_RECFG,
+	MSM_PCM_RT_EVT_DEVSWITCH,
+	MSM_PCM_RT_EVT_MAX,
+};
+
 /* dai_id: front-end ID,
  * dspst_id:  DSP audio stream ID
  * stream_type: playback or capture
@@ -142,6 +148,15 @@
 void msm_pcm_routing_reg_psthr_stream(int fedai_id, int dspst_id,
 		int stream_type);
 
+struct msm_pcm_routing_evt {
+	void (*event_func)(enum msm_pcm_routing_event, void *);
+	void *priv_data;
+};
+
+void msm_pcm_routing_reg_phy_stream_v2(int fedai_id, bool perf_mode,
+				       int dspst_id, int stream_type,
+				       struct msm_pcm_routing_evt event_info);
+
 void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type);
 
 int msm_routing_check_backend_enabled(int fedai_id);
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 95114e0..631e9bd 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -1256,6 +1256,7 @@
 		case ASM_STREAM_CMD_OPEN_READ_V3:
 		case ASM_STREAM_CMD_OPEN_WRITE_V3:
 		case ASM_STREAM_CMD_OPEN_READWRITE_V2:
+		case ASM_STREAM_CMD_OPEN_LOOPBACK_V2:
 		case ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2:
 		case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
 		case ASM_CMD_ADD_TOPOLOGIES:
@@ -1744,6 +1745,7 @@
 			rc);
 		goto fail_cmd;
 	}
+	ac->io_mode |= TUN_READ_IO_MODE;
 	return 0;
 fail_cmd:
 	return -EINVAL;
@@ -1837,6 +1839,7 @@
 			rc);
 		goto fail_cmd;
 	}
+	ac->io_mode |= TUN_WRITE_IO_MODE;
 	return 0;
 fail_cmd:
 	return -EINVAL;
@@ -1977,6 +1980,49 @@
 	return -EINVAL;
 }
 
+int q6asm_open_loopback_v2(struct audio_client *ac, uint16_t bits_per_sample)
+{
+	int rc = 0x00;
+	struct asm_stream_cmd_open_loopback_v2 open;
+
+	if ((ac == NULL) || (ac->apr == NULL)) {
+		pr_err("%s APR handle NULL\n", __func__);
+		return -EINVAL;
+	}
+	pr_debug("%s: session[%d]", __func__, ac->session);
+
+	q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
+	open.hdr.opcode = ASM_STREAM_CMD_OPEN_LOOPBACK_V2;
+
+	open.mode_flags = 0;
+	open.src_endpointype = 0;
+	open.sink_endpointype = 0;
+	/* source endpoint : matrix */
+	open.postprocopo_id = get_asm_topology();
+	if (open.postprocopo_id == 0)
+		open.postprocopo_id = DEFAULT_POPP_TOPOLOGY;
+	open.bits_per_sample = bits_per_sample;
+	open.reserved = 0;
+
+	rc = apr_send_pkt(ac->apr, (uint32_t *) &open);
+	if (rc < 0) {
+		pr_err("%s open failed op[0x%x]rc[%d]\n", __func__,
+				open.hdr.opcode, rc);
+		goto fail_cmd;
+	}
+
+	rc = wait_event_timeout(ac->cmd_wait,
+			(atomic_read(&ac->cmd_state) == 0), 5*HZ);
+	if (!rc) {
+		pr_err("%s timeout. waited for open_loopback rc[%d]\n",
+				__func__, rc);
+		goto fail_cmd;
+	}
+	return 0;
+fail_cmd:
+	return -EINVAL;
+}
+
 int q6asm_run(struct audio_client *ac, uint32_t flags,
 		uint32_t msw_ts, uint32_t lsw_ts)
 {
@@ -4217,9 +4263,11 @@
 {
 	int cnt = 0;
 	int loopcnt = 0;
+	int used;
 	struct audio_port_data *port = NULL;
 
 	if (ac->io_mode & SYNC_IO_MODE) {
+		used = (ac->io_mode & TUN_WRITE_IO_MODE ? 1 : 0);
 		mutex_lock(&ac->cmd_lock);
 		for (loopcnt = 0; loopcnt <= OUT; loopcnt++) {
 			port = &ac->port[loopcnt];
@@ -4229,7 +4277,7 @@
 			while (cnt >= 0) {
 				if (!port->buf)
 					continue;
-				port->buf[cnt].used = 1;
+				port->buf[cnt].used = used;
 				cnt--;
 			}
 		}
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 673ecff..c4395c2 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -350,6 +350,11 @@
 				NULL : &common.voice[idx]);
 }
 
+static bool is_voice_session(u32 session_id)
+{
+	return (session_id == common.voice[VOC_PATH_PASSIVE].session_id);
+}
+
 static bool is_voip_session(u32 session_id)
 {
 	return (session_id == common.voice[VOC_PATH_FULL].session_id);
@@ -1861,10 +1866,18 @@
 
 	cvp_setdev_cmd.cvp_set_device_v2.tx_port_id = v->dev_tx.port_id;
 	cvp_setdev_cmd.cvp_set_device_v2.rx_port_id = v->dev_rx.port_id;
-	cvp_setdev_cmd.cvp_set_device_v2.vocproc_mode =
+
+	if (common.ec_ref_ext) {
+		cvp_setdev_cmd.cvp_set_device_v2.vocproc_mode =
+				VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING;
+		cvp_setdev_cmd.cvp_set_device_v2.ec_ref_port_id =
+				common.ec_port_id;
+	} else {
+		cvp_setdev_cmd.cvp_set_device_v2.vocproc_mode =
 				    VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING;
-	cvp_setdev_cmd.cvp_set_device_v2.ec_ref_port_id =
+		cvp_setdev_cmd.cvp_set_device_v2.ec_ref_port_id =
 				    VSS_IVOCPROC_PORT_ID_NONE;
+	}
 	pr_debug("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
 		cvp_setdev_cmd.cvp_set_device_v2.tx_topology_id,
 		cvp_setdev_cmd.cvp_set_device_v2.tx_port_id,
@@ -3026,10 +3039,17 @@
 	cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.port_id;
 	cvp_session_cmd.cvp_session.profile_id =
 					 VSS_ICOMMON_CAL_NETWORK_ID_NONE;
-	cvp_session_cmd.cvp_session.vocproc_mode =
+	if (common.ec_ref_ext) {
+		cvp_session_cmd.cvp_session.vocproc_mode =
+				VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING;
+		cvp_session_cmd.cvp_session.ec_ref_port_id =
+					common.ec_port_id;
+	} else {
+		cvp_session_cmd.cvp_session.vocproc_mode =
 				 VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING;
-	cvp_session_cmd.cvp_session.ec_ref_port_id =
+		cvp_session_cmd.cvp_session.ec_ref_port_id =
 						 VSS_IVOCPROC_PORT_ID_NONE;
+	}
 
 	pr_debug("tx_topology: %d tx_port_id=%d, rx_port_id=%d, mode: 0x%x\n",
 		cvp_session_cmd.cvp_session.tx_topology_id,
@@ -4257,8 +4277,10 @@
 		v = voice_get_session(voc_get_session_id(VOICE_SESSION_NAME));
 	else if (port_id == VOICE2_PLAYBACK_TX)
 		v = voice_get_session(voc_get_session_id(VOICE2_SESSION_NAME));
+	else
+		pr_err("%s: Invalid port_id 0x%x", __func__, port_id);
 
-	if (v != NULL) {
+	while (v != NULL) {
 		mutex_lock(&v->lock);
 		v->music_info.port_id = port_id;
 		v->music_info.play_enable = set;
@@ -4278,8 +4300,17 @@
 		}
 
 		mutex_unlock(&v->lock);
-	} else {
-		pr_err("%s: Invalid port_id 0x%x", __func__, port_id);
+
+		/* Voice and VoLTE call use the same pseudo port and hence
+		 * use the same mixer control. So enable incall delivery
+		 * for VoLTE as well with Voice.
+		 */
+		if (is_voice_session(v->session_id)) {
+			v = voice_get_session(voc_get_session_id(
+							VOLTE_SESSION_NAME));
+		} else {
+			break;
+		}
 	}
 
 	return ret;
@@ -4313,7 +4344,8 @@
 
 		v->voc_state = VOC_CHANGE;
 	}
-
+	if (common.ec_ref_ext)
+		voc_set_ext_ec_ref(AFE_PORT_INVALID, false);
 fail:	mutex_unlock(&v->lock);
 
 	return ret;
@@ -4756,6 +4788,8 @@
 
 		ret = -EINVAL;
 	}
+	if (common.ec_ref_ext)
+		voc_set_ext_ec_ref(AFE_PORT_INVALID, false);
 
 	mutex_unlock(&v->lock);
 	return ret;
@@ -4973,6 +5007,28 @@
 	return ret;
 }
 
+int voc_set_ext_ec_ref(uint16_t port_id, bool state)
+{
+	int ret = 0;
+
+	mutex_lock(&common.common_lock);
+	if (state == true) {
+		if (port_id == AFE_PORT_INVALID) {
+			pr_err("%s: Invalid port id", __func__);
+			ret = -EINVAL;
+			goto exit;
+		}
+		common.ec_port_id = port_id;
+		common.ec_ref_ext = true;
+	} else {
+		common.ec_ref_ext = false;
+		common.ec_port_id = port_id;
+	}
+exit:
+	mutex_unlock(&common.common_lock);
+	return ret;
+}
+
 void voc_register_mvs_cb(ul_cb_fn ul_cb,
 			   dl_cb_fn dl_cb,
 			   void *private_data)
@@ -5807,7 +5863,7 @@
 	common.default_vol_step_val = 0;
 	common.default_vol_ramp_duration_ms = DEFAULT_VOLUME_RAMP_DURATION;
 	common.default_mute_ramp_duration_ms = DEFAULT_MUTE_RAMP_DURATION;
-
+	common.ec_ref_ext = false;
 	/* Initialize MVS info. */
 	common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
 
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index 39f0986..5c0cf21 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.h
@@ -1328,6 +1328,8 @@
 	uint32_t default_vol_step_val;
 	uint32_t default_vol_ramp_duration_ms;
 	uint32_t default_mute_ramp_duration_ms;
+	bool ec_ref_ext;
+	uint16_t ec_port_id;
 
 	/* APR to MVM in the Q6 */
 	void *apr_q6_mvm;
@@ -1462,5 +1464,6 @@
 int voc_start_playback(uint32_t set, uint16_t port_id);
 int voc_start_record(uint32_t port_id, uint32_t set, uint32_t session_id);
 int voice_get_idx_for_session(u32 session_id);
+int voc_set_ext_ec_ref(uint16_t port_id, bool state);
 
 #endif
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index bc3f6a7..63bbbdd 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1922,7 +1922,7 @@
 {
 	struct snd_soc_card *card = widget->dapm->card;
 	int ret;
-	mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
+	mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_PCM);
 	ret = soc_dapm_mux_update_power(widget, kcontrol, change, mux, e);
 	mutex_unlock(&card->dapm_mutex);
 	return ret;
@@ -1970,7 +1970,7 @@
 {
 	struct snd_soc_card *card = widget->dapm->card;
 	int ret;
-	mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
+	mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_PCM);
 	ret = soc_dapm_mixer_update_power(widget, kcontrol, connect);
 	mutex_unlock(&card->dapm_mutex);
 	return ret;
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 9eb96e5..60a401a 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -36,6 +36,7 @@
 int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type,
 		     struct snd_soc_jack *jack)
 {
+	mutex_init(&jack->mutex);
 	jack->codec = codec;
 	INIT_LIST_HEAD(&jack->pins);
 	INIT_LIST_HEAD(&jack->jack_zones);
@@ -75,7 +76,7 @@
 	codec = jack->codec;
 	dapm =  &codec->dapm;
 
-	mutex_lock(&codec->mutex);
+	mutex_lock(&jack->mutex);
 
 	oldstatus = jack->status;
 
@@ -109,7 +110,7 @@
 	snd_jack_report(jack->jack, jack->status);
 
 out:
-	mutex_unlock(&codec->mutex);
+	mutex_unlock(&jack->mutex);
 }
 EXPORT_SYMBOL_GPL(snd_soc_jack_report);