Merge "ARM: dts: MSM: Remove flash source flash1 on 8x26"
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 99de826..9af81da 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 "qti,cpr-regulator"
+- compatible:			Must be "qcom,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,41 +22,41 @@
 				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
-- 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
+- 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
 				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.
-- 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
+- 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
 				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
-- 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)
+- 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)
 				occurred before issuing UP interrupt.
-- qti,cpr-timer-cons-down:	Consecutive number of timer interval (qti,cpr-timer-delay)
+- qcom,cpr-timer-cons-down:	Consecutive number of timer interval (qcom,cpr-timer-delay)
 				occurred before issuing DOWN interrupt.
-- 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
+- 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
 				to issue error_steps.
-- qti,cpr-up-threshold:	The threshold for CPR to issue interrupt when
+- qcom,cpr-up-threshold:	The threshold for CPR to issue interrupt when
 				error_steps is greater than it when stepping up.
-- qti,cpr-down-threshold:	The threshold for CPR to issue interrupt when
+- qcom,cpr-down-threshold:	The threshold for CPR to issue interrupt when
 				error_steps is greater than it when stepping down.
-- 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,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,pvs-fuse-redun-sel:	Array of 5 elements to indicate where to read the bits, what value to
+- qcom,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 and method to read fuse row, reading
 				register through SCM or directly. The 5 elements with index [0..4] are:
@@ -70,19 +70,19 @@
 				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.
+- qcom,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
 				  [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.
+- qcom,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
 				  [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
+- qcom,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 and method to read fuse row, using SCM
 				to read or read register directly. The 5 elements with index [0..4] are:
@@ -96,32 +96,32 @@
 				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
+- qcom,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.
+- qcom,cpr-fuse-bp-cpr-disable:	Bit position of the bit to indicate if CPR should be disable
+- qcom,cpr-fuse-bp-scheme:	Bit position of the bit to indicate if it's a global/local scheme
+- qcom,cpr-fuse-target-quot:	Array of bit positions in fuse for Target Quotient of all corners.
 				It should have index and value like this:
 				  [0] => bit position of the LSB bit for SVS target quotient
 				  [1] => bit position of the LSB bit for NOMINAL target quotient
 				  [2] => bit position of the LSB bit for TURBO target quotient
-- qti,cpr-fuse-ro-sel:		Array of bit positions in fuse for RO select of all corners.
+- qcom,cpr-fuse-ro-sel:		Array of bit positions in fuse for RO select of all corners.
 				It should have index and value like this:
 				  [0] => bit position of the LSB bit for SVS RO select bits
 				  [1] => bit position of the LSB bit for NOMINAL RO select bits
 				  [2] => bit position of the LSB bit for TURBO RO select bits
-- qti,cpr-fuse-redun-row:	Array of row number of redundant CPR fuse and method to read that
+- qcom,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.
+- qcom,cpr-fuse-redun-target-quot:	Array of bit positions in fuse for redundant Target Quotient of all corners.
 				It should have index and value like this:
 				  [0] => bit position of the LSB bit for redundant SVS target quotient
 				  [1] => bit position of the LSB bit for redundant NOMINAL target quotient
 				  [2] => bit position of the LSB bit for redundant TURBO target quotient
-- qti,cpr-fuse-redun-ro-sel:	Array of bit positions in eFuse for redundant RO select.
+- qcom,cpr-fuse-redun-ro-sel:	Array of bit positions in eFuse for redundant RO select.
 				It should have index and value like this:
 				  [0] => bit position of the LSB bit for redundant SVS RO select bits
 				  [1] => bit position of the LSB bit for redundant NOMINAL RO select bits
@@ -131,23 +131,23 @@
 Optional properties:
 - vdd-mx-supply:		Regulator to supply memory power as dependency
 				of VDD APC.
-- qti,vdd-mx-vmax:		The maximum voltage in uV for vdd-mx-supply. This
+- qcom,vdd-mx-vmax:		The maximum voltage in uV for vdd-mx-supply. This
 				is required when vdd-mx-supply is present.
-- qti,vdd-mx-vmin-method:	The method to determine the minimum voltage for
+- qcom,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 qti,vdd-mx-vmax
+				  3 => equal to qcom,vdd-mx-vmax
 				This is required when vdd-mx-supply is present.
-- 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
+- qcom,cpr-fuse-redun-bp-cpr-disable:	Redundant bit position of the bit to indicate if CPR should be disable
+- qcom,cpr-fuse-redun-bp-scheme:	Redundant bit position of the bit to indicate if it's a global/local scheme
 					This property is required if cpr-fuse-redun-bp-cpr-disable
 					is present, and vise versa.
-- qti,cpr-enable:		Present: CPR enabled by default.
+- qcom,cpr-enable:		Present: CPR enabled by default.
 				Not Present: CPR disable by default.
-- qti,cpr-fuse-cond-min-volt-sel:	Array of 5 elements to indicate where to read the bits,  what value to
+- qcom,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:
@@ -159,11 +159,11 @@
 				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
+				using "qcom,cpr-cond-min-voltage".
+- qcom,cpr-cond-min-voltage:	Minimum voltage in microvolts for SVS, NOM and TURBO mode if the fuse bits
+				defined in qcom,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
+- qcom,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:
@@ -175,7 +175,7 @@
 				[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,
+- qcom,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;
@@ -183,36 +183,45 @@
 				[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,
+- qcom,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
+- qcom,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
+- qcom,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
+- qcom,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.
+- qcom,cpr-quot-adjust-table:	Array of triples in which each triple indicates the speed bin of the CPU, the virtual
+				corner to use and the quotient adjustment.
+				The 3 elements in one triple are:
+				[0]: => the speed bin of the CPU.
+				[1]: => the virtual voltage corner to use.
+				[2]: => the quotient adjustment for the corresponding virtual corner.
+				If the speed bin in a triple is equal to the speed bin of the CPU, the adjustment would
+				be subtracted from the quotient value of the voltage corner when the CPU is running at
+				that virtual corner. Each virtual corner value must be in the range 1 to the number of
+				elements in qcom,cpr-corner-map.
+- qcom,cpr-corner-map:		Array of elements of fuse corner value for each virtual corner.
+				The location or 1-based index of an element in the list corresponds to
+				the virtual corner value. For example, the first element in the list is the fuse corner
+				value that virtual corner 1 maps to.
+				This is required if qcom,cpr-quot-adjust-table is present.
+- qcom,cpr-quotient-adjustment:	Present: CPR adjusts quotient value. The
+				adjustment equals to the quotient adjustment
+				in millivolts multiply the KV value.
+				Not Present: CPR will not adjust quotient value.
 
 Example:
 	apc_vreg_corner: regulator@f9018000 {
 		status = "okay";
-		compatible = "qti,cpr-regulator";
+		compatible = "qcom,cpr-regulator";
 		reg = <0xf9018000 0x1000>, <0xfc4b8000 0x1000>;
 		reg-names = "rbcpr", "efuse_addr";
 		interrupts = <0 15 0>;
@@ -220,11 +229,11 @@
 		regulator-min-microvolt = <1>;
 		regulator-max-microvolt = <3>;
 
-		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-fuse = <22 6 5 1>;
+		qcom,pvs-fuse-redun-sel = <22 24 3 2 1>;
+		qcom,pvs-fuse-redun = <22 27 5 1>;
 
-		qti,pvs-init-voltage = <1330000 1330000 1330000 1320000
+		qcom,pvs-init-voltage = <1330000 1330000 1330000 1320000
 						1310000 1300000 1290000 1280000
 						1270000 1260000 1250000 1240000
 						1230000 1220000 1210000 1200000
@@ -232,47 +241,48 @@
 						1150000 1140000 1140000 1140000
 						1140000 1140000 1140000 1140000
 						1140000 1140000 1140000 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>;
+		qcom,pvs-corner-ceiling-slow = <1050000 1160000 1275000>;
+		qcom,pvs-corner-ceiling-nom  =  <975000 1075000 1200000>;
+		qcom,pvs-corner-ceiling-fast =  <900000 1000000 1140000>;
 		vdd-apc-supply = <&pm8226_s2>;
 		vdd-mx-supply = <&pm8226_l3_ao>;
-		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,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,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>;
+		qcom,cpr-fuse-row = <138 1>;
+		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 1>;
+		qcom,cpr-fuse-redun-row = <139 1>;
+		qcom,cpr-fuse-redun-target-quot = <24 12 0>;
+		qcom,cpr-fuse-redun-ro-sel = <46 36 39>;
+		qcom,cpr-fuse-cond-min-volt-sel = <54 42 6 7 1>;
+		qcom,cpr-cond-min-voltage = <1140000>;
+		qcom,cpr-fuse-uplift-sel = <22 53 1 0 0>;
+		qcom,cpr-uplift-voltage = <50000>;
+		qcom,cpr-uplift-quotient = <0 0 120>;
+		qcom,cpr-uplift-max-volt = <1350000>;
+		qcom,cpr-uplift-speed-bin = <1>;
+		qcom,speed-bin-fuse-sel = <22 0 3 0>;
+		qcom,cpr-corner-map = <1 1 2 2 3 3 3 3 3 3 3 3>;
+		qcom,cpr-quot-adjust-table = <1 1 0>, <1 2 0>, <1 3 0>,
+						<1 4 0>, <1 5 450>, <1 6 375>,
+						<1 7 300>, <1 8 225>, <1 9 187>,
+						<1 10 150>, <1 11 75>, <1 12 0>;
 	};
 
diff --git a/Documentation/devicetree/bindings/arm/msm/cpubw.txt b/Documentation/devicetree/bindings/arm/msm/cpubw.txt
new file mode 100644
index 0000000..1dc3835
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/cpubw.txt
@@ -0,0 +1,30 @@
+MSM CPU bandwidth device
+
+cpubw is a device that represents the CPU subsystem master ports in a MSM SoC
+and the related info that is needed to make CPU to DDR bandwidth votes.
+
+Required properties:
+- compatible:		Must be "qcom,cpubw"
+- qcom,cpu-mem-ports:	A list of tuples where each tuple consists of a bus
+			master (CPU subsystem) port number and a bus slave
+			(memory) port number.
+- qcom,bw-tbl:		A list of meaningful instantaneous bandwidth values
+			(in MB/s) that can be requested from the CPU
+			subsystem to DDR. The list of values depend on the
+			supported DDR frequencies and the bus widths.
+
+Example:
+
+	qcom,cpubw {
+		compatible = "qcom,cpubw";
+		qcom,cpu-mem-ports = <1 512>, <2 512>;
+		qcom,bw-tbl =
+			<  572 /*  75 MHz */ >,
+			< 1144 /* 150 MHz */ >,
+			< 1525 /* 200 MHz */ >,
+			< 2342 /* 307 MHz */ >,
+			< 3509 /* 460 MHz */ >,
+			< 4684 /* 614 MHz */ >,
+			< 6103 /* 800 MHz */ >,
+			< 7102 /* 931 MHz */ >;
+	};
diff --git a/Documentation/devicetree/bindings/arm/msm/msm-cpufreq.txt b/Documentation/devicetree/bindings/arm/msm/msm-cpufreq.txt
index 02514d4..fed49c9 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm-cpufreq.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm-cpufreq.txt
@@ -9,23 +9,15 @@
 - compatible:		Must be "qcom,msm-cpufreq"
 - qcom,cpufreq-table:	A list of tuples where each tuple consists of a
 			usable CPU frequency (KHz), an optional cache
-			frequency (KHz) and an optional memory bandwidth
+			frequency (KHz) and a mandatory memory bandwidth
 			value (MBPS) listed in that order.  The cache
 			frequencies shall not be listed if the device cannot
-			run the cache asynchronous to one or more CPUs. The
-			memory bandwidth values shall not be listed if the
-			optional cpu-mem-ports property is not supplied.
-
-Optional properties:
-- qcom,cpu-mem-ports:	A list of tuples where each tuple consists of a bus
-			master (CPU) port number and a bus slave (memory)
-			port number.
+			run the cache asynchronous to one or more CPUs.
 
 Example:
 	qcom,msm-cpufreq@0 {
 		regs = <0 4>
 		compatible = "qcom,msm-cpufreq";
-		qcom,cpu-mem-ports = <1 512>, <2 513>;
 		qcom,cpufreq-table =
 			<  300000  300000  600 >,
 			<  422400  422400 1200 >,
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/fb/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
index 0e236f2..113ded8 100644
--- a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
@@ -142,6 +142,8 @@
 					0 = default value.
 - qcom,mdss-dsi-bl-max-level:		Specifies the max backlight level supported by the panel.
 					255 = default value.
+- qcom,mdss-brightness-max-level:	Specifies the max brightness level supported.
+					255 = default value.
 - qcom,mdss-dsi-interleave-mode:	Specifies interleave mode.
 					0 = default value.
 - qcom,mdss-dsi-panel-type:		Specifies the panel operating mode.
diff --git a/Documentation/devicetree/bindings/fb/mdss-edp.txt b/Documentation/devicetree/bindings/fb/mdss-edp.txt
index 2070c64..fd8d14f 100644
--- a/Documentation/devicetree/bindings/fb/mdss-edp.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-edp.txt
@@ -26,6 +26,8 @@
 
 Optional properties:
 - qcom,cont-splash-enabled:             Boolean used to enable continuous splash mode.
+- qcom,mdss-brightness-max-level:	Specifies the max brightness level supported.
+					255 = default value.
 
 Example:
 	mdss_edp: qcom,mdss_edp@fd923400 {
diff --git a/Documentation/devicetree/bindings/hwmon/qpnp-adc-voltage.txt b/Documentation/devicetree/bindings/hwmon/qpnp-adc-voltage.txt
index ae7d039..1be5504 100644
--- a/Documentation/devicetree/bindings/hwmon/qpnp-adc-voltage.txt
+++ b/Documentation/devicetree/bindings/hwmon/qpnp-adc-voltage.txt
@@ -65,6 +65,8 @@
 			3 : Returns current across 0.1 ohm resistor.
 			4 : Returns XO thermistor voltage in degree's Centigrade.
 			5 : Returns result in degC for 150k pull-up.
+			9 : Conversion to temperature based on -15~55 allowable
+			    battery charging tempeature setting for btm parameters.
 - qcom,hw-settle-time : Settling period for the channel before ADC read.
 			Select from the following unsigned int.
 			0 : 0us
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index 56bdc59..6277054 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -4,23 +4,29 @@
 
 Required properties:
 
- - compatible : "qcom,msm-pcm-dsp"
+ - compatible : "qti,msm-pcm-dsp"
 
- - qcom,msm-pcm-dsp-id : device node id
+ - qti,msm-pcm-dsp-id : device node id
 
 * msm-pcm-low-latency
 
 Required properties:
 
- - compatible : "qcom,msm-pcm-dsp"
+ - compatible : "qti,msm-pcm-dsp"
 
- - qcom,msm-pcm-dsp-id : device node id
+ - qti,msm-pcm-dsp-id : device node id
 
    Optional properties
 
-      - qcom,msm-pcm-low-latency : Flag indicating whether
+      - qti,msm-pcm-low-latency : Flag indicating whether
         the device node is of type low latency.
 
+      - qti,latency-level : Flag indicating whether the device node
+                            is of type regular low latency or ultra
+                            low latency.
+                            regular : regular low latency stream
+                            ultra : ultra low latency stream
+
 * msm-pcm-routing
 
 Required properties:
@@ -102,6 +108,12 @@
 
  - compatible : "qcom,msm-lsm-client"
 
+* msm-pcm-loopback
+
+Required properties:
+
+ - compatible : "qti,msm-pcm-loopback"
+
 * msm-dai-q6
 
 [First Level Nodes]
@@ -220,16 +232,16 @@
 
 Example:
 
-        qcom,msm-pcm {
-		compatible = "qcom,msm-pcm-dsp";
-		qcom,msm-pcm-dsp-id = <0>;
+	qti,msm-pcm {
+		compatible = "qti,msm-pcm-dsp";
+		qti,msm-pcm-dsp-id = <0>;
 	};
 
-	qcom,msm-pcm-low-latency {
-		compatible = "qcom,msm-pcm-dsp";
-		qcom,msm-pcm-dsp-id = <1>;
-		qcom,msm-pcm-low-latency;
-        };
+	qti,msm-pcm-low-latency {
+		compatible = "qti,msm-pcm-dsp";
+		qti,msm-pcm-dsp-id = <1>;
+		qti,msm-pcm-low-latency;
+	};
 
         qcom,msm-pcm-routing {
                 compatible = "qcom,msm-pcm-routing";
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/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/msm8226-regulator.dtsi b/arch/arm/boot/dts/msm8226-regulator.dtsi
index 63da606..0146367 100644
--- a/arch/arm/boot/dts/msm8226-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8226-regulator.dtsi
@@ -30,74 +30,76 @@
 &soc {
 	apc_vreg_corner: regulator@f9018000 {
 		status = "okay";
-		compatible = "qti,cpr-regulator";
+		compatible = "qcom,cpr-regulator";
 		reg = <0xf9018000 0x1000>, <0xf9011064 4>, <0xfc4b8000 0x1000>;
 		reg-names = "rbcpr", "rbcpr_clk", "efuse_addr";
 		interrupts = <0 15 0>;
 		regulator-name = "apc_corner";
 		regulator-min-microvolt = <1>;
-		regulator-max-microvolt = <3>;
+		regulator-max-microvolt = <12>;
 
-		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-fuse-redun-sel = <22 24 3 2 0>;
+		qcom,pvs-fuse = <22 6 5 0>;
+		qcom,pvs-fuse-redun = <22 27 5 0>;
 
-		qti,pvs-init-voltage = <1275000 1275000 1275000 1275000 1275000
+		qcom,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>;
-		qti,pvs-corner-ceiling-slow = <1050000 1150000 1275000>;
-		qti,pvs-corner-ceiling-nom  = <1050000 1075000 1200000>;
-		qti,pvs-corner-ceiling-fast = <1050000 1050000 1100000>;
+		qcom,pvs-corner-ceiling-slow = <1050000 1150000 1275000>;
+		qcom,pvs-corner-ceiling-nom  = <1050000 1075000 1200000>;
+		qcom,pvs-corner-ceiling-fast = <1050000 1050000 1100000>;
 		vdd-apc-supply = <&pm8226_s2>;
 
 		vdd-mx-supply = <&pm8226_l3_ao>;
-		qti,vdd-mx-vmax = <1350000>;
-		qti,vdd-mx-vmin-method = <1>;
+		qcom,vdd-mx-vmax = <1350000>;
+		qcom,vdd-mx-vmin-method = <1>;
 
-		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-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-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-fuse-redun-sel = <138 57 1 1 0>;
+		qcom,cpr-fuse-row = <138 0>;
+		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 0>;
+		qcom,cpr-fuse-redun-target-quot = <24 12 0>;
+		qcom,cpr-fuse-redun-ro-sel = <46 36 39>;
 
-		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>;
+		qcom,cpr-enable;
+		qcom,cpr-fuse-cond-min-volt-sel = <54 42 6 7 1>;
+		qcom,cpr-cond-min-voltage = <1140000>;
+		qcom,cpr-fuse-uplift-sel = <22 53 1 0 0>;
+		qcom,cpr-uplift-voltage = <50000>;
+		qcom,cpr-uplift-quotient = <0 0 120>;
+		qcom,cpr-uplift-max-volt = <1350000>;
+		qcom,cpr-uplift-speed-bin = <1>;
+		qcom,speed-bin-fuse-sel = <22 0 3 0>;
+		qcom,cpr-corner-map = <1 1 2 2 3 3 3 3 3 3 3 3>;
+		qcom,cpr-quot-adjust-table =
+					<1 5 450>,
+					<1 6 375>,
+					<1 7 300>,
+					<1 8 225>,
+					<1 9 187>,
+					<1 10 150>,
+					<1 11 75>;
 	};
 };
 
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 ddba542..089d415 100644
--- a/arch/arm/boot/dts/msm8226-v2.dtsi
+++ b/arch/arm/boot/dts/msm8226-v2.dtsi
@@ -52,20 +52,20 @@
 };
 
 &apc_vreg_corner {
-	qti,pvs-init-voltage = <1330000 1330000 1330000 1320000 1310000
+	qcom,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>;
-	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>;
+	qcom,pvs-corner-ceiling-slow = <1050000 1150000 1280000>;
+	qcom,pvs-corner-ceiling-nom  = <1050000 1080000 1200000>;
+	qcom,pvs-corner-ceiling-fast = <1050000 1050000 1100000>;
+	qcom,cpr-step-quotient = <30>;
+	qcom,cpr-up-threshold = <0>;
+	qcom,cpr-down-threshold = <5>;
+	qcom,cpr-apc-volt-step = <10000>;
 };
 
 &msm_gpu {
@@ -80,39 +80,46 @@
 		reg-names = "rcg-base", "efuse";
 		qcom,speed0-bin-v2 =
 			<         0 0>,
-			< 384000000 1>,
-			< 787200000 2>,
-			<1190400000 3>;
+			< 384000000 2>,
+			< 787200000 4>,
+			<1190400000 7>;
 		qcom,speed6-bin-v2 =
 			<         0 0>,
-			< 384000000 1>,
-			< 787200000 2>,
-			<1190400000 3>;
+			< 384000000 2>,
+			< 787200000 4>,
+			<1190400000 7>;
 		qcom,speed2-bin-v2 =
 			<         0 0>,
-			< 384000000 1>,
-			< 787200000 2>,
-			<1401600000 3>;
+			< 384000000 2>,
+			< 787200000 4>,
+			<1401600000 10>;
 		qcom,speed5-bin-v2 =
 			<         0 0>,
-			< 384000000 1>,
-			< 787200000 2>,
-			<1401600000 3>;
+			< 384000000 2>,
+			< 787200000 4>,
+			<1401600000 10>;
 		qcom,speed4-bin-v2 =
 			<         0 0>,
-			< 384000000 1>,
-			< 787200000 2>,
-			<149700000 3>;
+			< 384000000 2>,
+			< 787200000 4>,
+			<1401600000 10>;
 		qcom,speed7-bin-v2 =
 			<         0 0>,
-			< 384000000 1>,
-			< 787200000 2>,
-			<1497600000 3>;
+			< 384000000 2>,
+			< 787200000 4>,
+			<1401600000 10>;
 		qcom,speed1-bin-v2 =
 			<         0 0>,
-			< 384000000 1>,
-			< 787200000 2>,
-			<1593600000 3>;
+			< 384000000 2>,
+			< 787200000 4>,
+			< 998400000 5>,
+			<1094400000 6>,
+			<1190400000 7>,
+			<1305600000 8>,
+			<1344000000 9>,
+			<1401600000 10>,
+			<1497600000 11>,
+			<1593600000 12>;
 	};
 };
 
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index 1250ed2..e0304f5 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -429,19 +429,20 @@
 		qcom,tapan-codec-9302;
 	};
 
-	qcom,msm-pcm {
-		compatible = "qcom,msm-pcm-dsp";
-		qcom,msm-pcm-dsp-id = <0>;
+	qti,msm-pcm {
+		compatible = "qti,msm-pcm-dsp";
+		qti,msm-pcm-dsp-id = <0>;
 	};
 
 	qcom,msm-pcm-routing {
 		compatible = "qcom,msm-pcm-routing";
 	};
 
-	qcom,msm-pcm-low-latency {
-		compatible = "qcom,msm-pcm-dsp";
-		qcom,msm-pcm-dsp-id = <1>;
-		qcom,msm-pcm-low-latency;
+	qti,msm-pcm-low-latency {
+		compatible = "qti,msm-pcm-dsp";
+		qti,msm-pcm-dsp-id = <1>;
+		qti,msm-pcm-low-latency;
+		qti,latency-level = "regular";
 	};
 
 	qcom,msm-pcm-lpa {
@@ -1010,30 +1011,39 @@
 		clock-names = "clk-4", "clk-5";
 		qcom,speed0-bin-v0 =
 			<         0 0>,
-			< 384000000 1>,
-			< 787200000 2>,
-			<1190400000 3>;
+			< 384000000 2>,
+			< 787200000 4>,
+			<1190400000 7>;
 
 		cpu-vdd-supply = <&apc_vreg_corner>;
 	};
 
+	qcom,cpubw {
+		compatible = "qcom,cpubw";
+		qcom,cpu-mem-ports = <1 512>;
+		qcom,bw-tbl =
+			< 1525 /* 200 MHz */ >,
+			< 2441 /* 320 MHz */ >,
+			< 3051 /* 400 MHz */ >,
+			< 4066 /* 533 MHz */ >;
+	};
+
 	qcom,msm-cpufreq@0 {
 		reg = <0 4>;
 		compatible = "qcom,msm-cpufreq";
-		qcom,cpu-mem-ports = <1 512>;
 		qcom,cpufreq-table =
-			<  300000 1600 /* 200 MHz */ >,
-			<  384000 1600 /* 200 MHz */ >,
-			<  600000 3200 /* 320 MHz */ >,
-			<  787200 4264 /* 533 MHz */ >,
-			<  998400 4264 /* 533 MHz */ >,
-			< 1094400 4264 /* 533 MHz */ >,
-			< 1190400 4264 /* 533 MHz */ >,
-			< 1305600 4264 /* 533 MHz */ >,
-			< 1344000 4264 /* 533 MHz */ >,
-			< 1401600 4264 /* 533 MHz */ >,
-			< 1497600 4264 /* 533 MHz */ >,
-			< 1593600 4264 /* 533 MHz */ >;
+			<  300000 1525 >,
+			<  384000 1525 >,
+			<  600000 1525 >,
+			<  787200 3051 >,
+			<  998400 4066 >,
+			< 1094400 4066 >,
+			< 1190400 4066 >,
+			< 1305600 4066 >,
+			< 1344000 4066 >,
+			< 1401600 4066 >,
+			< 1497600 4066 >,
+			< 1593600 4066 >;
 	};
 
 	qcom,ocmem@fdd00000 {
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-regulator.dtsi b/arch/arm/boot/dts/msm8610-regulator.dtsi
index f9bafb4..1340612 100644
--- a/arch/arm/boot/dts/msm8610-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8610-regulator.dtsi
@@ -30,61 +30,62 @@
 &soc {
 	apc_vreg_corner: regulator@f9018000 {
 		status = "okay";
-		compatible = "qti,cpr-regulator";
+		compatible = "qcom,cpr-regulator";
 		reg = <0xf9018000 0x1000>, <0xf9011064 4>, <0xfc4b8000 0x1000>;
 		reg-names = "rbcpr", "rbcpr_clk", "efuse_addr";
 		interrupts = <0 15 0>;
 		regulator-name = "apc_corner";
 		regulator-min-microvolt = <1>;
-		regulator-max-microvolt = <3>;
+		regulator-max-microvolt = <12>;
 
-		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-fuse-redun-sel = <53 25 3 2 1>;
+		qcom,pvs-fuse = <23 6 5 1>;
+		qcom,pvs-fuse-redun = <61 47 5 1>;
 
-		qti,pvs-init-voltage = <1275000 1275000 1275000 1275000 1275000
+		qcom,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>;
-		qti,pvs-corner-ceiling-slow = <1150000 1150000 1275000>;
-		qti,pvs-corner-ceiling-nom  = <1075000 1075000 1200000>;
-		qti,pvs-corner-ceiling-fast = <1050000 1050000 1140000>;
+		qcom,pvs-corner-ceiling-slow = <1050000 1150000 1275000>;
+		qcom,pvs-corner-ceiling-nom  = <1050000 1075000 1275000>;
+		qcom,pvs-corner-ceiling-fast = <1050000 1050000 1275000>;
 		vdd-apc-supply = <&pm8110_s2>;
 
 		vdd-mx-supply = <&pm8110_l3_ao>;
-		qti,vdd-mx-vmax = <1350000>;
-		qti,vdd-mx-vmin-method = <1>;
+		qcom,vdd-mx-vmax = <1350000>;
+		qcom,vdd-mx-vmin-method = <1>;
 
-		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-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-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-fuse-redun-sel = <53 25 3 2 1>;
+		qcom,cpr-fuse-row = <61 1>;
+		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 1>;
+		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>;
+		qcom,cpr-corner-map = <1 1 2 2 3 3 3 3 3 3 3 3>;
 
-		qti,cpr-enable;
+		qcom,cpr-enable;
 	};
 };
 
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-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.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index 94a9db0..558f8c2 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -535,6 +535,8 @@
 	i2c@f9924000 { /* BLSP-1 QUP-3 */
 		cell-index = <2>;
 		compatible = "qcom,i2c-qup";
+		#address-cells = <1>;
+		#size-cells = <0>;
 		reg-names = "qup_phys_addr";
 		reg = <0xf9924000 0x1000>;
 		interrupt-names = "qup_err_intr";
@@ -615,15 +617,16 @@
 		qcom,model = "msm8x10-snd-card";
 	};
 
-	qcom,msm-pcm {
-		compatible = "qcom,msm-pcm-dsp";
-		qcom,msm-pcm-dsp-id = <0>;
+	qti,msm-pcm {
+		compatible = "qti,msm-pcm-dsp";
+		qti,msm-pcm-dsp-id = <0>;
 	};
 
-	qcom,msm-pcm-low-latency {
-		compatible = "qcom,msm-pcm-dsp";
-		qcom,msm-pcm-dsp-id = <1>;
-		qcom,msm-pcm-low-latency;
+	qti,msm-pcm-low-latency {
+		compatible = "qti,msm-pcm-dsp";
+		qti,msm-pcm-dsp-id = <1>;
+		qti,msm-pcm-low-latency;
+		qti,latency-level = "ultra";
 	};
 
 	qcom,msm-pcm-routing {
diff --git a/arch/arm/boot/dts/msm8926-qrd-skug-pvt.dts b/arch/arm/boot/dts/msm8926-qrd-skug-pvt.dts
new file mode 100644
index 0000000..2a45592
--- /dev/null
+++ b/arch/arm/boot/dts/msm8926-qrd-skug-pvt.dts
@@ -0,0 +1,27 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/include/ "msm8926-qrd-skug.dtsi"
+
+/ {
+	model = "Qti MSM 8926 QRD SKUG PVT";
+	compatible = "qcom,msm8926-qrd", "qcom,msm8926", "qcom,qrd";
+	qcom,board-id = <0x2000b 5>;
+};
+
+&pm8226_vadc {
+	chan@30 {
+		label = "batt_therm";
+		qcom,scale-function = <9>;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8926-qrd-skug.dts b/arch/arm/boot/dts/msm8926-qrd-skug.dts
index 15a2d58..4aab4f9 100644
--- a/arch/arm/boot/dts/msm8926-qrd-skug.dts
+++ b/arch/arm/boot/dts/msm8926-qrd-skug.dts
@@ -11,9 +11,7 @@
  */
 
 /dts-v1/;
-/include/ "msm8926.dtsi"
-/include/ "msm8226-qrd.dtsi"
-/include/ "msm8926-camera-sensor-qrd.dtsi"
+/include/ "msm8926-qrd-skug.dtsi"
 
 / {
 	model = "Qualcomm MSM 8926 QRD SKUG";
@@ -21,88 +19,3 @@
 	qcom,board-id = <11 5>;
 };
 
-&qrd_batterydata {
-	qcom,rpull-up-kohm = <100>;
-	qcom,vref-batt-therm = <1800000>;
-
-	/include/ "batterydata-qrd-4v2-2000mah.dtsi"
-};
-
-&pm8226_bms {
-	qcom,battery-data = <&qrd_batterydata>;
-};
-
-&pm8226_chg {
-	qcom,battery-data = <&qrd_batterydata>;
-};
-
-&soc {
-	i2c@f9927000 { /* BLSP1 QUP5 */
-		focaltech@38 {
-			compatible = "focaltech,5x06";
-			reg = <0x38>;
-			interrupt-parent = <&msmgpio>;
-			interrupts = <17 0x2>;
-			vdd-supply = <&pm8226_l19>;
-			vcc_i2c-supply = <&pm8226_lvs1>;
-			focaltech,name = "ft5336";
-			focaltech,family-id = <0x14>;
-			focaltech,reset-gpio = <&msmgpio 16 0x00>;
-			focaltech,irq-gpio = <&msmgpio 17 0x00>;
-			focaltech,display-coords = <0 0 720 1280>;
-			focaltech,panel-coords = <0 0 720 1400>;
-			focaltech,button-map= <139 102 158>;
-			focaltech,no-force-update;
-			focaltech,i2c-pull-up;
-			focaltech,group-id = <1>;
-			focaltech,hard-reset-delay-ms = <20>;
-			focaltech,soft-reset-delay-ms = <200>;
-			focaltech,num-max-touches = <5>;
-			focaltech,fw-name = "ft_8926_qrd_fw.bin";
-			focaltech,fw-delay-aa-ms = <30>;
-			focaltech,fw-delay-55-ms = <30>;
-			focaltech,fw-upgrade-id1 = <0x11>;
-			focaltech,fw-upgrade-id2 = <0x11>;
-			focaltech,fw-delay-readid-ms = <10>;
-			focaltech,fw-delay-era-flsh-ms = <2000>;
-			focaltech,fw-auto-cal;
-			focaltech,ignore-id-check;
-		};
-	};
-
-	gen-vkeys {
-		compatible = "qcom,gen-vkeys";
-		label = "ft5x06_ts";
-		qcom,disp-maxx = <720>;
-		qcom,disp-maxy = <1280>;
-		qcom,panel-maxx = <720>;
-		qcom,panel-maxy = <1404>;
-		qcom,key-codes = <139 172 158>;
-		qcom,y-offset = <0>;
-	};
-
-	gpio-leds {
-		compatible = "gpio-leds";
-		keypad-backlight {
-			gpios = <&msmgpio 34 0>;
-			label = "button-backlight";
-			linux,default-trigger = "none";
-		};
-	};
-};
-
-&spmi_bus {
-	qcom,pm8226@0 {
-		qcom,leds@a100 {
-			status = "disable";
-			};
-		};
-};
-
-&mdss_dsi0 {
-	qcom,dsi-pref-prim-pan = <&dsi_ssd2080m_720_vid>;
-};
-
-&dsi_ssd2080m_720_vid {
-	qcom,cont-splash-enabled;
-};
diff --git a/arch/arm/boot/dts/msm8926-qrd-skug.dtsi b/arch/arm/boot/dts/msm8926-qrd-skug.dtsi
new file mode 100644
index 0000000..fea5a9e
--- /dev/null
+++ b/arch/arm/boot/dts/msm8926-qrd-skug.dtsi
@@ -0,0 +1,101 @@
+/* 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/ "msm8926.dtsi"
+/include/ "msm8226-qrd.dtsi"
+/include/ "msm8926-camera-sensor-qrd.dtsi"
+
+&qrd_batterydata {
+	qcom,rpull-up-kohm = <100>;
+	qcom,vref-batt-therm = <1800000>;
+
+	/include/ "batterydata-qrd-4v2-2000mah.dtsi"
+};
+
+&pm8226_bms {
+	qcom,battery-data = <&qrd_batterydata>;
+};
+
+&pm8226_chg {
+	qcom,battery-data = <&qrd_batterydata>;
+};
+
+&soc {
+	i2c@f9927000 { /* BLSP1 QUP5 */
+		focaltech@38 {
+			compatible = "focaltech,5x06";
+			reg = <0x38>;
+			interrupt-parent = <&msmgpio>;
+			interrupts = <17 0x2>;
+			vdd-supply = <&pm8226_l19>;
+			vcc_i2c-supply = <&pm8226_lvs1>;
+			focaltech,name = "ft5336";
+			focaltech,family-id = <0x14>;
+			focaltech,reset-gpio = <&msmgpio 16 0x00>;
+			focaltech,irq-gpio = <&msmgpio 17 0x00>;
+			focaltech,display-coords = <0 0 720 1280>;
+			focaltech,panel-coords = <0 0 720 1400>;
+			focaltech,button-map= <139 102 158>;
+			focaltech,no-force-update;
+			focaltech,i2c-pull-up;
+			focaltech,group-id = <1>;
+			focaltech,hard-reset-delay-ms = <20>;
+			focaltech,soft-reset-delay-ms = <200>;
+			focaltech,num-max-touches = <5>;
+			focaltech,fw-name = "ft_8926_qrd_fw.bin";
+			focaltech,fw-delay-aa-ms = <30>;
+			focaltech,fw-delay-55-ms = <30>;
+			focaltech,fw-upgrade-id1 = <0x11>;
+			focaltech,fw-upgrade-id2 = <0x11>;
+			focaltech,fw-delay-readid-ms = <10>;
+			focaltech,fw-delay-era-flsh-ms = <2000>;
+			focaltech,fw-auto-cal;
+			focaltech,ignore-id-check;
+		};
+	};
+
+	gen-vkeys {
+		compatible = "qcom,gen-vkeys";
+		label = "ft5x06_ts";
+		qcom,disp-maxx = <720>;
+		qcom,disp-maxy = <1280>;
+		qcom,panel-maxx = <720>;
+		qcom,panel-maxy = <1404>;
+		qcom,key-codes = <139 172 158>;
+		qcom,y-offset = <0>;
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+		keypad-backlight {
+			gpios = <&msmgpio 34 0>;
+			label = "button-backlight";
+			linux,default-trigger = "none";
+		};
+	};
+};
+
+&spmi_bus {
+	qcom,pm8226@0 {
+		qcom,leds@a100 {
+			status = "disable";
+			};
+		};
+};
+
+&mdss_dsi0 {
+	qcom,dsi-pref-prim-pan = <&dsi_ssd2080m_720_vid>;
+};
+
+&dsi_ssd2080m_720_vid {
+	qcom,cont-splash-enabled;
+};
diff --git a/arch/arm/boot/dts/msm8926.dtsi b/arch/arm/boot/dts/msm8926.dtsi
index 0b876a1..963c1b8 100644
--- a/arch/arm/boot/dts/msm8926.dtsi
+++ b/arch/arm/boot/dts/msm8926.dtsi
@@ -39,10 +39,45 @@
 		vdd_mss-supply = <&pm8226_s5>;
 	};
 
-	qcom,acpuclk@f9011050 {
+	qcom,clock-a7@f9011050 {
 		reg =	<0xf9011050 0x8>,
 			<0xfc4b80b0 0x8>;
-		reg-names = "rcg_base", "pte_efuse";
+		reg-names = "rcg-base", "efuse";
+		qcom,speed0-bin-v1 =
+			<         0 0>,
+			< 384000000 1>,
+			< 787200000 2>,
+			<1190400000 3>;
+		qcom,speed6-bin-v1 =
+			<         0 0>,
+			< 384000000 1>,
+			< 787200000 2>,
+			<1190400000 3>;
+		qcom,speed2-bin-v1 =
+			<         0 0>,
+			< 384000000 1>,
+			< 787200000 2>,
+			<1401600000 3>;
+		qcom,speed5-bin-v1 =
+			<         0 0>,
+			< 384000000 1>,
+			< 787200000 2>,
+			<1401600000 3>;
+		qcom,speed4-bin-v1 =
+			<         0 0>,
+			< 384000000 1>,
+			< 787200000 2>,
+			<1401600000 3>;
+		qcom,speed7-bin-v1 =
+			<         0 0>,
+			< 384000000 1>,
+			< 787200000 2>,
+			<1401600000 3>;
+		qcom,speed1-bin-v1 =
+			<         0 0>,
+			< 384000000 1>,
+			< 787200000 2>,
+			<1593600000 3>;
 	};
 
 	qcom,msm-thermal {
@@ -116,20 +151,21 @@
 };
 
 &apc_vreg_corner {
-	qti,pvs-init-voltage = <1350000 1340000 1330000 1320000 1310000
+	qcom,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>;
-	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>;
+	qcom,pvs-corner-ceiling-slow = <1050000 1150000 1280000>;
+	qcom,pvs-corner-ceiling-nom  = <1050000 1080000 1200000>;
+	qcom,pvs-corner-ceiling-fast = <1050000 1050000 1100000>;
+	qcom,cpr-step-quotient = <30>;
+	qcom,cpr-up-threshold = <0>;
+	qcom,cpr-down-threshold = <1>;
+	qcom,cpr-apc-volt-step = <10000>;
+	qcom,cpr-quotient-adjustment = <96>;
 };
 
 &tsens {
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi
index 9d44bda..29e2aaa 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi
@@ -16,6 +16,7 @@
 		cell-index = <0>;
 		compatible = "qcom,camera-led-flash";
 		qcom,flash-type = <1>;
+		qcom,torch-source = <&pm8941_torch>;
 		qcom,flash-source = <&pm8941_flash0 &pm8941_flash1>;
 	};
 };
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 2ff92ed..e4dace1 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -1515,25 +1515,39 @@
 			< 2265600000  925000 691 >;
 	};
 
+	qcom,cpubw {
+		compatible = "qcom,cpubw";
+		qcom,cpu-mem-ports = <1 512>, <2 512>;
+		qcom,bw-tbl =
+			<  572 /*  75 MHz */ >,
+			< 1144 /* 150 MHz */ >,
+			< 1525 /* 200 MHz */ >,
+			< 2342 /* 307 MHz */ >,
+			< 3509 /* 460 MHz */ >,
+			< 4684 /* 614 MHz */ >,
+			< 6103 /* 800 MHz */ >,
+			< 7102 /* 931 MHz */ >;
+	};
+
 	qcom,msm-cpufreq@0 {
 		reg = <0 4>;
 		compatible = "qcom,msm-cpufreq";
-		qcom,cpu-mem-ports = <1 512>, <2 512>;
 		qcom,cpufreq-table =
-			<  300000  300000  600 /*  75 MHz */ >,
-			<  422400  422400 1200 /* 150 MHz */ >,
-			<  652800  499200 1600 /* 200 MHz */ >,
-			<  729600  576000 2456 /* 307 MHz */ >,
-			<  883200  576000 2456 /* 307 MHz */ >,
-			<  960000  960000 3680 /* 460 MHz */ >,
-			< 1036800 1036800 3680 /* 460 MHz */ >,
-			< 1190400 1036800 3680 /* 460 MHz */ >,
-			< 1267200 1267200 4912 /* 614 MHz */ >,
-			< 1497600 1497600 4912 /* 614 MHz */ >,
-			< 1574400 1574400 6400 /* 800 MHz */ >,
-			< 1728000 1651200 6400 /* 800 MHz */ >,
-			< 1958400 1728000 7448 /* 931 MHz */ >,
-			< 2265600 1728000 7448 /* 931 MHz */ >;
+			<  300000  300000  572 >,
+			<  422400  422400 1144 >,
+			<  652800  499200 1525 >,
+			<  729600  576000 2342 >,
+			<  883200  576000 2342 >,
+			<  960000  960000 3509 >,
+			< 1036800 1036800 3509 >,
+			< 1190400 1036800 3509 >,
+			< 1267200 1267200 4684 >,
+			< 1497600 1497600 4684 >,
+			< 1574400 1574400 6103 >,
+			< 1728000 1651200 6103 >,
+			< 1958400 1728000 7102 >,
+			< 2265600 1728000 7102 >,
+			< 2457600 1728000 7102 >;
 	};
 
 	usb3: qcom,ssusb@f9200000 {
@@ -1628,15 +1642,16 @@
 		compatible = "qcom,msm-audio-ion";
 	};
 
-	qcom,msm-pcm {
-		compatible = "qcom,msm-pcm-dsp";
-		qcom,msm-pcm-dsp-id = <0>;
+	qti,msm-pcm {
+		compatible = "qti,msm-pcm-dsp";
+		qti,msm-pcm-dsp-id = <0>;
 	};
 
-	qcom,msm-pcm-low-latency {
-		compatible = "qcom,msm-pcm-dsp";
-		qcom,msm-pcm-dsp-id = <1>;
-		qcom,msm-pcm-low-latency;
+	qti,msm-pcm-low-latency {
+		compatible = "qti,msm-pcm-dsp";
+		qti,msm-pcm-dsp-id = <1>;
+		qti,msm-pcm-low-latency;
+		qti,latency-level = "regular";
 	};
 
 	qcom,msm-pcm-routing {
@@ -1684,6 +1699,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 {
@@ -2179,6 +2198,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-ab-pm8941-mtp.dts b/arch/arm/boot/dts/msm8974pro-ab-pm8941-mtp.dts
index fa313bf..6b62391 100644
--- a/arch/arm/boot/dts/msm8974pro-ab-pm8941-mtp.dts
+++ b/arch/arm/boot/dts/msm8974pro-ab-pm8941-mtp.dts
@@ -22,5 +22,5 @@
 };
 
 &sdhc_1 {
-	qcom,pad-drv-on = <0x4 0x4 0x4>; /* 10mA, 10mA, 10mA */
+	qcom,pad-drv-on = <0x7 0x4 0x4>; /* 16mA, 10mA, 10mA */
 };
diff --git a/arch/arm/boot/dts/msm8974pro-pm.dtsi b/arch/arm/boot/dts/msm8974pro-pm.dtsi
index 366faef..63cb68b 100644
--- a/arch/arm/boot/dts/msm8974pro-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pm.dtsi
@@ -214,6 +214,10 @@
 			<50 172>, /* usb1_hs_async_wakeup_irq */
 			<53 104>, /* mdss_irq */
 			<62 222>, /* ee0_krait_hlos_spmi_periph_irq */
+			<0xff 18>,  /* APCx_qgicQTmrSecPhysIrptReq */
+			<0xff 19>,  /* APCx_qgicQTmrSecPhysIrptReq */
+			<0xff 25>,  /* APCx_qgicExtFaultIrptReq */
+			<0xff 33>, /*l2_perf_mon*/
 			<0xff 34>,  /* APCC_qgicL2ErrorIrptReq */
 			<0xff 35>,  /* WDT_barkInt */
 			<0xff 40>,  /* qtimer_phy_irq */
@@ -236,7 +240,10 @@
 			<0xff 105>, /* iommu_pmon_nonsecure_irq */
 			<0xff 109>,  /* ocmem_dm_nonsec_irq */
 			<0xff 126>,  /* bam_irq[0] */
+			<0xff 140>,  /* uart_dm_intr */
 			<0xff 155>,  /* sdcc_irq[0] */
+			<0xff 157>,  /* sdcc_irq[0] */
+			<0xff 159>,  /* sdcc_irq[0] */
 			<0xff 163>,  /* usb30_ee1_irq */
 			<0xff 170>,  /* sdcc_pwr_cmd_irq */
 			<0xff 173>, /* o_wcss_apss_smd_hi */
@@ -269,6 +276,8 @@
 			<0xff 207>, /* rpm_ipc(27) */
 			<0xff 211>, /* usb_dwc3_otg */
 			<0xff 240>, /* summary_irq_kpss */
+			<0xff 253>, /* sdcc_pwr_cmd_irq */
+			<0xff 256>, /* sdcc_pwr_cmd_irq */
 			<0xff 268>, /* bam_irq[1] */
 			<0xff 270>, /* bam_irq[0] */
 			<0xff 271>; /* bam_irq[0] */
diff --git a/arch/arm/boot/dts/msm8974pro-pm8941.dtsi b/arch/arm/boot/dts/msm8974pro-pm8941.dtsi
index 2c06c3c..8b13c9f 100644
--- a/arch/arm/boot/dts/msm8974pro-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pm8941.dtsi
@@ -38,28 +38,32 @@
 
 &krait0_vreg {
 		regulator-max-microvolt = <1120000>;
-		qcom,ldo-delta-voltage = <25000>;
+		qcom,ldo-delta-voltage = <12500>;
 };
 
 &krait1_vreg {
 		regulator-max-microvolt = <1120000>;
-		qcom,ldo-delta-voltage = <25000>;
+		qcom,ldo-delta-voltage = <12500>;
 };
 
 &krait2_vreg {
 		regulator-max-microvolt = <1120000>;
-		qcom,ldo-delta-voltage = <25000>;
+		qcom,ldo-delta-voltage = <12500>;
 };
 
 &krait3_vreg {
 		regulator-max-microvolt = <1120000>;
-		qcom,ldo-delta-voltage = <25000>;
+		qcom,ldo-delta-voltage = <12500>;
 };
 
 &tspp {
 	vdd_cx-supply = <&pm8841_s2_corner>;
 };
 
+&pm8841_s2_corner {
+	qcom,init-smps-mode = <0>;	/* Allow AUTO mode for VDD_CX. */
+};
+
 &krait_regulator_pmic {
 	status = "ok";
 
diff --git a/arch/arm/boot/dts/msm8974pro-pma8084-regulator.dtsi b/arch/arm/boot/dts/msm8974pro-pma8084-regulator.dtsi
index 00e3b8b..79d7412 100644
--- a/arch/arm/boot/dts/msm8974pro-pma8084-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pma8084-regulator.dtsi
@@ -494,7 +494,7 @@
 			qcom,retention-voltage = <675000>;
 			qcom,ldo-default-voltage = <750000>;
 			qcom,ldo-threshold-voltage = <850000>;
-			qcom,ldo-delta-voltage = <25000>;
+			qcom,ldo-delta-voltage = <12500>;
 			qcom,cpu-num = <0>;
 		};
 
@@ -510,7 +510,7 @@
 			qcom,retention-voltage = <675000>;
 			qcom,ldo-default-voltage = <750000>;
 			qcom,ldo-threshold-voltage = <850000>;
-			qcom,ldo-delta-voltage = <25000>;
+			qcom,ldo-delta-voltage = <12500>;
 			qcom,cpu-num = <1>;
 		};
 
@@ -526,7 +526,7 @@
 			qcom,retention-voltage = <675000>;
 			qcom,ldo-default-voltage = <750000>;
 			qcom,ldo-threshold-voltage = <850000>;
-			qcom,ldo-delta-voltage = <25000>;
+			qcom,ldo-delta-voltage = <12500>;
 			qcom,cpu-num = <2>;
 		};
 
@@ -542,7 +542,7 @@
 			qcom,retention-voltage = <675000>;
 			qcom,ldo-default-voltage = <750000>;
 			qcom,ldo-threshold-voltage = <850000>;
-			qcom,ldo-delta-voltage = <25000>;
+			qcom,ldo-delta-voltage = <12500>;
 			qcom,cpu-num = <3>;
 		};
 	};
diff --git a/arch/arm/boot/dts/msm8974pro-pma8084.dtsi b/arch/arm/boot/dts/msm8974pro-pma8084.dtsi
index 2693642..c06ebf8 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,10 +183,18 @@
 	qcom,use-phase-switching;
 };
 
+&mdss_mdp {
+	vdd-cx-supply = <&pma8084_s2_corner>;
+};
+
 &tspp {
 	vdd_cx-supply = <&pma8084_s2_corner>;
 };
 
+&pma8084_s2_corner {
+	qcom,init-smps-mode = <0>;	/* Allow AUTO mode for VDD_CX. */
+};
+
 &krait_regulator_pmic {
 	status = "ok";
 
diff --git a/arch/arm/boot/dts/msm8974pro.dtsi b/arch/arm/boot/dts/msm8974pro.dtsi
index 41f02fe..b670cfd 100755
--- a/arch/arm/boot/dts/msm8974pro.dtsi
+++ b/arch/arm/boot/dts/msm8974pro.dtsi
@@ -1548,25 +1548,6 @@
 			< 2457600000  970000  802 >;
 	};
 
-	qcom,msm-cpufreq@0 {
-		qcom,cpufreq-table =
-			<  300000  300000 300 /* 37.5 MHz */ >,
-			<  422400  422400 300 /* 37.5 MHz */ >,
-			<  652800  499200 300 /* 37.5 MHz */ >,
-			<  729600  576000 300 /* 37.5 MHz */ >,
-			<  883200  576000 300 /* 37.5 MHz */ >,
-			<  960000  960000 300 /* 37.5 MHz */ >,
-			< 1036800 1036800 300 /* 37.5 MHz */ >,
-			< 1190400 1036800 300 /* 37.5 MHz */ >,
-			< 1267200 1267200 300 /* 37.5 MHz */ >,
-			< 1497600 1497600 300 /* 37.5 MHz */ >,
-			< 1574400 1574400 300 /* 37.5 MHz */ >,
-			< 1728000 1651200 300 /* 37.5 MHz */ >,
-			< 1958400 1728000 300 /* 37.5 MHz */ >,
-			< 2265600 1728000 300 /* 37.5 MHz */ >,
-			< 2496000 1728000 300 /* 37.5 MHz */ >;
-	};
-
 	i2c@f9928000 { /* BLSP-1 QUP-6 */
 		cell-index = <3>;
 		compatible = "qcom,i2c-qup";
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 0e7baf1..dee1f68 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -686,9 +686,9 @@
 		qcom,adsp-state = <2>;
 	};
 
-	qcom,msm-pcm {
-		compatible = "qcom,msm-pcm-dsp";
-		qcom,msm-pcm-dsp-id = <0>;
+	qti,msm-pcm {
+		compatible = "qti,msm-pcm-dsp";
+		qti,msm-pcm-dsp-id = <0>;
 	};
 
 	qcom,msm-pcm-routing {
diff --git a/arch/arm/configs/apq8084_defconfig b/arch/arm/configs/apq8084_defconfig
index 968a5ee..823e4f8 100644
--- a/arch/arm/configs/apq8084_defconfig
+++ b/arch/arm/configs/apq8084_defconfig
@@ -301,6 +301,11 @@
 # CONFIG_LCD_CLASS_DEVICE is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 # CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_UHID=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_ELECOM=y
 CONFIG_USB=y
 CONFIG_USB_SUSPEND=y
 CONFIG_USB_EHCI_HCD=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 d746bba..6b1f88d 100644
--- a/arch/arm/configs/msm8226-perf_defconfig
+++ b/arch/arm/configs/msm8226-perf_defconfig
@@ -216,6 +216,7 @@
 CONFIG_BT_HCISMD=y
 CONFIG_CFG80211=y
 CONFIG_NL80211_TESTMODE=y
+CONFIG_CFG80211_INTERNAL_REGDB=y
 CONFIG_CMA=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
@@ -348,6 +349,8 @@
 CONFIG_UHID=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_ELECOM=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_SUSPEND=y
 CONFIG_USB_MON=y
@@ -457,5 +460,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 f672cc0..2d54549 100644
--- a/arch/arm/configs/msm8226_defconfig
+++ b/arch/arm/configs/msm8226_defconfig
@@ -373,6 +373,8 @@
 CONFIG_UHID=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_ELECOM=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_SUSPEND=y
 CONFIG_USB_MON=y
@@ -511,5 +513,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 c5a4421..b5119b7 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
@@ -83,7 +78,6 @@
 CONFIG_KSM=y
 CONFIG_CC_STACKPROTECTOR=y
 CONFIG_KSM=y
-CONFIG_ENABLE_VMALLOC_SAVING=y
 CONFIG_CP_ACCESS=y
 CONFIG_USE_OF=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
@@ -212,6 +206,7 @@
 CONFIG_BT_HCISMD=y
 CONFIG_CFG80211=y
 CONFIG_NL80211_TESTMODE=y
+CONFIG_CFG80211_INTERNAL_REGDB=y
 CONFIG_CMA=y
 CONFIG_CMA_SIZE_MBYTES=4
 CONFIG_BLK_DEV_LOOP=y
@@ -320,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
@@ -332,6 +328,8 @@
 CONFIG_UHID=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_ELECOM=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DEBUG_FILES=y
 CONFIG_USB_GADGET_DEBUG_FS=y
@@ -430,3 +428,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 0a48930..165b841 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
@@ -84,7 +79,6 @@
 CONFIG_KSM=y
 CONFIG_CC_STACKPROTECTOR=y
 CONFIG_KSM=y
-CONFIG_ENABLE_VMALLOC_SAVING=y
 CONFIG_CP_ACCESS=y
 CONFIG_USE_OF=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
@@ -343,6 +337,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
@@ -355,6 +350,8 @@
 CONFIG_UHID=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_ELECOM=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DEBUG_FILES=y
 CONFIG_USB_GADGET_DEBUG_FS=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 200433d..737d98d 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
@@ -244,6 +245,7 @@
 CONFIG_MSM_BT_POWER=y
 CONFIG_CFG80211=y
 CONFIG_NL80211_TESTMODE=y
+CONFIG_CFG80211_INTERNAL_REGDB=y
 CONFIG_RFKILL=y
 CONFIG_GENLOCK=y
 CONFIG_GENLOCK_MISCDEVICE=y
@@ -388,6 +390,7 @@
 CONFIG_HID_APPLE=y
 CONFIG_HID_MAGICMOUSE=y
 CONFIG_HID_MICROSOFT=y
+CONFIG_HID_ELECOM=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_SUSPEND=y
 CONFIG_USB_XHCI_HCD=y
@@ -504,3 +507,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 c106913..e5be6d5 100755
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -82,7 +82,6 @@
 CONFIG_MSM_L1_ERR_LOG=y
 CONFIG_MSM_L2_ERP_PRINT_ACCESS_ERRORS=y
 CONFIG_MSM_L2_ERP_PORT_PANIC=y
-CONFIG_MSM_L2_ERP_1BIT_PANIC=y
 CONFIG_MSM_L2_ERP_2BIT_PANIC=y
 CONFIG_MSM_CACHE_DUMP=y
 CONFIG_MSM_CACHE_DUMP_ON_PANIC=y
@@ -104,6 +103,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
@@ -396,6 +396,7 @@
 CONFIG_HID_APPLE=y
 CONFIG_HID_MAGICMOUSE=y
 CONFIG_HID_MICROSOFT=y
+CONFIG_HID_ELECOM=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_SUSPEND=y
 CONFIG_USB_XHCI_HCD=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/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 4b8d443..4576257 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -261,6 +261,8 @@
 	select MSM_GPIOMUX
 	select MULTI_IRQ_HANDLER
 	select MSM_MULTIMEDIA_USE_ION
+	select PM_DEVFREQ
+	select MSM_DEVFREQ_CPUBW
 	select MSM_PIL
 	select MSM_SPM_V2
 	select MSM_L2_SPM
@@ -309,11 +311,15 @@
 	select MSM_SPM_V2
 	select MSM_L2_SPM
 	select MSM_RPM_SMD
+	select PM_DEVFREQ
+	select MSM_DEVFREQ_CPUBW
 	select ENABLE_VMALLOC_SAVINGS
 
 config ARCH_MPQ8092
 	bool "MPQ8092"
 	select ARCH_MSM_KRAITMP
+	select PM_DEVFREQ
+	select MSM_DEVFREQ_CPUBW
 	select GPIO_MSM_V3
 	select ARM_GIC
 	select MULTI_IRQ_HANDLER
@@ -332,6 +338,8 @@
 	select MSM_SCM
 	select MSM_GPIOMUX
 	select MULTI_IRQ_HANDLER
+	select PM_DEVFREQ
+	select MSM_DEVFREQ_CPUBW
 	select MSM_PIL
 	select MSM_NATIVE_RESTART
 	select MSM_RESTART_V2
@@ -435,6 +443,8 @@
 	select MEMORY_HOLE_CARVEOUT
 	select QMI_ENCDEC
 	select MSM_CORTEX_A7
+	select PM_DEVFREQ
+	select MSM_DEVFREQ_CPUBW
 
 config ARCH_MSM8610
 	bool "MSM8610"
@@ -464,6 +474,8 @@
 	select MSM_CORTEX_A7
 	select CPU_FREQ_MSM
 	select CPU_FREQ
+	select PM_DEVFREQ
+	select MSM_DEVFREQ_CPUBW
 	select MSM_PIL
 	select MSM_RUN_QUEUE_STATS
 	select ARM_HAS_SG_CHAIN
@@ -475,7 +487,6 @@
 	select MSM_RPM_LOG
 	select MSM_IOMMU_SYNC
 	select MSM_RPM_STATS_LOG
-	select ENABLE_VMALLOC_SAVINGS
 
 config ARCH_MSM8226
 	bool "MSM8226"
@@ -505,6 +516,8 @@
 	select MSM_CORTEX_A7
 	select CPU_FREQ_MSM
 	select CPU_FREQ
+	select PM_DEVFREQ
+	select MSM_DEVFREQ_CPUBW
 	select MSM_PIL
 	select MSM_RUN_QUEUE_STATS
 	select ARM_HAS_SG_CHAIN
@@ -525,6 +538,8 @@
 	select ARM_GIC
 	select CPU_V7
 	select MSM_SCM
+	select PM_DEVFREQ
+	select MSM_DEVFREQ_CPUBW
 	select MSM_PIL
 	select MSM_GPIOMUX
 	select MULTI_IRQ_HANDLER
@@ -1563,20 +1578,6 @@
 	  Enables the PCIe functionality by configures PCIe core on
 	  MSM chipset and by enabling the ARM PCI framework extension.
 
-config MSM_RPC_SDIO_XPRT
-	depends on MSM_SDIO_AL
-	default y
-	bool "MSM SDIO XPRT Layer"
-	help
-	  SDIO Transport Layer for RPC Rouer
-
-config MSM_RPC_SDIO_DEBUG
-	depends on MSM_RPC_SDIO_XPRT
-	default y
-	bool "MSM SDIO XPRT debug support"
-	help
-	  Support for debugging SDIO XPRT
-
 config MSM_SMD_DEBUG
 	depends on MSM_SMD
 	default y
@@ -1585,21 +1586,6 @@
 	  Support for debugging the SMD for communication
 	  between the ARM9 and ARM11
 
-config MSM_SDIO_AL
-	depends on ((ARCH_MSM7X30 || MACH_MSM8X60_FUSN_FFA || MACH_TYPE_MSM8X60_FUSION) && HAS_WAKELOCK)
-	default y
-	tristate "SDIO-Abstraction-Layer"
-	help
-	  Support MSM<->MDM Communication over SDIO bus.
-	  MDM SDIO-Client should have pipes support.
-
-config MSM_SDIO_DMUX
-	bool "SDIO Data Mux Driver"
-	depends on MSM_SDIO_AL
-	default n
-	help
-	  Support Muxed Data Channels over SDIO interface.
-
 config MSM_BAM_DMUX
 	bool "BAM Data Mux Driver"
 	depends on SPS
@@ -1680,16 +1666,6 @@
 
 	  If in doubt, say yes.
 
-config MSM_SDIO_TTY
-	bool "SDIO TTY Driver"
-	depends on MSM_SDIO_AL
-	default n
-	help
-	  Provides a TTY driver SDIO TTY
-	  This driver can be used by user space
-	  applications for passing data through the
-	  SDIO interface.
-
 config MSM_SMD_TTY
 	bool "SMD TTY Driver"
 	depends on MSM_SMD
@@ -1717,13 +1693,6 @@
 
 	  If in doubt, say yes.
 
-config MSM_SDIO_CMUX
-	bool "SDIO CMUX Driver"
-	depends on MSM_SDIO_AL
-	default n
-	help
-	  Provides a Muxed port interface over SDIO QMI
-
 config MSM_DSPS
 	bool "Sensors DSPS driver"
 	depends on (MSM_PIL && (ARCH_MSM8X60 || ARCH_MSM8960))
@@ -1736,13 +1705,6 @@
 	  The number of clocks and their name may vary between targets.
 	  It also triggers the PIL to load the DSPS firmware.
 
-config MSM_SDIO_CTL
-	bool "SDIO CTL Driver"
-	depends on MSM_SDIO_CMUX
-	default n
-	help
-	  Provides a binary SDIO control port interface.
-
 config MSM_ONCRPCROUTER
 	depends on MSM_SMD
 	default n
@@ -1891,15 +1853,6 @@
 	  Collects performance statistics and shows this information
 	  through a debugfs file rmt_storage_stats.
 
-config MSM_SDIO_SMEM
-        depends on MSM_SDIO_AL
-        default n
-        bool "SDIO SMEM for remote storage"
-        help
-          Copies data from remote MDM9K memory to local MSM8x60
-	  memory. Used by remote storage client to shadow
-	  MDM9K filesystem.
-
 config MSM_DALRPC
 	bool "DAL RPC support"
 	default n
@@ -1934,6 +1887,20 @@
 
 endif # CPU_FREQ_MSM
 
+config MSM_DEVFREQ_CPUBW
+	bool "Devfreq device for CPU<->DDR IB/AB BW voting"
+	depends on PM_DEVFREQ
+	select DEVFREQ_GOV_PERFORMANCE
+	select DEVFREQ_GOV_POWERSAVE
+	select DEVFREQ_GOV_USERSPACE
+	select DEVFREQ_GOV_MSM_CPUFREQ
+	default n
+	help
+	  Different devfreq governors use this devfreq device to make CPU to
+	  DDR IB/AB bandwidth votes. This driver provides a SoC topology
+	  agnostic interface to so that some of the devfreq governors can be
+	  shared across SoCs.
+
 config MSM_AVS_HW
 	bool "Enable Adaptive Voltage Scaling (AVS)"
 	default n
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 4e60414..22e14d6 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -98,10 +98,6 @@
 obj-$(CONFIG_ARCH_FSM9XXX) += sirc-fsm9xxx.o
 obj-$(CONFIG_MSM_FIQ_SUPPORT) += fiq_glue.o
 obj-$(CONFIG_MACH_TROUT) += board-trout-rfkill.o
-obj-$(CONFIG_MSM_SDIO_AL) += sdio_al.o
-obj-$(CONFIG_MSM_SDIO_AL) += sdio_al_test.o
-obj-$(CONFIG_MSM_SDIO_AL) += sdio_al_dloader.o
-obj-$(CONFIG_MSM_SDIO_DMUX) += sdio_dmux.o
 obj-$(CONFIG_MSM_BAM_DMUX) += bam_dmux.o
 obj-$(CONFIG_MSM_SMD_LOGGING) += smem_log.o
 obj-$(CONFIG_MSM_IPC_LOGGING) += ipc_logging.o
@@ -118,13 +114,10 @@
 obj-$(CONFIG_ARCH_MSM9615) += nand_partitions.o
 obj-$(CONFIG_ARCH_MSM8625) += nand_partitions.o
 obj-$(CONFIG_ARCH_MSM7X27A) += nand_partitions.o
-obj-$(CONFIG_MSM_SDIO_TTY) += sdio_tty.o
 obj-$(CONFIG_MSM_SMD_TTY) += smd_tty.o
 obj-$(CONFIG_MSM_SMD_QMI) += smd_qmi.o
 obj-$(CONFIG_MSM_SMD_PKT) += smd_pkt.o
-obj-$(CONFIG_MSM_SDIO_CMUX) += sdio_cmux.o
 obj-$(CONFIG_MSM_DSPS) += msm_dsps.o
-obj-$(CONFIG_MSM_SDIO_CTL) += sdio_ctl.o
 obj-$(CONFIG_MSM_SMD_NMEA) += smd_nmea.o
 obj-$(CONFIG_MSM_RESET_MODEM) += reset_modem.o
 obj-$(CONFIG_MSM_IPC_ROUTER_SMD_XPRT) += ipc_router_smd_xprt.o
@@ -141,7 +134,6 @@
 obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_clients.o
 obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_xdr.o
 obj-$(CONFIG_MSM_ONCRPCROUTER) += rpcrouter_smd_xprt.o
-obj-$(CONFIG_MSM_RPC_SDIO_XPRT) += rpcrouter_sdio_xprt.o
 obj-$(CONFIG_MSM_RPC_PING) += ping_mdm_rpc_client.o
 obj-$(CONFIG_MSM_RPC_PROC_COMM_TEST) += proc_comm_test.o
 obj-$(CONFIG_MSM_RPC_PING) += ping_mdm_rpc_client.o ping_apps_server.o
@@ -322,7 +314,6 @@
 obj-$(CONFIG_HTC_PWRSINK) += htc_pwrsink.o
 obj-$(CONFIG_HTC_HEADSET) += htc_headset.o
 obj-$(CONFIG_MSM_RMT_STORAGE_CLIENT) += rmt_storage_client.o
-obj-$(CONFIG_MSM_SDIO_SMEM) += sdio_smem.o
 obj-$(CONFIG_MSM_RPM) += rpm.o rpm_resources.o
 obj-$(CONFIG_MSM_LPM_TEST) += test-lpm.o
 obj-$(CONFIG_MSM_RPM_SMD) += rpm-smd.o lpm_levels.o
@@ -422,6 +413,7 @@
 obj-$(CONFIG_ARCH_MSM8974) += msm_mpmctr.o
 obj-$(CONFIG_MSM_CPR_REGULATOR) += cpr-regulator.o
 obj-$(CONFIG_CPU_FREQ_MSM) += cpufreq.o
+obj-$(CONFIG_MSM_DEVFREQ_CPUBW) += devfreq_cpubw.o
 
 obj-$(CONFIG_WALL_CLK) += wallclk.o
 obj-$(CONFIG_WALL_CLK_SYSFS) += wallclk_sysfs.o
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
index 83c1d4c..78df289 100644
--- a/arch/arm/mach-msm/Makefile.boot
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -117,6 +117,7 @@
 	dtb-$(CONFIG_ARCH_MSM8226)	+= msm8926-1080p-mtp.dtb
 	dtb-$(CONFIG_ARCH_MSM8226)	+= msm8926-qrd.dtb
 	dtb-$(CONFIG_ARCH_MSM8226)	+= msm8926-qrd-skug.dtb
+	dtb-$(CONFIG_ARCH_MSM8226)	+= msm8926-qrd-skug-pvt.dtb
 	dtb-$(CONFIG_ARCH_MSM8226)	+= msm8226-v1-qrd-skuf.dtb
 	dtb-$(CONFIG_ARCH_MSM8226)	+= msm8226-v2-qrd-skuf.dtb
 	dtb-$(CONFIG_ARCH_MSM8226)	+= apq8026-v1-xpm.dtb
diff --git a/arch/arm/mach-msm/acpuclock-8226.c b/arch/arm/mach-msm/acpuclock-8226.c
index da3cfba..d42e798 100644
--- a/arch/arm/mach-msm/acpuclock-8226.c
+++ b/arch/arm/mach-msm/acpuclock-8226.c
@@ -60,64 +60,64 @@
 };
 
 static struct clkctl_acpu_speed acpu_freq_tbl_8226_1p1[] = {
-	{ 1,  300000, PLL0,    4, 2,   CPR_CORNER_SVS,    0, 4 },
-	{ 1,  384000, ACPUPLL, 5, 2,   CPR_CORNER_SVS,    0, 4 },
-	{ 1,  600000, PLL0,    4, 0,   CPR_CORNER_NORMAL, 0, 6 },
-	{ 1,  787200, ACPUPLL, 5, 0,   CPR_CORNER_NORMAL, 0, 6 },
-	{ 1,  998400, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
-	{ 1, 1094400, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
-	{ 0, 1190400, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
+	{ 1,  300000, PLL0,    4, 2,   CPR_CORNER_2,    0, 4 },
+	{ 1,  384000, ACPUPLL, 5, 2,   CPR_CORNER_2,    0, 4 },
+	{ 1,  600000, PLL0,    4, 0,   CPR_CORNER_4, 0, 6 },
+	{ 1,  787200, ACPUPLL, 5, 0,   CPR_CORNER_4, 0, 6 },
+	{ 1,  998400, ACPUPLL, 5, 0,   CPR_CORNER_12,  0, 7 },
+	{ 1, 1094400, ACPUPLL, 5, 0,   CPR_CORNER_12,  0, 7 },
+	{ 0, 1190400, ACPUPLL, 5, 0,   CPR_CORNER_12,  0, 7 },
 	{ 0 }
 };
 
 static struct clkctl_acpu_speed acpu_freq_tbl_8226_1p2[] = {
-	{ 1,  300000, PLL0,    4, 2,   CPR_CORNER_SVS,    0, 4 },
-	{ 1,  384000, ACPUPLL, 5, 2,   CPR_CORNER_SVS,    0, 4 },
-	{ 1,  600000, PLL0,    4, 0,   CPR_CORNER_NORMAL, 0, 6 },
-	{ 1,  787200, ACPUPLL, 5, 0,   CPR_CORNER_NORMAL, 0, 6 },
-	{ 1,  998400, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
-	{ 1, 1094400, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
-	{ 1, 1190400, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
+	{ 1,  300000, PLL0,    4, 2,   CPR_CORNER_2,    0, 4 },
+	{ 1,  384000, ACPUPLL, 5, 2,   CPR_CORNER_2,    0, 4 },
+	{ 1,  600000, PLL0,    4, 0,   CPR_CORNER_4, 0, 6 },
+	{ 1,  787200, ACPUPLL, 5, 0,   CPR_CORNER_4, 0, 6 },
+	{ 1,  998400, ACPUPLL, 5, 0,   CPR_CORNER_12,  0, 7 },
+	{ 1, 1094400, ACPUPLL, 5, 0,   CPR_CORNER_12,  0, 7 },
+	{ 1, 1190400, ACPUPLL, 5, 0,   CPR_CORNER_12,  0, 7 },
 	{ 0 }
 };
 
 static struct clkctl_acpu_speed acpu_freq_tbl_8226_1p4[] = {
-	{ 1,  300000, PLL0,    4, 2,   CPR_CORNER_SVS,    0, 4 },
-	{ 1,  384000, ACPUPLL, 5, 2,   CPR_CORNER_SVS,    0, 4 },
-	{ 1,  600000, PLL0,    4, 0,   CPR_CORNER_NORMAL, 0, 6 },
-	{ 1,  787200, ACPUPLL, 5, 0,   CPR_CORNER_NORMAL, 0, 6 },
-	{ 1,  998400, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
-	{ 1, 1094400, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
-	{ 1, 1190400, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
-	{ 1, 1305600, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
-	{ 1, 1344000, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
-	{ 1, 1401600, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
+	{ 1,  300000, PLL0,    4, 2,   CPR_CORNER_2,    0, 4 },
+	{ 1,  384000, ACPUPLL, 5, 2,   CPR_CORNER_2,    0, 4 },
+	{ 1,  600000, PLL0,    4, 0,   CPR_CORNER_4, 0, 6 },
+	{ 1,  787200, ACPUPLL, 5, 0,   CPR_CORNER_4, 0, 6 },
+	{ 1,  998400, ACPUPLL, 5, 0,   CPR_CORNER_12,  0, 7 },
+	{ 1, 1094400, ACPUPLL, 5, 0,   CPR_CORNER_12,  0, 7 },
+	{ 1, 1190400, ACPUPLL, 5, 0,   CPR_CORNER_12,  0, 7 },
+	{ 1, 1305600, ACPUPLL, 5, 0,   CPR_CORNER_12,  0, 7 },
+	{ 1, 1344000, ACPUPLL, 5, 0,   CPR_CORNER_12,  0, 7 },
+	{ 1, 1401600, ACPUPLL, 5, 0,   CPR_CORNER_12,  0, 7 },
 	{ 0 }
 };
 
 static struct clkctl_acpu_speed acpu_freq_tbl_8226_1p6[] = {
-	{ 1,  300000, PLL0,    4, 2,   CPR_CORNER_SVS,    0, 4 },
-	{ 1,  384000, ACPUPLL, 5, 2,   CPR_CORNER_SVS,    0, 4 },
-	{ 1,  600000, PLL0,    4, 0,   CPR_CORNER_NORMAL, 0, 6 },
-	{ 1,  787200, ACPUPLL, 5, 0,   CPR_CORNER_NORMAL, 0, 6 },
-	{ 1,  998400, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
-	{ 1, 1094400, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
-	{ 1, 1190400, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
-	{ 1, 1305600, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
-	{ 1, 1344000, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
-	{ 1, 1401600, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
-	{ 1, 1497600, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
-	{ 1, 1593600, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 7 },
+	{ 1,  300000, PLL0,    4, 2,   CPR_CORNER_2,    0, 4 },
+	{ 1,  384000, ACPUPLL, 5, 2,   CPR_CORNER_2,    0, 4 },
+	{ 1,  600000, PLL0,    4, 0,   CPR_CORNER_4, 0, 6 },
+	{ 1,  787200, ACPUPLL, 5, 0,   CPR_CORNER_4, 0, 6 },
+	{ 1,  998400, ACPUPLL, 5, 0,   CPR_CORNER_5,  0, 7 },
+	{ 1, 1094400, ACPUPLL, 5, 0,   CPR_CORNER_6,  0, 7 },
+	{ 1, 1190400, ACPUPLL, 5, 0,   CPR_CORNER_7,  0, 7 },
+	{ 1, 1305600, ACPUPLL, 5, 0,   CPR_CORNER_8,  0, 7 },
+	{ 1, 1344000, ACPUPLL, 5, 0,   CPR_CORNER_9,  0, 7 },
+	{ 1, 1401600, ACPUPLL, 5, 0,   CPR_CORNER_10,  0, 7 },
+	{ 1, 1497600, ACPUPLL, 5, 0,   CPR_CORNER_11,  0, 7 },
+	{ 1, 1593600, ACPUPLL, 5, 0,   CPR_CORNER_12,  0, 7 },
 	{ 0 }
 };
 
 static struct clkctl_acpu_speed acpu_freq_tbl_8610[] = {
-	{ 1,  300000, PLL0,    4, 2,   CPR_CORNER_SVS,    0, 3 },
-	{ 1,  384000, ACPUPLL, 5, 2,   CPR_CORNER_SVS,    0, 3 },
-	{ 1,  600000, PLL0,    4, 0,   CPR_CORNER_NORMAL, 0, 4 },
-	{ 1,  787200, ACPUPLL, 5, 0,   CPR_CORNER_NORMAL, 0, 4 },
-	{ 1,  998400, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 5 },
-	{ 1, 1190400, ACPUPLL, 5, 0,   CPR_CORNER_TURBO,  0, 5 },
+	{ 1,  300000, PLL0,    4, 2,   CPR_CORNER_2,    0, 3 },
+	{ 1,  384000, ACPUPLL, 5, 2,   CPR_CORNER_2,    0, 3 },
+	{ 1,  600000, PLL0,    4, 0,   CPR_CORNER_4, 0, 4 },
+	{ 1,  787200, ACPUPLL, 5, 0,   CPR_CORNER_4, 0, 4 },
+	{ 1,  998400, ACPUPLL, 5, 0,   CPR_CORNER_12,  0, 5 },
+	{ 1, 1190400, ACPUPLL, 5, 0,   CPR_CORNER_12,  0, 5 },
 	{ 0 }
 };
 
@@ -135,7 +135,7 @@
 	.freq_tbl = acpu_freq_tbl_8226_1p1,
 	.pvs_tables = pvs_tables_8226,
 	.bus_scale = &bus_client_pdata,
-	.vdd_max_cpu = CPR_CORNER_TURBO,
+	.vdd_max_cpu = CPR_CORNER_12,
 	.src_clocks = {
 		[PLL0].name = "gpll0",
 		[ACPUPLL].name = "a7sspll",
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 6281395..b618cd4 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -28,6 +28,7 @@
 #include <linux/wakelock.h>
 #include <linux/kfifo.h>
 #include <linux/of.h>
+#include <linux/srcu.h>
 #include <mach/msm_ipc_logging.h>
 #include <mach/sps.h>
 #include <mach/bam_dmux.h>
@@ -36,19 +37,12 @@
 #include <mach/socinfo.h>
 #include <mach/subsystem_restart.h>
 
+#include "bam_dmux_private.h"
+
 #define BAM_CH_LOCAL_OPEN       0x1
 #define BAM_CH_REMOTE_OPEN      0x2
 #define BAM_CH_IN_RESET         0x4
 
-#define BAM_MUX_HDR_MAGIC_NO    0x33fc
-
-#define BAM_MUX_HDR_CMD_DATA		0
-#define BAM_MUX_HDR_CMD_OPEN		1
-#define BAM_MUX_HDR_CMD_CLOSE		2
-#define BAM_MUX_HDR_CMD_STATUS		3 /* unused */
-#define BAM_MUX_HDR_CMD_OPEN_NO_A2_PC	4
-
-
 #define LOW_WATERMARK		2
 #define HIGH_WATERMARK		4
 #define DEFAULT_POLLING_MIN_SLEEP (950)
@@ -58,20 +52,47 @@
 static int msm_bam_dmux_debug_enable;
 module_param_named(debug_enable, msm_bam_dmux_debug_enable,
 		   int, S_IRUGO | S_IWUSR | S_IWGRP);
-static int POLLING_MIN_SLEEP = 950;
+static int POLLING_MIN_SLEEP = 2950;
 module_param_named(min_sleep, POLLING_MIN_SLEEP,
 		   int, S_IRUGO | S_IWUSR | S_IWGRP);
-static int POLLING_MAX_SLEEP = 1050;
+static int POLLING_MAX_SLEEP = 3050;
 module_param_named(max_sleep, POLLING_MAX_SLEEP,
 		   int, S_IRUGO | S_IWUSR | S_IWGRP);
-static int POLLING_INACTIVITY = 40;
+static int POLLING_INACTIVITY = 1;
 module_param_named(inactivity, POLLING_INACTIVITY,
 		   int, S_IRUGO | S_IWUSR | S_IWGRP);
-static int bam_adaptive_timer_enabled = 1;
+static int bam_adaptive_timer_enabled;
 module_param_named(adaptive_timer_enabled,
 			bam_adaptive_timer_enabled,
 		   int, S_IRUGO | S_IWUSR | S_IWGRP);
 
+static struct bam_ops_if bam_default_ops = {
+	/* smsm */
+	.smsm_change_state_ptr = &smsm_change_state,
+	.smsm_get_state_ptr = &smsm_get_state,
+	.smsm_state_cb_register_ptr = &smsm_state_cb_register,
+	.smsm_state_cb_deregister_ptr = &smsm_state_cb_deregister,
+
+	/* sps */
+	.sps_connect_ptr = &sps_connect,
+	.sps_disconnect_ptr = &sps_disconnect,
+	.sps_register_bam_device_ptr = &sps_register_bam_device,
+	.sps_deregister_bam_device_ptr = &sps_deregister_bam_device,
+	.sps_alloc_endpoint_ptr = &sps_alloc_endpoint,
+	.sps_free_endpoint_ptr = &sps_free_endpoint,
+	.sps_set_config_ptr = &sps_set_config,
+	.sps_get_config_ptr = &sps_get_config,
+	.sps_device_reset_ptr = &sps_device_reset,
+	.sps_register_event_ptr = &sps_register_event,
+	.sps_transfer_one_ptr = &sps_transfer_one,
+	.sps_get_iovec_ptr = &sps_get_iovec,
+	.sps_get_unused_desc_num_ptr = &sps_get_unused_desc_num,
+
+	.dma_to = DMA_TO_DEVICE,
+	.dma_from = DMA_FROM_DEVICE,
+};
+static struct bam_ops_if *bam_ops = &bam_default_ops;
+
 #if defined(DEBUG)
 static uint32_t bam_dmux_read_cnt;
 static uint32_t bam_dmux_write_cnt;
@@ -151,29 +172,10 @@
 	int use_wm;
 };
 
-struct tx_pkt_info {
-	struct sk_buff *skb;
-	dma_addr_t dma_address;
-	char is_cmd;
-	uint32_t len;
-	struct work_struct work;
-	struct list_head list_node;
-	unsigned ts_sec;
-	unsigned long ts_nsec;
-};
-
-struct rx_pkt_info {
-	struct sk_buff *skb;
-	dma_addr_t dma_address;
-	struct work_struct work;
-	struct list_head list_node;
-};
-
 #define A2_NUM_PIPES		6
 #define A2_SUMMING_THRESHOLD	4096
 #define A2_PHYS_BASE		0x124C2000
 #define A2_PHYS_SIZE		0x2000
-#define BUFFER_SIZE		2048
 #define DEFAULT_NUM_BUFFERS	32
 
 #ifndef A2_BAM_IRQ
@@ -210,26 +212,20 @@
 static DEFINE_SPINLOCK(bam_tx_pool_spinlock);
 static DEFINE_MUTEX(bam_pdev_mutexlock);
 
-struct bam_mux_hdr {
-	uint16_t magic_num;
-	uint8_t reserved;
-	uint8_t cmd;
-	uint8_t pad_len;
-	uint8_t ch_id;
-	uint16_t pkt_len;
-};
-
 static void notify_all(int event, unsigned long data);
 static void bam_mux_write_done(struct work_struct *work);
 static void handle_bam_mux_cmd(struct work_struct *work);
 static void rx_timer_work_func(struct work_struct *work);
+static void queue_rx_work_func(struct work_struct *work);
 
 static DECLARE_WORK(rx_timer_work, rx_timer_work_func);
-static struct delayed_work queue_rx_work;
+static DECLARE_WORK(queue_rx_work, queue_rx_work_func);
 
 static struct workqueue_struct *bam_mux_rx_workqueue;
 static struct workqueue_struct *bam_mux_tx_workqueue;
 
+static struct srcu_struct bam_dmux_srcu;
+
 /* A2 power collaspe */
 #define UL_TIMEOUT_DELAY 1000	/* in ms */
 #define ENABLE_DISCONNECT_ACK	0x1
@@ -390,7 +386,7 @@
 	spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
 }
 
-static void queue_rx(void)
+static void __queue_rx(gfp_t alloc_flags)
 {
 	void *ptr;
 	struct rx_pkt_info *info;
@@ -405,29 +401,29 @@
 		if (in_global_reset)
 			goto fail;
 
-		info = kmalloc(sizeof(struct rx_pkt_info),
-						GFP_NOWAIT | __GFP_NOWARN);
+		info = kmalloc(sizeof(struct rx_pkt_info), alloc_flags);
 		if (!info) {
 			DMUX_LOG_KERR(
-			"%s: unable to alloc rx_pkt_info, will retry later\n",
-								__func__);
+			"%s: unable to alloc rx_pkt_info w/ flags %x, will retry later\n",
+								__func__,
+								alloc_flags);
 			goto fail;
 		}
 
 		INIT_WORK(&info->work, handle_bam_mux_cmd);
 
-		info->skb = __dev_alloc_skb(BUFFER_SIZE,
-						GFP_NOWAIT | __GFP_NOWARN);
+		info->skb = __dev_alloc_skb(BUFFER_SIZE, alloc_flags);
 		if (info->skb == NULL) {
 			DMUX_LOG_KERR(
-				"%s: unable to alloc skb, will retry later\n",
-								__func__);
+				"%s: unable to alloc skb w/ flags %x, will retry later\n",
+								__func__,
+								alloc_flags);
 			goto fail_info;
 		}
 		ptr = skb_put(info->skb, BUFFER_SIZE);
 
 		info->dma_address = dma_map_single(NULL, ptr, BUFFER_SIZE,
-							DMA_FROM_DEVICE);
+							bam_ops->dma_from);
 		if (info->dma_address == 0 || info->dma_address == ~0) {
 			DMUX_LOG_KERR("%s: dma_map_single failure %p for %p\n",
 				__func__, (void *)info->dma_address, ptr);
@@ -437,8 +433,8 @@
 		mutex_lock(&bam_rx_pool_mutexlock);
 		list_add_tail(&info->list_node, &bam_rx_pool);
 		rx_len_cached = ++bam_rx_pool_len;
-		ret = sps_transfer_one(bam_rx_pipe, info->dma_address,
-			BUFFER_SIZE, info, 0);
+		ret = bam_ops->sps_transfer_one_ptr(bam_rx_pipe,
+				info->dma_address, BUFFER_SIZE, info, 0);
 		if (ret) {
 			list_del(&info->list_node);
 			rx_len_cached = --bam_rx_pool_len;
@@ -447,7 +443,7 @@
 				__func__, ret);
 
 			dma_unmap_single(NULL, info->dma_address, BUFFER_SIZE,
-						DMA_FROM_DEVICE);
+						bam_ops->dma_from);
 
 			goto fail_skb;
 		}
@@ -463,15 +459,30 @@
 	kfree(info);
 
 fail:
-	if (rx_len_cached == 0 && !in_global_reset) {
+	if (!in_global_reset) {
 		DMUX_LOG_KERR("%s: rescheduling\n", __func__);
-		schedule_delayed_work(&queue_rx_work, msecs_to_jiffies(100));
+		schedule_work(&queue_rx_work);
 	}
 }
 
+static void queue_rx(void)
+{
+	/*
+	 * Hot path.  Delays waiting for the allocation to find memory if its
+	 * not immediately available, and delays from logging allocation
+	 * failures which cannot be tolerated at this time.
+	 */
+	__queue_rx(GFP_NOWAIT | __GFP_NOWARN);
+}
+
 static void queue_rx_work_func(struct work_struct *work)
 {
-	queue_rx();
+	/*
+	 * Cold path.  Delays can be tolerated.  Use of GFP_KERNEL should
+	 * guarentee the requested memory will be found, after some ammount of
+	 * delay.
+	 */
+	__queue_rx(GFP_KERNEL);
 }
 
 static void bam_mux_process_data(struct sk_buff *rx_skb)
@@ -535,7 +546,8 @@
 
 	info = container_of(work, struct rx_pkt_info, work);
 	rx_skb = info->skb;
-	dma_unmap_single(NULL, info->dma_address, BUFFER_SIZE, DMA_FROM_DEVICE);
+	dma_unmap_single(NULL, info->dma_address, BUFFER_SIZE,
+			bam_ops->dma_from);
 	kfree(info);
 
 	rx_hdr = (struct bam_mux_hdr *)rx_skb->data;
@@ -644,7 +656,7 @@
 	}
 
 	dma_address = dma_map_single(NULL, data, len,
-					DMA_TO_DEVICE);
+					bam_ops->dma_to);
 	if (!dma_address) {
 		pr_err("%s: dma_map_single() failed\n", __func__);
 		kfree(pkt);
@@ -659,7 +671,7 @@
 	INIT_WORK(&pkt->work, bam_mux_write_done);
 	spin_lock_irqsave(&bam_tx_pool_spinlock, flags);
 	list_add_tail(&pkt->list_node, &bam_tx_pool);
-	rc = sps_transfer_one(bam_tx_pipe, dma_address, len,
+	rc = bam_ops->sps_transfer_one_ptr(bam_tx_pipe, dma_address, len,
 				pkt, SPS_IOVEC_FLAG_EOT);
 	if (rc) {
 		DMUX_LOG_KERR("%s sps_transfer_one failed rc=%d\n",
@@ -669,7 +681,7 @@
 		spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
 		dma_unmap_single(NULL, pkt->dma_address,
 					pkt->len,
-					DMA_TO_DEVICE);
+					bam_ops->dma_to);
 		kfree(pkt);
 	} else {
 		spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
@@ -746,6 +758,7 @@
 	struct sk_buff *new_skb = NULL;
 	dma_addr_t dma_address;
 	struct tx_pkt_info *pkt;
+	int rcu_id;
 
 	if (id >= BAM_DMUX_NUM_CHANNELS)
 		return -EINVAL;
@@ -754,11 +767,19 @@
 	if (!bam_mux_initialized)
 		return -ENODEV;
 
+	rcu_id = srcu_read_lock(&bam_dmux_srcu);
+	if (in_global_reset) {
+		BAM_DMUX_LOG("%s: In SSR... ch_id[%d]\n", __func__, id);
+		srcu_read_unlock(&bam_dmux_srcu, rcu_id);
+		return -EFAULT;
+	}
+
 	DBG("%s: writing to ch %d len %d\n", __func__, id, skb->len);
 	spin_lock_irqsave(&bam_ch[id].lock, flags);
 	if (!bam_ch_is_open(id)) {
 		spin_unlock_irqrestore(&bam_ch[id].lock, flags);
 		pr_err("%s: port not open: %d\n", __func__, bam_ch[id].status);
+		srcu_read_unlock(&bam_dmux_srcu, rcu_id);
 		return -ENODEV;
 	}
 
@@ -766,6 +787,7 @@
 	    (bam_ch[id].num_tx_pkts >= HIGH_WATERMARK)) {
 		spin_unlock_irqrestore(&bam_ch[id].lock, flags);
 		pr_err("%s: watermark exceeded: %d\n", __func__, id);
+		srcu_read_unlock(&bam_dmux_srcu, rcu_id);
 		return -EAGAIN;
 	}
 	spin_unlock_irqrestore(&bam_ch[id].lock, flags);
@@ -774,8 +796,10 @@
 	if (!bam_is_connected) {
 		read_unlock(&ul_wakeup_lock);
 		ul_wakeup();
-		if (unlikely(in_global_reset == 1))
+		if (unlikely(in_global_reset == 1)) {
+			srcu_read_unlock(&bam_dmux_srcu, rcu_id);
 			return -EFAULT;
+		}
 		read_lock(&ul_wakeup_lock);
 		notify_all(BAM_DMUX_UL_CONNECTED, (unsigned long)(NULL));
 	}
@@ -820,7 +844,7 @@
 	}
 
 	dma_address = dma_map_single(NULL, skb->data, skb->len,
-					DMA_TO_DEVICE);
+					bam_ops->dma_to);
 	if (!dma_address) {
 		pr_err("%s: dma_map_single() failed\n", __func__);
 		goto write_fail3;
@@ -832,7 +856,7 @@
 	INIT_WORK(&pkt->work, bam_mux_write_done);
 	spin_lock_irqsave(&bam_tx_pool_spinlock, flags);
 	list_add_tail(&pkt->list_node, &bam_tx_pool);
-	rc = sps_transfer_one(bam_tx_pipe, dma_address, skb->len,
+	rc = bam_ops->sps_transfer_one_ptr(bam_tx_pipe, dma_address, skb->len,
 				pkt, SPS_IOVEC_FLAG_EOT);
 	if (rc) {
 		DMUX_LOG_KERR("%s sps_transfer_one failed rc=%d\n",
@@ -841,7 +865,7 @@
 		DBG_INC_TX_SPS_FAILURE_CNT();
 		spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
 		dma_unmap_single(NULL, pkt->dma_address,
-					pkt->skb->len,	DMA_TO_DEVICE);
+					pkt->skb->len,	bam_ops->dma_to);
 		kfree(pkt);
 		if (new_skb)
 			dev_kfree_skb_any(new_skb);
@@ -853,6 +877,7 @@
 	}
 	ul_packet_written = 1;
 	read_unlock(&ul_wakeup_lock);
+	srcu_read_unlock(&bam_dmux_srcu, rcu_id);
 	return rc;
 
 write_fail3:
@@ -863,6 +888,7 @@
 		dev_kfree_skb_any(new_skb);
 write_fail:
 	read_unlock(&ul_wakeup_lock);
+	srcu_read_unlock(&bam_dmux_srcu, rcu_id);
 	return -ENOMEM;
 }
 
@@ -1049,14 +1075,14 @@
 	 * Attempt to enable interrupts - if this fails,
 	 * continue polling and we will retry later.
 	 */
-	ret = sps_get_config(bam_rx_pipe, &cur_rx_conn);
+	ret = bam_ops->sps_get_config_ptr(bam_rx_pipe, &cur_rx_conn);
 	if (ret) {
 		pr_err("%s: sps_get_config() failed %d\n", __func__, ret);
 		goto fail;
 	}
 
 	rx_register_event.options = SPS_O_EOT;
-	ret = sps_register_event(bam_rx_pipe, &rx_register_event);
+	ret = bam_ops->sps_register_event_ptr(bam_rx_pipe, &rx_register_event);
 	if (ret) {
 		pr_err("%s: sps_register_event() failed %d\n", __func__, ret);
 		goto fail;
@@ -1064,7 +1090,7 @@
 
 	cur_rx_conn.options = SPS_O_AUTO_ENABLE |
 		SPS_O_EOT | SPS_O_ACK_TRANSFERS;
-	ret = sps_set_config(bam_rx_pipe, &cur_rx_conn);
+	ret = bam_ops->sps_set_config_ptr(bam_rx_pipe, &cur_rx_conn);
 	if (ret) {
 		pr_err("%s: sps_set_config() failed %d\n", __func__, ret);
 		goto fail;
@@ -1075,7 +1101,7 @@
 
 	/* handle any rx packets before interrupt was enabled */
 	while (bam_connection_is_active && !polling_mode) {
-		ret = sps_get_iovec(bam_rx_pipe, &iov);
+		ret = bam_ops->sps_get_iovec_ptr(bam_rx_pipe, &iov);
 		if (ret) {
 			pr_err("%s: sps_get_iovec failed %d\n",
 					__func__, ret);
@@ -1160,7 +1186,7 @@
 				return;
 			}
 
-			ret = sps_get_iovec(bam_rx_pipe, &iov);
+			ret = bam_ops->sps_get_iovec_ptr(bam_rx_pipe, &iov);
 			if (ret) {
 				DMUX_LOG_KERR("%s: sps_get_iovec failed %d\n",
 						__func__, ret);
@@ -1209,7 +1235,7 @@
 		if (bam_adaptive_timer_enabled) {
 			usleep_range(rx_timer_interval, rx_timer_interval + 50);
 
-			ret = sps_get_unused_desc_num(bam_rx_pipe,
+			ret = bam_ops->sps_get_unused_desc_num_ptr(bam_rx_pipe,
 						&buffs_unused);
 
 			if (ret) {
@@ -1261,11 +1287,11 @@
 		if (!pkt->is_cmd)
 			dma_unmap_single(NULL, pkt->dma_address,
 						pkt->skb->len,
-						DMA_TO_DEVICE);
+						bam_ops->dma_to);
 		else
 			dma_unmap_single(NULL, pkt->dma_address,
 						pkt->len,
-						DMA_TO_DEVICE);
+						bam_ops->dma_to);
 		queue_work(bam_mux_tx_workqueue, &pkt->work);
 		break;
 	default:
@@ -1288,7 +1314,8 @@
 	case SPS_EVENT_EOT:
 		/* attempt to disable interrupts in this pipe */
 		if (!polling_mode) {
-			ret = sps_get_config(bam_rx_pipe, &cur_rx_conn);
+			ret = bam_ops->sps_get_config_ptr(bam_rx_pipe,
+					&cur_rx_conn);
 			if (ret) {
 				pr_err("%s: sps_get_config() failed %d, interrupts"
 					" not disabled\n", __func__, ret);
@@ -1296,7 +1323,8 @@
 			}
 			cur_rx_conn.options = SPS_O_AUTO_ENABLE |
 				SPS_O_ACK_TRANSFERS | SPS_O_POLL;
-			ret = sps_set_config(bam_rx_pipe, &cur_rx_conn);
+			ret = bam_ops->sps_set_config_ptr(bam_rx_pipe,
+					&cur_rx_conn);
 			if (ret) {
 				pr_err("%s: sps_set_config() failed %d, interrupts"
 					" not disabled\n", __func__, ret);
@@ -1476,9 +1504,11 @@
 
 	bam_dmux_uplink_vote = vote;
 	if (vote)
-		smsm_change_state(SMSM_APPS_STATE, 0, SMSM_A2_POWER_CONTROL);
+		bam_ops->smsm_change_state_ptr(SMSM_APPS_STATE,
+			0, SMSM_A2_POWER_CONTROL);
 	else
-		smsm_change_state(SMSM_APPS_STATE, SMSM_A2_POWER_CONTROL, 0);
+		bam_ops->smsm_change_state_ptr(SMSM_APPS_STATE,
+			SMSM_A2_POWER_CONTROL, 0);
 }
 
 /*
@@ -1747,29 +1777,31 @@
 	if (!power_management_only_mode) {
 		if (ssr_skipped_disconnect) {
 			/* delayed to here to prevent bus stall */
-			sps_disconnect(bam_tx_pipe);
-			sps_disconnect(bam_rx_pipe);
+			bam_ops->sps_disconnect_ptr(bam_tx_pipe);
+			bam_ops->sps_disconnect_ptr(bam_rx_pipe);
 			__memzero(rx_desc_mem_buf.base, rx_desc_mem_buf.size);
 			__memzero(tx_desc_mem_buf.base, tx_desc_mem_buf.size);
 		}
 		ssr_skipped_disconnect = 0;
-		i = sps_device_reset(a2_device_handle);
+		i = bam_ops->sps_device_reset_ptr(a2_device_handle);
 		if (i)
 			pr_err("%s: device reset failed rc = %d\n", __func__,
 									i);
-		i = sps_connect(bam_tx_pipe, &tx_connection);
+		i = bam_ops->sps_connect_ptr(bam_tx_pipe, &tx_connection);
 		if (i)
 			pr_err("%s: tx connection failed rc = %d\n", __func__,
 									i);
-		i = sps_connect(bam_rx_pipe, &rx_connection);
+		i = bam_ops->sps_connect_ptr(bam_rx_pipe, &rx_connection);
 		if (i)
 			pr_err("%s: rx connection failed rc = %d\n", __func__,
 									i);
-		i = sps_register_event(bam_tx_pipe, &tx_register_event);
+		i = bam_ops->sps_register_event_ptr(bam_tx_pipe,
+				&tx_register_event);
 		if (i)
 			pr_err("%s: tx event reg failed rc = %d\n", __func__,
 									i);
-		i = sps_register_event(bam_rx_pipe, &rx_register_event);
+		i = bam_ops->sps_register_event_ptr(bam_rx_pipe,
+				&rx_register_event);
 		if (i)
 			pr_err("%s: rx event reg failed rc = %d\n", __func__,
 									i);
@@ -1823,9 +1855,9 @@
 	if (!power_management_only_mode) {
 		if (likely(!in_ssr)) {
 			BAM_DMUX_LOG("%s: disconnect tx\n", __func__);
-			sps_disconnect(bam_tx_pipe);
+			bam_ops->sps_disconnect_ptr(bam_tx_pipe);
 			BAM_DMUX_LOG("%s: disconnect rx\n", __func__);
-			sps_disconnect(bam_rx_pipe);
+			bam_ops->sps_disconnect_ptr(bam_rx_pipe);
 			__memzero(rx_desc_mem_buf.base, rx_desc_mem_buf.size);
 			__memzero(tx_desc_mem_buf.base, tx_desc_mem_buf.size);
 			BAM_DMUX_LOG("%s: device reset\n", __func__);
@@ -1842,7 +1874,7 @@
 		list_del(node);
 		info = container_of(node, struct rx_pkt_info, list_node);
 		dma_unmap_single(NULL, info->dma_address, BUFFER_SIZE,
-							DMA_FROM_DEVICE);
+							bam_ops->dma_from);
 		dev_kfree_skb_any(info->skb);
 		kfree(info);
 	}
@@ -1957,9 +1989,12 @@
 	 * because a watchdog crash from a bus stall would likely occur.
 	 */
 	if (code == SUBSYS_BEFORE_SHUTDOWN) {
+		BAM_DMUX_LOG("%s: begin\n", __func__);
 		in_global_reset = 1;
 		in_ssr = 1;
-		BAM_DMUX_LOG("%s: begin\n", __func__);
+		/* wait till all bam_dmux writes completes */
+		synchronize_srcu(&bam_dmux_srcu);
+		BAM_DMUX_LOG("%s: ssr signaling complete\n", __func__);
 		flush_workqueue(bam_mux_rx_workqueue);
 	}
 	if (code != SUBSYS_AFTER_SHUTDOWN)
@@ -2008,12 +2043,12 @@
 		if (!info->is_cmd) {
 			dma_unmap_single(NULL, info->dma_address,
 						info->skb->len,
-						DMA_TO_DEVICE);
+						bam_ops->dma_to);
 			dev_kfree_skb_any(info->skb);
 		} else {
 			dma_unmap_single(NULL, info->dma_address,
 						info->len,
-						DMA_TO_DEVICE);
+						bam_ops->dma_to);
 			kfree(info->skb);
 		}
 		kfree(info);
@@ -2053,20 +2088,20 @@
 	if (cpu_is_msm9615() || satellite_mode)
 		a2_props.manage = SPS_BAM_MGR_DEVICE_REMOTE;
 	/* need to free on tear down */
-	ret = sps_register_bam_device(&a2_props, &h);
+	ret = bam_ops->sps_register_bam_device_ptr(&a2_props, &h);
 	if (ret < 0) {
 		pr_err("%s: register bam error %d\n", __func__, ret);
 		goto register_bam_failed;
 	}
 	a2_device_handle = h;
 
-	bam_tx_pipe = sps_alloc_endpoint();
+	bam_tx_pipe = bam_ops->sps_alloc_endpoint_ptr();
 	if (bam_tx_pipe == NULL) {
 		pr_err("%s: tx alloc endpoint failed\n", __func__);
 		ret = -ENOMEM;
 		goto tx_alloc_endpoint_failed;
 	}
-	ret = sps_get_config(bam_tx_pipe, &tx_connection);
+	ret = bam_ops->sps_get_config_ptr(bam_tx_pipe, &tx_connection);
 	if (ret) {
 		pr_err("%s: tx get config failed %d\n", __func__, ret);
 		goto tx_get_config_failed;
@@ -2091,19 +2126,19 @@
 	tx_connection.desc = tx_desc_mem_buf;
 	tx_connection.event_thresh = 0x10;
 
-	ret = sps_connect(bam_tx_pipe, &tx_connection);
+	ret = bam_ops->sps_connect_ptr(bam_tx_pipe, &tx_connection);
 	if (ret < 0) {
 		pr_err("%s: tx connect error %d\n", __func__, ret);
 		goto tx_connect_failed;
 	}
 
-	bam_rx_pipe = sps_alloc_endpoint();
+	bam_rx_pipe = bam_ops->sps_alloc_endpoint_ptr();
 	if (bam_rx_pipe == NULL) {
 		pr_err("%s: rx alloc endpoint failed\n", __func__);
 		ret = -ENOMEM;
 		goto rx_alloc_endpoint_failed;
 	}
-	ret = sps_get_config(bam_rx_pipe, &rx_connection);
+	ret = bam_ops->sps_get_config_ptr(bam_rx_pipe, &rx_connection);
 	if (ret) {
 		pr_err("%s: rx get config failed %d\n", __func__, ret);
 		goto rx_get_config_failed;
@@ -2129,7 +2164,7 @@
 	rx_connection.desc = rx_desc_mem_buf;
 	rx_connection.event_thresh = 0x10;
 
-	ret = sps_connect(bam_rx_pipe, &rx_connection);
+	ret = bam_ops->sps_connect_ptr(bam_rx_pipe, &rx_connection);
 	if (ret < 0) {
 		pr_err("%s: rx connect error %d\n", __func__, ret);
 		goto rx_connect_failed;
@@ -2140,7 +2175,7 @@
 	tx_register_event.xfer_done = NULL;
 	tx_register_event.callback = bam_mux_tx_notify;
 	tx_register_event.user = NULL;
-	ret = sps_register_event(bam_tx_pipe, &tx_register_event);
+	ret = bam_ops->sps_register_event_ptr(bam_tx_pipe, &tx_register_event);
 	if (ret < 0) {
 		pr_err("%s: tx register event error %d\n", __func__, ret);
 		goto rx_event_reg_failed;
@@ -2151,7 +2186,7 @@
 	rx_register_event.xfer_done = NULL;
 	rx_register_event.callback = bam_mux_rx_notify;
 	rx_register_event.user = NULL;
-	ret = sps_register_event(bam_rx_pipe, &rx_register_event);
+	ret = bam_ops->sps_register_event_ptr(bam_rx_pipe, &rx_register_event);
 	if (ret < 0) {
 		pr_err("%s: tx register event error %d\n", __func__, ret);
 		goto rx_event_reg_failed;
@@ -2171,22 +2206,22 @@
 	return 0;
 
 rx_event_reg_failed:
-	sps_disconnect(bam_rx_pipe);
+	bam_ops->sps_disconnect_ptr(bam_rx_pipe);
 rx_connect_failed:
 	dma_free_coherent(NULL, rx_desc_mem_buf.size, rx_desc_mem_buf.base,
 				rx_desc_mem_buf.phys_base);
 rx_mem_failed:
 rx_get_config_failed:
-	sps_free_endpoint(bam_rx_pipe);
+	bam_ops->sps_free_endpoint_ptr(bam_rx_pipe);
 rx_alloc_endpoint_failed:
-	sps_disconnect(bam_tx_pipe);
+	bam_ops->sps_disconnect_ptr(bam_tx_pipe);
 tx_connect_failed:
 	dma_free_coherent(NULL, tx_desc_mem_buf.size, tx_desc_mem_buf.base,
 				tx_desc_mem_buf.phys_base);
 tx_get_config_failed:
-	sps_free_endpoint(bam_tx_pipe);
+	bam_ops->sps_free_endpoint_ptr(bam_tx_pipe);
 tx_alloc_endpoint_failed:
-	sps_deregister_bam_device(h);
+	bam_ops->sps_deregister_bam_device_ptr(h);
 	/*
 	 * sps_deregister_bam_device() calls iounmap.  calling iounmap on the
 	 * same handle below will cause a crash, so skip it if we've freed
@@ -2224,7 +2259,7 @@
 	a2_props.summing_threshold = A2_SUMMING_THRESHOLD;
 	if (cpu_is_msm9615() || satellite_mode)
 		a2_props.manage = SPS_BAM_MGR_DEVICE_REMOTE;
-	ret = sps_register_bam_device(&a2_props, &h);
+	ret = bam_ops->sps_register_bam_device_ptr(&a2_props, &h);
 	if (ret < 0) {
 		pr_err("%s: register bam error %d\n", __func__, ret);
 		goto register_bam_failed;
@@ -2276,7 +2311,7 @@
 
 	BAM_DMUX_LOG("%s: apps ack %d->%d\n", __func__,
 			clear_bit & 0x1, ~clear_bit & 0x1);
-	smsm_change_state(SMSM_APPS_STATE,
+	bam_ops->smsm_change_state_ptr(SMSM_APPS_STATE,
 				clear_bit & SMSM_A2_POWER_CONTROL_ACK,
 				~clear_bit & SMSM_A2_POWER_CONTROL_ACK);
 	clear_bit = ~clear_bit;
@@ -2333,6 +2368,51 @@
 	complete_all(&ul_wakeup_ack_completion);
 }
 
+/**
+ * msm_bam_dmux_set_bam_ops() - sets the bam_ops
+ * @ops: bam_ops_if to set
+ *
+ * Sets bam_ops to allow switching of runtime behavior. Preconditon, bam dmux
+ * must be in an idle state. If input ops is NULL, then bam_ops will be
+ * restored to their default state.
+ */
+void msm_bam_dmux_set_bam_ops(struct bam_ops_if *ops)
+{
+	if (ops != NULL)
+		bam_ops = ops;
+	else
+		bam_ops = &bam_default_ops;
+}
+EXPORT_SYMBOL(msm_bam_dmux_set_bam_ops);
+
+/**
+ * msm_bam_dmux_deinit() - puts bam dmux into a deinited state
+ *
+ * Puts bam dmux into a deinitialized state by simulating an ssr.
+ */
+void msm_bam_dmux_deinit(void)
+{
+	restart_notifier_cb(NULL, SUBSYS_BEFORE_SHUTDOWN, NULL);
+	restart_notifier_cb(NULL, SUBSYS_AFTER_SHUTDOWN, NULL);
+}
+EXPORT_SYMBOL(msm_bam_dmux_deinit);
+
+/**
+ * msm_bam_dmux_reinit() - reinitializes bam dmux
+ */
+void msm_bam_dmux_reinit(void)
+{
+	bam_ops->smsm_state_cb_register_ptr(SMSM_MODEM_STATE,
+			SMSM_A2_POWER_CONTROL,
+			bam_dmux_smsm_cb, NULL);
+	bam_ops->smsm_state_cb_register_ptr(SMSM_MODEM_STATE,
+			SMSM_A2_POWER_CONTROL_ACK,
+			bam_dmux_smsm_ack_cb, NULL);
+	bam_mux_initialized = 0;
+	bam_init();
+}
+EXPORT_SYMBOL(msm_bam_dmux_reinit);
+
 static int bam_dmux_probe(struct platform_device *pdev)
 {
 	int rc;
@@ -2432,11 +2512,12 @@
 	init_completion(&shutdown_completion);
 	complete_all(&shutdown_completion);
 	INIT_DELAYED_WORK(&ul_timeout_work, ul_timeout);
-	INIT_DELAYED_WORK(&queue_rx_work, queue_rx_work_func);
 	wake_lock_init(&bam_wakelock, WAKE_LOCK_SUSPEND, "bam_dmux_wakelock");
+	init_srcu_struct(&bam_dmux_srcu);
 
-	rc = smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_A2_POWER_CONTROL,
-					bam_dmux_smsm_cb, NULL);
+	rc = bam_ops->smsm_state_cb_register_ptr(SMSM_MODEM_STATE,
+			SMSM_A2_POWER_CONTROL,
+			bam_dmux_smsm_cb, NULL);
 
 	if (rc) {
 		destroy_workqueue(bam_mux_rx_workqueue);
@@ -2445,13 +2526,14 @@
 		return -ENOMEM;
 	}
 
-	rc = smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_A2_POWER_CONTROL_ACK,
-					bam_dmux_smsm_ack_cb, NULL);
+	rc = bam_ops->smsm_state_cb_register_ptr(SMSM_MODEM_STATE,
+			SMSM_A2_POWER_CONTROL_ACK,
+			bam_dmux_smsm_ack_cb, NULL);
 
 	if (rc) {
 		destroy_workqueue(bam_mux_rx_workqueue);
 		destroy_workqueue(bam_mux_tx_workqueue);
-		smsm_state_cb_deregister(SMSM_MODEM_STATE,
+		bam_ops->smsm_state_cb_deregister_ptr(SMSM_MODEM_STATE,
 					SMSM_A2_POWER_CONTROL,
 					bam_dmux_smsm_cb, NULL);
 		pr_err("%s: smsm ack cb register failed, rc: %d\n", __func__,
@@ -2461,8 +2543,10 @@
 		return -ENOMEM;
 	}
 
-	if (smsm_get_state(SMSM_MODEM_STATE) & SMSM_A2_POWER_CONTROL)
-		bam_dmux_smsm_cb(NULL, 0, smsm_get_state(SMSM_MODEM_STATE));
+	if (bam_ops->smsm_get_state_ptr(SMSM_MODEM_STATE) &
+			SMSM_A2_POWER_CONTROL)
+		bam_dmux_smsm_cb(NULL, 0,
+			bam_ops->smsm_get_state_ptr(SMSM_MODEM_STATE));
 
 	return 0;
 }
diff --git a/arch/arm/mach-msm/bam_dmux_private.h b/arch/arm/mach-msm/bam_dmux_private.h
new file mode 100644
index 0000000..871dd64
--- /dev/null
+++ b/arch/arm/mach-msm/bam_dmux_private.h
@@ -0,0 +1,173 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _BAM_DMUX_PRIVATE_H
+#define _BAM_DMUX_PRIVATE_H
+
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/sps.h>
+
+#define BAM_MUX_HDR_MAGIC_NO			0x33fc
+#define BAM_MUX_HDR_CMD_DATA			0
+#define BAM_MUX_HDR_CMD_OPEN			1
+#define BAM_MUX_HDR_CMD_CLOSE			2
+#define BAM_MUX_HDR_CMD_STATUS			3 /* unused */
+#define BAM_MUX_HDR_CMD_OPEN_NO_A2_PC		4
+#define BUFFER_SIZE				2048
+
+/**
+ * struct bam_ops_if - collection of function pointers to allow swappable
+ * runtime functionality
+ * @smsm_change_state_ptr: pointer to smsm_change_state function
+ * @smsm_get_state_ptr: pointer to smsm_get_state function
+ * @smsm_state_cb_register_ptr: pointer to smsm_state_cb_register function
+ * @smsm_state_cb_deregister_ptr: pointer to smsm_state_cb_deregister function
+ * @sps_connect_ptr: pointer to sps_connect function
+ * @sps_disconnect_ptr: pointer to sps_disconnect function
+ * @sps_register_bam_device_ptr: pointer to sps_register_bam_device
+ * @sps_deregister_bam_device_ptr: pointer to sps_deregister_bam_device
+ * function
+ * @sps_alloc_endpoint_ptr: pointer to sps_alloc_endpoint function
+ * @sps_free_endpoint_ptr: pointer to sps_free_endpoint function
+ * @sps_set_config_ptr: pointer to sps_set_config function
+ * @sps_get_config_ptr: pointer to sps_get_config function
+ * @sps_device_reset_ptr: pointer to sps_device_reset function
+ * @sps_register_event_ptr: pointer to sps_register_event function
+ * @sps_transfer_one_ptr: pointer to sps_transfer_one function
+ * @sps_get_iovec_ptr: pointer to sps_get_iovec function
+ * @sps_get_unused_desc_num_ptr: pointer to sps_get_unused_desc_num function
+ * @dma_to: enum for the direction of dma operations to device
+ * @dma_from: enum for the direction of dma operations from device
+ *
+ * This struct contains the interface from bam_dmux to smsm and sps. The
+ * pointers can be swapped out at run time to provide different functionality.
+ */
+struct bam_ops_if {
+	/* smsm */
+	int (*smsm_change_state_ptr)(uint32_t smsm_entry,
+		uint32_t clear_mask, uint32_t set_mask);
+
+	uint32_t (*smsm_get_state_ptr)(uint32_t smsm_entry);
+
+	int (*smsm_state_cb_register_ptr)(uint32_t smsm_entry, uint32_t mask,
+		void (*notify)(void *, uint32_t old_state, uint32_t new_state),
+		void *data);
+
+	int (*smsm_state_cb_deregister_ptr)(uint32_t smsm_entry, uint32_t mask,
+		void (*notify)(void *, uint32_t, uint32_t), void *data);
+
+	/* sps */
+	int (*sps_connect_ptr)(struct sps_pipe *h, struct sps_connect *connect);
+
+	int (*sps_disconnect_ptr)(struct sps_pipe *h);
+
+	int (*sps_register_bam_device_ptr)(
+		const struct sps_bam_props *bam_props,
+		u32 *dev_handle);
+
+	int (*sps_deregister_bam_device_ptr)(u32 dev_handle);
+
+	struct sps_pipe *(*sps_alloc_endpoint_ptr)(void);
+
+	int (*sps_free_endpoint_ptr)(struct sps_pipe *h);
+
+	int (*sps_set_config_ptr)(struct sps_pipe *h,
+		struct sps_connect *config);
+
+	int (*sps_get_config_ptr)(struct sps_pipe *h,
+		struct sps_connect *config);
+
+	int (*sps_device_reset_ptr)(u32 dev);
+
+	int (*sps_register_event_ptr)(struct sps_pipe *h,
+		struct sps_register_event *reg);
+
+	int (*sps_transfer_one_ptr)(struct sps_pipe *h,
+		u32 addr, u32 size,
+		void *user, u32 flags);
+
+	int (*sps_get_iovec_ptr)(struct sps_pipe *h,
+		struct sps_iovec *iovec);
+
+	int (*sps_get_unused_desc_num_ptr)(struct sps_pipe *h,
+		u32 *desc_num);
+
+	enum dma_data_direction dma_to;
+
+	enum dma_data_direction dma_from;
+};
+
+/**
+ * struct bam_mux_hdr - struct which contains bam dmux header info
+ * @magic_num: magic number placed at start to ensure that it is actually a
+ * valid bam dmux header
+ * @reserved: for later use
+ * @cmd: the command
+ * @pad_len: the length of padding
+ * @ch_id: the id of the bam dmux channel that this is sent on
+ * @pkt_len: the length of the packet that this is the header of
+ */
+struct bam_mux_hdr {
+	uint16_t magic_num;
+	uint8_t reserved;
+	uint8_t cmd;
+	uint8_t pad_len;
+	uint8_t ch_id;
+	uint16_t pkt_len;
+};
+
+/**
+ * struct rx_pkt_info - struct describing an rx packet
+ * @skb: socket buffer containing the packet
+ * @dma_address: dma mapped address of the packet
+ * @work: work_struct for processing the packet
+ * @list_node: list_head for placing this on a list
+ */
+struct rx_pkt_info {
+	struct sk_buff *skb;
+	dma_addr_t dma_address;
+	struct work_struct work;
+	struct list_head list_node;
+};
+
+/**
+ * struct tx_pkt_info - struct describing a tx packet
+ * @skb: socket buffer containing the packet
+ * @dma_address: dma mapped address of the packet
+ * @is_cmd: signifies whether this is a command or data packet
+ * @len: length og the packet
+ * @work: work_struct for processing this packet
+ * @list_node: list_head for placing this on a list
+ * @ts_sec: seconds portion of the timestamp
+ * @ts_nsec: nanoseconds portion of the timestamp
+ *
+ */
+struct tx_pkt_info {
+	struct sk_buff *skb;
+	dma_addr_t dma_address;
+	char is_cmd;
+	uint32_t len;
+	struct work_struct work;
+	struct list_head list_node;
+	unsigned ts_sec;
+	unsigned long ts_nsec;
+};
+
+void msm_bam_dmux_set_bam_ops(struct bam_ops_if *ops);
+
+void msm_bam_dmux_deinit(void);
+
+void msm_bam_dmux_reinit(void);
+
+#endif /* _BAM_DMUX_PRIVATE_H */
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/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index 3a0c152..3c5ddc5 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -3150,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_pin.c, "2-000e"),
+	CLK_LOOKUP("ref_clk",            cxo_d1_a_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-8974.c b/arch/arm/mach-msm/clock-8974.c
index 0051578..6ae909b 100755
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -579,17 +579,6 @@
 			| BVAL(10, 8, s##_mm_source_val), \
 	}
 
-#define F_HDMI(f, s, div, m, n) \
-	{ \
-		.freq_hz = (f), \
-		.src_clk = &s##_clk_src, \
-		.m_val = (m), \
-		.n_val = ~((n)-(m)) * !!(n), \
-		.d_val = ~(n),\
-		.div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \
-			| BVAL(10, 8, s##_mm_source_val), \
-	}
-
 #define F_EDP(f, s, div, m, n) \
 	{ \
 		.freq_hz = (f), \
@@ -3267,60 +3256,19 @@
 	},
 };
 
-static int hdmi_pll_clk_enable(struct clk *c)
-{
-	return hdmi_pll_enable();
-}
-
-static void hdmi_pll_clk_disable(struct clk *c)
-{
-	hdmi_pll_disable();
-}
-
-static int hdmi_pll_clk_set_rate(struct clk *c, unsigned long rate)
-{
-	return hdmi_pll_set_rate(rate);
-}
-
-static struct clk_ops clk_ops_hdmi_pll = {
-	.enable = hdmi_pll_clk_enable,
-	.disable = hdmi_pll_clk_disable,
-	.set_rate = hdmi_pll_clk_set_rate,
-};
-
-static struct clk hdmipll_clk_src = {
-	.parent = &cxo_clk_src.c,
-	.dbg_name = "hdmipll_clk_src",
-	.ops = &clk_ops_hdmi_pll,
-	CLK_INIT(hdmipll_clk_src),
-};
-
 static struct clk_freq_tbl ftbl_mdss_extpclk_clk[] = {
-	/*
-	 * The zero rate is required since suspend/resume wipes out the HDMI PHY
-	 * registers. This entry allows the HDMI driver to switch the cached
-	 * rate to zero before suspend and back to the real rate after resume.
-	 */
-	F_HDMI(        0, hdmipll, 1, 0, 0),
-	F_HDMI( 25200000, hdmipll, 1, 0, 0),
-	F_HDMI( 27000000, hdmipll, 1, 0, 0),
-	F_HDMI( 27030000, hdmipll, 1, 0, 0),
-	F_HDMI( 65000000, hdmipll, 1, 0, 0),
-	F_HDMI( 74250000, hdmipll, 1, 0, 0),
-	F_HDMI(108000000, hdmipll, 1, 0, 0),
-	F_HDMI(148500000, hdmipll, 1, 0, 0),
-	F_HDMI(268500000, hdmipll, 1, 0, 0),
-	F_HDMI(297000000, hdmipll, 1, 0, 0),
+	F_MM(148500000, hdmipll, 1, 0, 0),
 	F_END
 };
 
 static struct rcg_clk extpclk_clk_src = {
 	.cmd_rcgr_reg = EXTPCLK_CMD_RCGR,
 	.freq_tbl = ftbl_mdss_extpclk_clk,
-	.current_freq = &rcg_dummy_freq,
+	.current_freq = ftbl_mdss_extpclk_clk,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
 		.dbg_name = "extpclk_clk_src",
+		.parent = &hdmipll_clk_src.c,
 		.ops = &clk_ops_rcg_hdmi,
 		VDD_DIG_FMAX_MAP2(LOW, 148500000, NOMINAL, 297000000),
 		CLK_INIT(extpclk_clk_src.c),
diff --git a/arch/arm/mach-msm/clock-a7.c b/arch/arm/mach-msm/clock-a7.c
index 5b8dc4e..d09e4b6 100644
--- a/arch/arm/mach-msm/clock-a7.c
+++ b/arch/arm/mach-msm/clock-a7.c
@@ -193,7 +193,8 @@
 	if (!c->fmax)
 		return -ENOMEM;
 
-	array = devm_kzalloc(&pdev->dev, prop_len * sizeof(u32), GFP_KERNEL);
+	array = devm_kzalloc(&pdev->dev,
+			prop_len * sizeof(u32) * 2, GFP_KERNEL);
 	if (!array)
 		return -ENOMEM;
 
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index cc6f290..e3693ee 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -843,23 +843,16 @@
  */
 static int rcg_clk_set_rate_hdmi(struct clk *c, unsigned long rate)
 {
-	struct clk_freq_tbl *nf;
 	struct rcg_clk *rcg = to_rcg_clk(c);
+	struct clk_freq_tbl *nf = rcg->freq_tbl;
 	int rc;
 
-	for (nf = rcg->freq_tbl; nf->freq_hz != rate; nf++)
-		if (nf->freq_hz == FREQ_END) {
-			rc = -EINVAL;
-			goto out;
-		}
-
 	rc = clk_set_rate(nf->src_clk, rate);
 	if (rc < 0)
 		goto out;
 	set_rate_hid(rcg, nf);
 
 	rcg->current_freq = nf;
-	c->parent = nf->src_clk;
 out:
 	return rc;
 }
@@ -870,12 +863,6 @@
 	struct clk *clk;
 	struct clk_freq_tbl *freq;
 	uint32_t rate;
-	u32 cmd_rcgr_regval;
-
-	/* Is there a pending configuration? */
-	cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg));
-	if (cmd_rcgr_regval & CMD_RCGR_CONFIG_DIRTY_MASK)
-		return NULL;
 
 	/* Figure out what rate the rcg is running at */
 	for (freq = rcg->freq_tbl; freq->freq_hz != FREQ_END; freq++) {
@@ -895,6 +882,21 @@
 	return freq->src_clk;
 }
 
+static struct clk *rcg_hdmi_clk_get_parent(struct clk *c)
+{
+	struct rcg_clk *rcg = to_rcg_clk(c);
+	struct clk_freq_tbl *freq = rcg->freq_tbl;
+	u32 cmd_rcgr_regval;
+
+	/* Is there a pending configuration? */
+	cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg));
+	if (cmd_rcgr_regval & CMD_RCGR_CONFIG_DIRTY_MASK)
+		return NULL;
+
+	rcg->current_freq->freq_hz = clk_get_rate(c->parent);
+
+	return freq->src_clk;
+}
 
 static DEFINE_SPINLOCK(mux_reg_lock);
 
@@ -1007,7 +1009,7 @@
 	.list_rate = rcg_clk_list_rate,
 	.round_rate = rcg_clk_round_rate,
 	.handoff = rcg_clk_handoff,
-	.get_parent = rcg_clk_get_parent,
+	.get_parent = rcg_hdmi_clk_get_parent,
 };
 
 struct clk_ops clk_ops_rcg_edp = {
diff --git a/arch/arm/mach-msm/clock-mdss-8974.c b/arch/arm/mach-msm/clock-mdss-8974.c
index b500e1d..d1b1885 100644
--- a/arch/arm/mach-msm/clock-mdss-8974.c
+++ b/arch/arm/mach-msm/clock-mdss-8974.c
@@ -171,23 +171,71 @@
 		(!(readl_relaxed(gdsc_base) & BIT(0)));
 }
 
-void hdmi_pll_disable(void)
+/* Auto PLL calibaration */
+static int mdss_ahb_clk_enable(int enable)
 {
-	clk_enable(mdss_ahb_clk);
+	int rc = 0;
+
+	/* todo: Ideally, we should enable/disable GDSC whenever we are
+	 * attempting to enable/disable MDSS AHB clock.
+	 * For now, just return error if  GDSC is not enabled.
+	 */
+	if (!mdss_gdsc_enabled()) {
+		pr_err("%s: mdss GDSC is not enabled\n", __func__);
+		return -EPERM;
+	}
+
+	if (enable)
+		rc = clk_prepare_enable(mdss_ahb_clk);
+	else
+		clk_disable_unprepare(mdss_ahb_clk);
+
+	return rc;
+}
+
+static void hdmi_vco_disable(struct clk *c)
+{
+	u32 rc;
+
+	if (!mdss_gdsc_enabled()) {
+		pr_err("%s: mdss GDSC is not enabled\n", __func__);
+		return;
+	}
+
+	rc = clk_enable(mdss_ahb_clk);
+	if (rc) {
+		pr_err("%s: failed to enable mdss ahb clock. rc=%d\n",
+			__func__, rc);
+		return;
+	}
+
 	REG_W(0x0, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
 	udelay(5);
 	REG_W(0x0, hdmi_phy_base + HDMI_PHY_GLB_CFG);
+
 	clk_disable(mdss_ahb_clk);
 
 	hdmi_pll_on = 0;
-} /* hdmi_pll_disable */
+} /* hdmi_vco_disable */
 
-int hdmi_pll_enable(void)
+static int hdmi_vco_enable(struct clk *c)
 {
 	u32 status;
+	u32 rc;
 	u32 max_reads, timeout_us;
 
-	clk_enable(mdss_ahb_clk);
+	if (!mdss_gdsc_enabled()) {
+		pr_err("%s: mdss GDSC is not enabled\n", __func__);
+		return -EPERM;
+	}
+
+	rc = clk_enable(mdss_ahb_clk);
+	if (rc) {
+		pr_err("%s: failed to enable mdss ahb clock. rc=%d\n",
+			__func__, rc);
+		return rc;
+	}
+
 	/* Global Enable */
 	REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
 	/* Power up power gen */
@@ -212,7 +260,7 @@
 		status, ((status & BIT(0)) == 1), max_reads, timeout_us)) {
 		pr_err("%s: hdmi phy pll status=%x failed to Lock\n",
 		       __func__, status);
-		hdmi_pll_disable();
+		hdmi_vco_disable(c);
 		clk_disable(mdss_ahb_clk);
 		return -EINVAL;
 	}
@@ -226,7 +274,7 @@
 		status, ((status & BIT(0)) == 1), max_reads, timeout_us)) {
 		pr_err("%s: hdmi phy status=%x failed to Lock\n",
 		       __func__, status);
-		hdmi_pll_disable();
+		hdmi_vco_disable(c);
 		clk_disable(mdss_ahb_clk);
 		return -EINVAL;
 	}
@@ -236,25 +284,173 @@
 	hdmi_pll_on = 1;
 
 	return 0;
-} /* hdmi_pll_enable */
+} /* hdmi_vco_enable */
 
-int hdmi_pll_set_rate(unsigned long rate)
+static inline struct hdmi_pll_vco_clk *to_hdmi_vco_clk(struct clk *clk)
+{
+	return container_of(clk, struct hdmi_pll_vco_clk, c);
+}
+
+static void hdmi_phy_pll_calculator(u32 vco_freq)
+{
+	u32 ref_clk             = 19200000;
+	u32 sdm_mode            = 1;
+	u32 ref_clk_multiplier  = sdm_mode == 1 ? 2 : 1;
+	u32 int_ref_clk_freq    = ref_clk * ref_clk_multiplier;
+	u32 fbclk_pre_div       = 1;
+	u32 ssc_mode            = 0;
+	u32 kvco                = 270;
+	u32 vdd                 = 95;
+	u32 ten_power_six       = 1000000;
+	u32 ssc_ds_ppm          = ssc_mode ? 5000 : 0;
+	u32 sdm_res             = 16;
+	u32 ssc_tri_step        = 32;
+	u32 ssc_freq            = 2;
+	u64 ssc_ds              = vco_freq * ssc_ds_ppm;
+	u32 div_in_freq         = vco_freq / fbclk_pre_div;
+	u64 dc_offset           = (div_in_freq / int_ref_clk_freq - 1) *
+					ten_power_six * 10;
+	u32 ssc_kdiv            = (int_ref_clk_freq / ssc_freq) -
+					ten_power_six;
+	u64 sdm_freq_seed;
+	u32 ssc_tri_inc;
+	u64 fb_div_n;
+
+	u32 val;
+
+	pr_debug("%s: vco_freq = %u\n", __func__, vco_freq);
+
+	do_div(ssc_ds, (u64)ten_power_six);
+
+	fb_div_n = (u64)div_in_freq * (u64)ten_power_six * 10;
+	do_div(fb_div_n, int_ref_clk_freq);
+
+	sdm_freq_seed = ((fb_div_n - dc_offset - ten_power_six * 10) *
+				(1 << sdm_res)  * 10) + 5;
+	do_div(sdm_freq_seed, ((u64)ten_power_six * 100));
+
+	ssc_tri_inc = (u32)ssc_ds;
+	ssc_tri_inc = (ssc_tri_inc / int_ref_clk_freq) * (1 << 16) /
+			ssc_tri_step;
+
+	val = (ref_clk_multiplier == 2 ? 1 : 0) +
+		((fbclk_pre_div == 2 ? 1 : 0) * 16);
+	pr_debug("%s: HDMI_UNI_PLL_REFCLK_CFG = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_REFCLK_CFG);
+
+	REG_W(0x02, hdmi_phy_pll_base + HDMI_UNI_PLL_CHFPUMP_CFG);
+	REG_W(0x19, hdmi_phy_pll_base + HDMI_UNI_PLL_VCOLPF_CFG);
+	REG_W(0x04, hdmi_phy_pll_base + HDMI_UNI_PLL_VREG_CFG);
+	REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_PWRGEN_CFG);
+	REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
+	REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
+	REG_W(0x0E, hdmi_phy_pll_base + HDMI_UNI_PLL_LPFR_CFG);
+	REG_W(0x20, hdmi_phy_pll_base + HDMI_UNI_PLL_LPFC1_CFG);
+	REG_W(0x0D, hdmi_phy_pll_base + HDMI_UNI_PLL_LPFC2_CFG);
+
+	do_div(dc_offset, (u64)ten_power_six * 10);
+	val = sdm_mode == 0 ? 64 + dc_offset : 0;
+	pr_debug("%s: HDMI_UNI_PLL_SDM_CFG0 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG0);
+
+	val = 64 + dc_offset;
+	pr_debug("%s: HDMI_UNI_PLL_SDM_CFG1 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG1);
+
+	val = sdm_freq_seed & 0xFF;
+	pr_debug("%s: HDMI_UNI_PLL_SDM_CFG2 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG2);
+
+	val = (sdm_freq_seed >> 8) & 0xFF;
+	pr_debug("%s: HDMI_UNI_PLL_SDM_CFG3 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG3);
+
+	val = (sdm_freq_seed >> 16) & 0xFF;
+	pr_debug("%s: HDMI_UNI_PLL_SDM_CFG4 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG4);
+
+	val = (ssc_mode == 0 ? 128 : 0) + (ssc_kdiv / ten_power_six);
+	pr_debug("%s: HDMI_UNI_PLL_SSC_CFG0 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SSC_CFG0);
+
+	val = ssc_tri_inc & 0xFF;
+	pr_debug("%s: HDMI_UNI_PLL_SSC_CFG1 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SSC_CFG1);
+
+	val = (ssc_tri_inc >> 8) & 0xFF;
+	pr_debug("%s: HDMI_UNI_PLL_SSC_CFG2 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SSC_CFG2);
+
+	pr_debug("%s: HDMI_UNI_PLL_SSC_CFG3 = 0x%x\n", __func__, ssc_tri_step);
+	REG_W(ssc_tri_step, hdmi_phy_pll_base + HDMI_UNI_PLL_SSC_CFG3);
+
+	REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
+	REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
+	REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
+	REG_W(0x0A, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG0);
+	REG_W(0x04, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG1);
+	REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
+	REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG3);
+	REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG4);
+	REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG5);
+
+	val = (kvco * vdd * 10000) / 6;
+	val += 500000;
+	val /= ten_power_six;
+	pr_debug("%s: HDMI_UNI_PLL_CAL_CFG6 = 0x%x\n", __func__, val);
+	REG_W(val & 0xFF, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG6);
+
+	val = (kvco * vdd * 10000) / 6;
+	val -= ten_power_six;
+	val /= ten_power_six;
+	val = (val >> 8) & 0xFF;
+	pr_debug("%s: HDMI_UNI_PLL_CAL_CFG7 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG7);
+
+	val = (ref_clk * 5) / ten_power_six;
+	pr_debug("%s: HDMI_UNI_PLL_CAL_CFG8 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG8);
+
+	val = ((ref_clk * 5) / ten_power_six) >> 8;
+	pr_debug("%s: HDMI_UNI_PLL_CAL_CFG9 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG9);
+
+	vco_freq /= ten_power_six;
+	val = vco_freq & 0xFF;
+	pr_debug("%s: HDMI_UNI_PLL_CAL_CFG10 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG10);
+
+	val = vco_freq >> 8;
+	pr_debug("%s: HDMI_UNI_PLL_CAL_CFG11 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG11);
+} /* hdmi_phy_pll_calculator */
+
+static int hdmi_vco_set_rate(struct clk *c, unsigned long rate)
 {
 	unsigned int set_power_dwn = 0;
+	int rc = 0;
+
+	struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
 
 	if (hdmi_pll_on) {
-		hdmi_pll_disable();
+		hdmi_vco_disable(c);
 		set_power_dwn = 1;
 	}
 
-	clk_enable(mdss_ahb_clk);
+	rc = mdss_ahb_clk_enable(1);
+	if (rc) {
+		pr_err("%s: failed to enable mdss ahb clock. rc=%d\n",
+			__func__, rc);
+		return rc;
+	}
+
 	pr_debug("%s: rate=%ld\n", __func__, rate);
+
 	switch (rate) {
 	case 0:
-		/* This case is needed for suspend/resume. */
-	break;
+		break;
 
-	case 25200000:
+	case 756000000:
 		/* 640x480p60 */
 		REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
@@ -271,7 +467,6 @@
 		REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
 		REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
 		REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
-		REG_W(0x03, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV1_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
@@ -299,7 +494,7 @@
 		udelay(200);
 	break;
 
-	case 27000000:
+	case 810000000:
 		/* 576p50/576i50 case */
 		REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
@@ -316,7 +511,6 @@
 		REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
 		REG_W(0X1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
 		REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
-		REG_W(0x03, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV1_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
@@ -344,7 +538,7 @@
 		udelay(200);
 	break;
 
-	case 27030000:
+	case 810900000:
 		/* 480p60/480i60 case */
 		REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
@@ -361,7 +555,6 @@
 		REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
 		REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
 		REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
-		REG_W(0x03, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV1_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
@@ -388,7 +581,7 @@
 		REG_W(0x05, hdmi_phy_base + HDMI_PHY_TXCAL_CFG3);
 		udelay(200);
 	break;
-	case 65000000:
+	case 650000000:
 		REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_REFCLK_CFG);
@@ -404,7 +597,6 @@
 		REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
 		REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
 		REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
-		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV1_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
@@ -431,7 +623,7 @@
 		REG_W(0x05, hdmi_phy_base + HDMI_PHY_TXCAL_CFG3);
 		udelay(200);
 	break;
-	case 74250000:
+	case 742500000:
 		/*
 		 * 720p60/720p50/1080i60/1080i50
 		 * 1080p24/1080p30/1080p25 case
@@ -451,7 +643,6 @@
 		REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
 		REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
 		REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
-		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV1_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
@@ -479,7 +670,7 @@
 		udelay(200);
 	break;
 
-	case 108000000:
+	case 1080000000:
 		REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_REFCLK_CFG);
@@ -495,7 +686,6 @@
 		REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
 		REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
 		REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
-		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV1_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
@@ -523,51 +713,7 @@
 		udelay(200);
 	break;
 
-	case 148500000:
-		REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
-		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
-		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_REFCLK_CFG);
-		REG_W(0x19, hdmi_phy_pll_base + HDMI_UNI_PLL_VCOLPF_CFG);
-		REG_W(0x0E, hdmi_phy_pll_base + HDMI_UNI_PLL_LPFR_CFG);
-		REG_W(0x20, hdmi_phy_pll_base + HDMI_UNI_PLL_LPFC1_CFG);
-		REG_W(0x0D, hdmi_phy_pll_base + HDMI_UNI_PLL_LPFC2_CFG);
-		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG0);
-		REG_W(0x52, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG1);
-		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG2);
-		REG_W(0x56, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG3);
-		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG4);
-		REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
-		REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
-		REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
-		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV1_CFG);
-		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
-		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
-		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
-		REG_W(0x60, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG8);
-		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG9);
-		REG_W(0xE6, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG10);
-		REG_W(0x02, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG11);
-		REG_W(0x1F, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
-		udelay(50);
-
-		REG_W(0x0F, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
-		REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL1);
-		REG_W(0x10, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
-		REG_W(0xDB, hdmi_phy_base + HDMI_PHY_ANA_CFG0);
-		REG_W(0x43, hdmi_phy_base + HDMI_PHY_ANA_CFG1);
-		REG_W(0x02, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
-		REG_W(0x00, hdmi_phy_base + HDMI_PHY_ANA_CFG3);
-		REG_W(0x04, hdmi_phy_pll_base + HDMI_UNI_PLL_VREG_CFG);
-		REG_W(0xD0, hdmi_phy_base + HDMI_PHY_DCC_CFG0);
-		REG_W(0x1A, hdmi_phy_base + HDMI_PHY_DCC_CFG1);
-		REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG0);
-		REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG1);
-		REG_W(0x02, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2);
-		REG_W(0x05, hdmi_phy_base + HDMI_PHY_TXCAL_CFG3);
-		udelay(200);
-	break;
-
-	case 268500000:
+	case 1342500000:
 		REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_REFCLK_CFG);
@@ -583,7 +729,6 @@
 		REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
 		REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
 		REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
-		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV1_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
@@ -611,7 +756,7 @@
 		udelay(200);
 	break;
 
-	case 297000000:
+	case 1485000000:
 		REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_REFCLK_CFG);
@@ -627,7 +772,6 @@
 		REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
 		REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
 		REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
-		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV1_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
@@ -656,40 +800,68 @@
 	break;
 
 	default:
-		pr_err("%s: not supported rate=%ld\n", __func__, rate);
+		pr_debug("%s: Use pll settings calculator for rate=%ld\n",
+			__func__, rate);
+
+		REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
+		hdmi_phy_pll_calculator(rate);
+		REG_W(0x1F, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
+		udelay(50);
+
+		REG_W(0x0F, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
+		REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL1);
+		REG_W(0x10, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
+		REG_W(0xDB, hdmi_phy_base + HDMI_PHY_ANA_CFG0);
+		REG_W(0x43, hdmi_phy_base + HDMI_PHY_ANA_CFG1);
+
+		if (rate < 825000000) {
+			REG_W(0x01, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
+			REG_W(0x00, hdmi_phy_base + HDMI_PHY_ANA_CFG3);
+		} else if (rate >= 825000000 && rate < 1342500000) {
+			REG_W(0x05, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
+			REG_W(0x03, hdmi_phy_base + HDMI_PHY_ANA_CFG3);
+		} else {
+			REG_W(0x06, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
+			REG_W(0x03, hdmi_phy_base + HDMI_PHY_ANA_CFG3);
+		}
+
+		REG_W(0x04, hdmi_phy_pll_base + HDMI_UNI_PLL_VREG_CFG);
+		REG_W(0xD0, hdmi_phy_base + HDMI_PHY_DCC_CFG0);
+		REG_W(0x1A, hdmi_phy_base + HDMI_PHY_DCC_CFG1);
+		REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG0);
+		REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG1);
+
+		if (rate < 825000000)
+			REG_W(0x01, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2);
+		else
+			REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2);
+
+		REG_W(0x05, hdmi_phy_base + HDMI_PHY_TXCAL_CFG3);
+		REG_W(0x62, hdmi_phy_base + HDMI_PHY_BIST_PATN0);
+		REG_W(0x03, hdmi_phy_base + HDMI_PHY_BIST_PATN1);
+		REG_W(0x69, hdmi_phy_base + HDMI_PHY_BIST_PATN2);
+		REG_W(0x02, hdmi_phy_base + HDMI_PHY_BIST_PATN3);
+
+		udelay(200);
+
+		REG_W(0x00, hdmi_phy_base + HDMI_PHY_BIST_CFG1);
+		REG_W(0x00, hdmi_phy_base + HDMI_PHY_BIST_CFG0);
 	}
 
 	/* Make sure writes complete before disabling iface clock */
 	mb();
 
-	clk_disable(mdss_ahb_clk);
+	mdss_ahb_clk_enable(0);
 
 	if (set_power_dwn)
-		hdmi_pll_enable();
+		hdmi_vco_enable(c);
+
+	vco->rate = rate;
+	vco->rate_set = true;
 
 	return 0;
 } /* hdmi_pll_set_rate */
 
-/* Auto PLL calibaration */
-int mdss_ahb_clk_enable(int enable)
-{
-	int rc = 0;
-
-	/* todo: Ideally, we should enable/disable GDSC whenever we are
-	 * attempting to enable/disable MDSS AHB clock.
-	 * For now, just return error if  GDSC is not enabled.
-	 */
-	if (!mdss_gdsc_enabled())
-		return -EPERM;
-
-	if (enable)
-		rc = clk_prepare_enable(mdss_ahb_clk);
-	else
-		clk_disable_unprepare(mdss_ahb_clk);
-
-	return rc;
-}
-
 int set_byte_mux_sel(struct mux_clk *clk, int sel)
 {
 	pr_debug("%s: byte mux set to %s mode\n", __func__,
@@ -2126,6 +2298,291 @@
 	},
 };
 
+/* HDMI PLL DIV CLK */
+
+static unsigned long hdmi_vco_get_rate(struct clk *c)
+{
+	unsigned long freq = 0;
+
+	if (mdss_ahb_clk_enable(1)) {
+		pr_err("%s: Failed to enable mdss ahb clock\n", __func__);
+		return freq;
+	}
+
+	freq = DSS_REG_R(hdmi_phy_pll_base, HDMI_UNI_PLL_CAL_CFG11) << 8 |
+		DSS_REG_R(hdmi_phy_pll_base, HDMI_UNI_PLL_CAL_CFG10);
+
+	switch (freq) {
+	case 742:
+		freq = 742500000;
+		break;
+	case 810:
+		if (DSS_REG_R(hdmi_phy_pll_base, HDMI_UNI_PLL_SDM_CFG3) == 0x18)
+			freq = 810000000;
+		else
+			freq = 810900000;
+		break;
+	case 1342:
+		freq = 1342500000;
+		break;
+	default:
+		freq *= 1000000;
+	}
+
+	mdss_ahb_clk_enable(0);
+
+	return freq;
+}
+
+static long hdmi_vco_round_rate(struct clk *c, unsigned long rate)
+{
+	unsigned long rrate = rate;
+	struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
+
+	if (rate < vco->min_rate)
+		rrate = vco->min_rate;
+	if (rate > vco->max_rate)
+		rrate = vco->max_rate;
+
+	pr_debug("%s: rrate=%ld\n", __func__, rrate);
+
+	return rrate;
+}
+
+static int hdmi_vco_prepare(struct clk *c)
+{
+	struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
+	int ret = 0;
+
+	pr_debug("%s: rate=%ld\n", __func__, vco->rate);
+
+	if (!vco->rate_set && vco->rate)
+		ret = hdmi_vco_set_rate(c, vco->rate);
+
+	if (!ret)
+		ret = clk_prepare(mdss_ahb_clk);
+
+	return ret;
+}
+
+static void hdmi_vco_unprepare(struct clk *c)
+{
+	struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
+
+	vco->rate_set = false;
+
+	clk_unprepare(mdss_ahb_clk);
+}
+
+static int hdmi_pll_lock_status(void)
+{
+	u32 status;
+	int pll_locked = 0;
+	int rc;
+
+	rc = mdss_ahb_clk_enable(1);
+	if (rc) {
+		pr_err("%s: failed to enable mdss ahb clock. rc=%d\n",
+			__func__, rc);
+		return 0;
+	}
+	/* poll for PLL ready status */
+	if (readl_poll_timeout_noirq((hdmi_phy_base + HDMI_PHY_STATUS),
+			status, ((status & BIT(0)) == 1),
+			PLL_POLL_MAX_READS, PLL_POLL_TIMEOUT_US)) {
+		pr_debug("%s: HDMI PLL status=%x failed to Lock\n",
+				__func__, status);
+		pll_locked = 0;
+	} else {
+		pll_locked = 1;
+	}
+	mdss_ahb_clk_enable(0);
+
+	return pll_locked;
+}
+
+static enum handoff hdmi_vco_handoff(struct clk *c)
+{
+	enum handoff ret = HANDOFF_DISABLED_CLK;
+
+	if (hdmi_pll_lock_status()) {
+		c->rate = hdmi_vco_get_rate(c);
+		ret = HANDOFF_ENABLED_CLK;
+	}
+
+	pr_debug("%s: done, ret=%d\n", __func__, ret);
+	return ret;
+}
+
+static struct clk_ops hdmi_vco_clk_ops = {
+	.enable = hdmi_vco_enable,
+	.set_rate = hdmi_vco_set_rate,
+	.get_rate = hdmi_vco_get_rate,
+	.round_rate = hdmi_vco_round_rate,
+	.prepare = hdmi_vco_prepare,
+	.unprepare = hdmi_vco_unprepare,
+	.disable = hdmi_vco_disable,
+	.handoff = hdmi_vco_handoff,
+};
+
+static struct hdmi_pll_vco_clk hdmi_vco_clk = {
+	.min_rate = 600000000,
+	.max_rate = 1800000000,
+	.c = {
+		.dbg_name = "hdmi_vco_clk",
+		.ops = &hdmi_vco_clk_ops,
+		CLK_INIT(hdmi_vco_clk.c),
+	},
+};
+
+struct div_clk hdmipll_div1_clk = {
+	.data = {
+		.div = 1,
+		.min_div = 1,
+		.max_div = 1,
+	},
+	.c = {
+		.parent = &hdmi_vco_clk.c,
+		.dbg_name = "hdmipll_div1_clk",
+		.ops = &clk_ops_div,
+		.flags = CLKFLAG_NO_RATE_CACHE,
+		CLK_INIT(hdmipll_div1_clk.c),
+	},
+};
+
+struct div_clk hdmipll_div2_clk = {
+	.data = {
+		.div = 2,
+		.min_div = 2,
+		.max_div = 2,
+	},
+	.c = {
+		.parent = &hdmi_vco_clk.c,
+		.dbg_name = "hdmipll_div2_clk",
+		.ops = &clk_ops_div,
+		.flags = CLKFLAG_NO_RATE_CACHE,
+		CLK_INIT(hdmipll_div2_clk.c),
+	},
+};
+
+struct div_clk hdmipll_div4_clk = {
+	.data = {
+		.div = 4,
+		.min_div = 4,
+		.max_div = 4,
+	},
+	.c = {
+		.parent = &hdmi_vco_clk.c,
+		.dbg_name = "hdmipll_div4_clk",
+		.ops = &clk_ops_div,
+		.flags = CLKFLAG_NO_RATE_CACHE,
+		CLK_INIT(hdmipll_div4_clk.c),
+	},
+};
+
+struct div_clk hdmipll_div6_clk = {
+	.data = {
+		.div = 6,
+		.min_div = 6,
+		.max_div = 6,
+	},
+	.c = {
+		.parent = &hdmi_vco_clk.c,
+		.dbg_name = "hdmipll_div6_clk",
+		.ops = &clk_ops_div,
+		.flags = CLKFLAG_NO_RATE_CACHE,
+		CLK_INIT(hdmipll_div6_clk.c),
+	},
+};
+
+static int hdmipll_set_mux_sel(struct mux_clk *clk, int mux_sel)
+{
+	int rc;
+
+	if (!mdss_gdsc_enabled()) {
+		pr_err("%s: mdss GDSC is not enabled\n", __func__);
+		return -EPERM;
+	}
+
+	rc = clk_enable(mdss_ahb_clk);
+	if (rc) {
+		pr_err("%s: Failed to enable mdss ahb clock\n", __func__);
+		return rc;
+	}
+
+	pr_debug("%s: mux_sel=%d\n", __func__, mux_sel);
+	DSS_REG_W(hdmi_phy_pll_base, HDMI_UNI_PLL_POSTDIV1_CFG, mux_sel);
+
+	clk_disable(mdss_ahb_clk);
+
+	return 0;
+}
+
+static int hdmipll_get_mux_sel(struct mux_clk *clk)
+{
+	int mux_sel = 0;
+
+	if (mdss_ahb_clk_enable(1)) {
+		pr_err("%s: Failed to enable mdss ahb clock\n", __func__);
+		return mux_sel;
+	}
+
+	mux_sel = DSS_REG_R(hdmi_phy_pll_base, HDMI_UNI_PLL_POSTDIV1_CFG);
+	mux_sel &= 0x03;
+	pr_debug("%s: mux_sel=%d\n", __func__, mux_sel);
+
+	mdss_ahb_clk_enable(0);
+
+	return mux_sel;
+}
+
+static struct clk_mux_ops hdmipll_mux_ops = {
+	.set_mux_sel = hdmipll_set_mux_sel,
+	.get_mux_sel = hdmipll_get_mux_sel,
+};
+
+static struct clk_ops hdmi_mux_ops;
+
+static int hdmi_mux_prepare(struct clk *c)
+{
+	int ret = 0;
+
+	if (c && c->ops && c->ops->set_rate)
+		ret = c->ops->set_rate(c, c->rate);
+
+	return ret;
+}
+
+static struct mux_clk hdmipll_mux_clk = {
+	MUX_SRC_LIST(
+		{ &hdmipll_div1_clk.c, 0 },
+		{ &hdmipll_div2_clk.c, 1 },
+		{ &hdmipll_div4_clk.c, 2 },
+		{ &hdmipll_div6_clk.c, 3 },
+	),
+	.ops = &hdmipll_mux_ops,
+	.c = {
+		.parent = &hdmipll_div1_clk.c,
+		.dbg_name = "hdmipll_mux_clk",
+		.ops = &hdmi_mux_ops,
+		CLK_INIT(hdmipll_mux_clk.c),
+	},
+};
+
+struct div_clk hdmipll_clk_src = {
+	.data = {
+		.div = 5,
+		.min_div = 5,
+		.max_div = 5,
+	},
+	.c = {
+		.parent = &hdmipll_mux_clk.c,
+		.dbg_name = "hdmipll_clk_src",
+		.ops = &clk_ops_div,
+		CLK_INIT(hdmipll_clk_src.c),
+	},
+};
+
 void __init mdss_clk_ctrl_pre_init(struct clk *ahb_clk)
 {
 	BUG_ON(ahb_clk == NULL);
@@ -2170,4 +2627,7 @@
 
 	edp_pixel_clk_ops = clk_ops_slave_div;
 	edp_pixel_clk_ops.prepare = div_prepare;
+
+	hdmi_mux_ops = clk_ops_gen_mux;
+	hdmi_mux_ops.prepare = hdmi_mux_prepare;
 }
diff --git a/arch/arm/mach-msm/clock-mdss-8974.h b/arch/arm/mach-msm/clock-mdss-8974.h
index da24b0d..f9286f1 100644
--- a/arch/arm/mach-msm/clock-mdss-8974.h
+++ b/arch/arm/mach-msm/clock-mdss-8974.h
@@ -22,9 +22,15 @@
 
 void mdss_clk_ctrl_pre_init(struct clk *ahb_clk);
 void mdss_clk_ctrl_post_init(void);
-int hdmi_pll_enable(void);
-void hdmi_pll_disable(void);
-int hdmi_pll_set_rate(unsigned long rate);
+
+struct hdmi_pll_vco_clk {
+	unsigned long rate;	/* current vco rate */
+	unsigned long min_rate;	/* min vco rate */
+	unsigned long max_rate;	/* max vco rate */
+	bool rate_set;
+
+	struct clk c;
+};
 
 struct edp_pll_vco_clk {
 	unsigned long ref_clk_rate;
@@ -67,5 +73,6 @@
 
 extern struct div_clk edp_mainlink_clk_src;
 extern struct div_clk edp_pixel_clk_src;
+extern struct div_clk hdmipll_clk_src;
 
 #endif
diff --git a/arch/arm/mach-msm/cpr-regulator.c b/arch/arm/mach-msm/cpr-regulator.c
index 1cf2e41..28afc91 100644
--- a/arch/arm/mach-msm/cpr-regulator.c
+++ b/arch/arm/mach-msm/cpr-regulator.c
@@ -25,7 +25,6 @@
 #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>
@@ -33,6 +32,10 @@
 
 /* Register Offsets for RB-CPR and Bit Definitions */
 
+/* RBCPR Version Register */
+#define REG_RBCPR_VERSION		0
+#define RBCPR_VER_2			0x02
+
 /* RBCPR Gate Count and Target Registers */
 #define REG_RBCPR_GCNT_TARGET(n)	(0x60 + 4 * n)
 
@@ -131,14 +134,14 @@
 
 #define BYTES_PER_FUSE_ROW		8
 
+#define FLAGS_IGNORE_1ST_IRQ_STATUS	BIT(0)
 #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;
+struct quot_adjust_info {
+	int speed_bin;
+	int virtual_corner;
 	int quot_adjust;
-	int corner;
 };
 
 enum voltage_change_dir {
@@ -160,7 +163,7 @@
 
 	/* Process voltage parameters */
 	u32		pvs_init_v[CPR_PVS_EFUSE_BINS_MAX];
-	u32		pvs_corner_v[NUM_APC_PVS][CPR_CORNER_MAX];
+	u32		pvs_corner_v[NUM_APC_PVS][CPR_FUSE_CORNER_MAX];
 	/* Process voltage variables */
 	u32		pvs_bin;
 	u32		process;
@@ -178,9 +181,8 @@
 	u64		cpr_fuse_bits;
 	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		cpr_fuse_target_quot[CPR_FUSE_CORNER_MAX];
+	int		cpr_fuse_ro_sel[CPR_FUSE_CORNER_MAX];
 	int		gcnt;
 
 	unsigned int	cpr_irq;
@@ -188,13 +190,13 @@
 	phys_addr_t	rbcpr_clk_addr;
 	struct mutex	cpr_mutex;
 
-	int		ceiling_volt[CPR_CORNER_MAX];
-	int		floor_volt[CPR_CORNER_MAX];
-	int		last_volt[CPR_CORNER_MAX];
+	int		ceiling_volt[CPR_FUSE_CORNER_MAX];
+	int		floor_volt[CPR_FUSE_CORNER_MAX];
+	int		*last_volt;
 	int		step_volt;
 
-	int		save_ctl[CPR_CORNER_MAX];
-	int		save_irq[CPR_CORNER_MAX];
+	int		*save_ctl;
+	int		*save_irq;
 
 	u32		save_regs[CPR_NUM_SAVE_REGS];
 	u32		save_reg_val[CPR_NUM_SAVE_REGS];
@@ -214,10 +216,10 @@
 	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;
+	int		*corner_map;
+	u32		num_corners;
+	int		*quot_adjust;
+	u32		quotient_adjustment;
 };
 
 #define CPR_DEBUG_MASK_IRQ	BIT(0)
@@ -280,28 +282,6 @@
 	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)
 {
@@ -362,9 +342,11 @@
 static void cpr_ctl_enable(struct cpr_regulator *cpr_vreg, int corner)
 {
 	u32 val;
+	int fuse_corner = cpr_vreg->corner_map[corner];
 
 	if (cpr_is_allowed(cpr_vreg) &&
-	    (cpr_vreg->ceiling_volt[corner] > cpr_vreg->floor_volt[corner]))
+	    (cpr_vreg->ceiling_volt[fuse_corner] >
+		cpr_vreg->floor_volt[fuse_corner]))
 		val = RBCPR_CTL_LOOP_EN;
 	else
 		val = 0;
@@ -376,13 +358,6 @@
 	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;
@@ -415,16 +390,12 @@
 static void cpr_corner_restore(struct cpr_regulator *cpr_vreg, int corner)
 {
 	u32 gcnt, ctl, irq, ro_sel;
-	int adjust;
+	int fuse_corner = cpr_vreg->corner_map[corner];
 
-	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[fuse_corner];
+	gcnt = cpr_vreg->gcnt | (cpr_vreg->cpr_fuse_target_quot[fuse_corner] -
+					cpr_vreg->quot_adjust[corner]);
 
-	ro_sel = cpr_vreg->cpr_fuse_ro_sel[corner];
-	gcnt = cpr_vreg->gcnt | cpr_vreg->cpr_fuse_target_quot[corner];
 	cpr_write(cpr_vreg, REG_RBCPR_GCNT_TARGET(ro_sel), gcnt);
 	ctl = cpr_vreg->save_ctl[corner];
 	cpr_write(cpr_vreg, REG_RBCPR_CTL, ctl);
@@ -462,8 +433,9 @@
 		goto _exit;
 	}
 
-	cpr_debug("%d -> %d [corner=%d]\n",
-		  old_cpr_enable, cpr_enable, the_cpr->corner);
+	cpr_debug("%d -> %d [corner=%d, fuse_corner=%d]\n",
+		  old_cpr_enable, cpr_enable, the_cpr->corner,
+		  the_cpr->corner_map[the_cpr->corner]);
 
 	if (the_cpr->cpr_fuse_disable) {
 		/* Already disabled */
@@ -509,17 +481,18 @@
 static int cpr_mx_get(struct cpr_regulator *cpr_vreg, int corner, int apc_volt)
 {
 	int vdd_mx;
+	int fuse_corner = cpr_vreg->corner_map[corner];
 
 	switch (cpr_vreg->vdd_mx_vmin_method) {
 	case VDD_MX_VMIN_APC:
 		vdd_mx = apc_volt;
 		break;
 	case VDD_MX_VMIN_APC_CORNER_CEILING:
-		vdd_mx = cpr_vreg->ceiling_volt[corner];
+		vdd_mx = cpr_vreg->ceiling_volt[fuse_corner];
 		break;
 	case VDD_MX_VMIN_APC_SLOW_CORNER_CEILING:
 		vdd_mx = cpr_vreg->pvs_corner_v[APC_PVS_SLOW]
-						[CPR_CORNER_TURBO];
+						[CPR_FUSE_CORNER_TURBO];
 		break;
 	case VDD_MX_VMIN_MX_VMAX:
 		vdd_mx = cpr_vreg->vdd_mx_vmax;
@@ -536,15 +509,19 @@
 		      int vdd_mx_vmin)
 {
 	int rc;
+	int fuse_corner = cpr_vreg->corner_map[corner];
 
 	rc = regulator_set_voltage(cpr_vreg->vdd_mx, vdd_mx_vmin,
 				   cpr_vreg->vdd_mx_vmax);
-	cpr_debug("[corner:%d] %d uV\n", corner, vdd_mx_vmin);
-	if (!rc)
+	cpr_debug("[corner:%d, fuse_corner:%d] %d uV\n", corner,
+			fuse_corner, vdd_mx_vmin);
+
+	if (!rc) {
 		cpr_vreg->vdd_mx_vmin = vdd_mx_vmin;
-	else
-		pr_err("set: vdd_mx [%d] = %d uV: rc=%d\n",
-		       corner, vdd_mx_vmin, rc);
+	} else {
+		pr_err("set: vdd_mx [corner:%d, fuse_corner:%d] = %d uV failed: rc=%d\n",
+			corner, fuse_corner, vdd_mx_vmin, rc);
+	}
 	return rc;
 }
 
@@ -582,9 +559,11 @@
 		      enum voltage_change_dir dir)
 {
 	u32 reg_val, error_steps, reg_mask;
-	int last_volt, new_volt, corner;
+	int last_volt, new_volt, corner, fuse_corner;
+	u32 gcnt, quot;
 
 	corner = cpr_vreg->corner;
+	fuse_corner = cpr_vreg->corner_map[corner];
 
 	reg_val = cpr_read(cpr_vreg, REG_RBCPR_RESULT_0);
 
@@ -592,18 +571,27 @@
 				& RBCPR_RESULT0_ERROR_STEPS_MASK;
 	last_volt = cpr_vreg->last_volt[corner];
 
-	cpr_debug_irq("last_volt[corner:%d] = %d uV\n", corner, last_volt);
+	cpr_debug_irq("last_volt[corner:%d, fuse_corner:%d] = %d uV\n", corner,
+			fuse_corner, last_volt);
+
+	gcnt = cpr_read(cpr_vreg, REG_RBCPR_GCNT_TARGET
+			(cpr_vreg->cpr_fuse_ro_sel[fuse_corner]));
+	quot = gcnt & ((1 << RBCPR_GCNT_TARGET_GCNT_SHIFT) - 1);
 
 	if (dir == UP) {
 		cpr_debug_irq("Up: cpr status = 0x%08x (error_steps=%d)\n",
 			      reg_val, error_steps);
 
-		if (last_volt >= cpr_vreg->ceiling_volt[corner]) {
-			cpr_debug_irq("[corn:%d] @ ceiling: %d >= %d: NACK\n",
-				      corner, last_volt,
-				      cpr_vreg->ceiling_volt[corner]);
+		if (last_volt >= cpr_vreg->ceiling_volt[fuse_corner]) {
+			cpr_debug_irq(
+			"[corn:%d, fuse_corn:%d] @ ceiling: %d >= %d: NACK\n",
+				corner, fuse_corner, last_volt,
+				cpr_vreg->ceiling_volt[fuse_corner]);
 			cpr_irq_clr_nack(cpr_vreg);
 
+			cpr_debug_irq("gcnt = 0x%08x (quot = %d)\n", gcnt,
+					quot);
+
 			/* Maximize the UP threshold */
 			reg_mask = RBCPR_CTL_UP_THRESHOLD_MASK <<
 					RBCPR_CTL_UP_THRESHOLD_SHIFT;
@@ -621,11 +609,12 @@
 
 		/* Calculate new voltage */
 		new_volt = last_volt + (error_steps * cpr_vreg->step_volt);
-		if (new_volt > cpr_vreg->ceiling_volt[corner]) {
+		if (new_volt > cpr_vreg->ceiling_volt[fuse_corner]) {
 			cpr_debug_irq("new_volt(%d) >= ceiling(%d): Clamp\n",
 				      new_volt,
-				      cpr_vreg->ceiling_volt[corner]);
-			new_volt = cpr_vreg->ceiling_volt[corner];
+				      cpr_vreg->ceiling_volt[fuse_corner]);
+
+			new_volt = cpr_vreg->ceiling_volt[fuse_corner];
 		}
 
 		if (cpr_scale_voltage(cpr_vreg, corner, new_volt, dir)) {
@@ -634,13 +623,9 @@
 		}
 		cpr_vreg->last_volt[corner] = new_volt;
 
-		/* Restore default threshold for DOWN */
-		reg_mask = RBCPR_CTL_DN_THRESHOLD_MASK <<
-				RBCPR_CTL_DN_THRESHOLD_SHIFT;
-		reg_val = cpr_vreg->down_threshold <<
-				RBCPR_CTL_DN_THRESHOLD_SHIFT;
-		/* and disable auto nack down */
-		reg_mask |= RBCPR_CTL_SW_AUTO_CONT_NACK_DN_EN;
+		/* Disable auto nack down */
+		reg_mask = RBCPR_CTL_SW_AUTO_CONT_NACK_DN_EN;
+		reg_val = 0;
 
 		cpr_ctl_modify(cpr_vreg, reg_mask, reg_val);
 
@@ -650,26 +635,26 @@
 		/* Ack */
 		cpr_irq_clr_ack(cpr_vreg);
 
-		cpr_debug_irq("UP: -> new_volt[corner:%d] = %d uV\n",
-			      corner, new_volt);
+		cpr_debug_irq(
+			"UP: -> new_volt[corner:%d, fuse_corner:%d] = %d uV\n",
+			corner, fuse_corner, new_volt);
 	} else if (dir == DOWN) {
 		cpr_debug_irq("Down: cpr status = 0x%08x (error_steps=%d)\n",
 			      reg_val, error_steps);
 
-		if (last_volt <= cpr_vreg->floor_volt[corner]) {
-			cpr_debug_irq("[corn:%d] @ floor: %d <= %d: NACK\n",
-				      corner, last_volt,
-				      cpr_vreg->floor_volt[corner]);
+		if (last_volt <= cpr_vreg->floor_volt[fuse_corner]) {
+			cpr_debug_irq(
+			"[corn:%d, fuse_corner:%d] @ floor: %d <= %d: NACK\n",
+				corner, fuse_corner, last_volt,
+				cpr_vreg->floor_volt[fuse_corner]);
 			cpr_irq_clr_nack(cpr_vreg);
 
-			/* Maximize the DOWN threshold */
-			reg_mask = RBCPR_CTL_DN_THRESHOLD_MASK <<
-					RBCPR_CTL_DN_THRESHOLD_SHIFT;
-			reg_val = reg_mask;
+			cpr_debug_irq("gcnt = 0x%08x (quot = %d)\n", gcnt,
+					quot);
 
 			/* Enable auto nack down */
-			reg_mask |= RBCPR_CTL_SW_AUTO_CONT_NACK_DN_EN;
-			reg_val |= RBCPR_CTL_SW_AUTO_CONT_NACK_DN_EN;
+			reg_mask = RBCPR_CTL_SW_AUTO_CONT_NACK_DN_EN;
+			reg_val = RBCPR_CTL_SW_AUTO_CONT_NACK_DN_EN;
 
 			cpr_ctl_modify(cpr_vreg, reg_mask, reg_val);
 
@@ -688,11 +673,11 @@
 
 		/* Calculte new voltage */
 		new_volt = last_volt - (error_steps * cpr_vreg->step_volt);
-		if (new_volt < cpr_vreg->floor_volt[corner]) {
+		if (new_volt < cpr_vreg->floor_volt[fuse_corner]) {
 			cpr_debug_irq("new_volt(%d) < floor(%d): Clamp\n",
 				      new_volt,
-				      cpr_vreg->floor_volt[corner]);
-			new_volt = cpr_vreg->floor_volt[corner];
+				      cpr_vreg->floor_volt[fuse_corner]);
+			new_volt = cpr_vreg->floor_volt[fuse_corner];
 		}
 
 		if (cpr_scale_voltage(cpr_vreg, corner, new_volt, dir)) {
@@ -711,8 +696,9 @@
 		/* Ack */
 		cpr_irq_clr_ack(cpr_vreg);
 
-		cpr_debug_irq("DOWN: -> new_volt[corner:%d] = %d uV\n",
-			      corner, new_volt);
+		cpr_debug_irq(
+		"DOWN: -> new_volt[corner:%d, fuse_corner:%d] = %d uV\n",
+			corner, fuse_corner, new_volt);
 	}
 }
 
@@ -724,6 +710,9 @@
 	mutex_lock(&cpr_vreg->cpr_mutex);
 
 	reg_val = cpr_read(cpr_vreg, REG_RBIF_IRQ_STATUS);
+	if (cpr_vreg->flags & FLAGS_IGNORE_1ST_IRQ_STATUS)
+		reg_val = cpr_read(cpr_vreg, REG_RBIF_IRQ_STATUS);
+
 	cpr_debug_irq("IRQ_STATUS = 0x%02X\n", reg_val);
 
 	if (!cpr_is_allowed(cpr_vreg)) {
@@ -831,6 +820,7 @@
 	int rc;
 	int new_volt;
 	enum voltage_change_dir change_dir = NO_CHANGE;
+	int fuse_corner = cpr_vreg->corner_map[corner];
 
 	mutex_lock(&cpr_vreg->cpr_mutex);
 
@@ -838,10 +828,12 @@
 		cpr_ctl_disable(cpr_vreg);
 		new_volt = cpr_vreg->last_volt[corner];
 	} else {
-		new_volt = cpr_vreg->pvs_corner_v[cpr_vreg->process][corner];
+		new_volt = cpr_vreg->pvs_corner_v
+				[cpr_vreg->process][fuse_corner];
 	}
 
-	cpr_debug("[corner:%d] = %d uV\n", corner, new_volt);
+	cpr_debug("[corner:%d, fuse_corner:%d] = %d uV\n", corner, fuse_corner,
+		new_volt);
 
 	if (corner > cpr_vreg->corner)
 		change_dir = UP;
@@ -934,11 +926,13 @@
 #define cpr_regulator_resume NULL
 #endif
 
-static int __devinit cpr_config(struct cpr_regulator *cpr_vreg)
+static int __devinit cpr_config(struct cpr_regulator *cpr_vreg,
+				struct device *dev)
 {
 	int i;
 	u32 val, gcnt, reg;
 	void __iomem *rbcpr_clk;
+	int size;
 
 	/* Use 19.2 MHz clock for CPR. */
 	rbcpr_clk = ioremap(cpr_vreg->rbcpr_clk_addr, 4);
@@ -1009,17 +1003,26 @@
 	cpr_vreg->save_regs[5] = REG_RBIF_IRQ_EN(cpr_vreg->irq_line);
 	cpr_vreg->save_regs[6] = REG_RBCPR_CTL;
 	cpr_vreg->save_regs[7] = REG_RBCPR_GCNT_TARGET
-		(cpr_vreg->cpr_fuse_ro_sel[CPR_CORNER_SVS]);
+		(cpr_vreg->cpr_fuse_ro_sel[CPR_FUSE_CORNER_SVS]);
 	cpr_vreg->save_regs[8] = REG_RBCPR_GCNT_TARGET
-		(cpr_vreg->cpr_fuse_ro_sel[CPR_CORNER_NORMAL]);
+		(cpr_vreg->cpr_fuse_ro_sel[CPR_FUSE_CORNER_NORMAL]);
 	cpr_vreg->save_regs[9] = REG_RBCPR_GCNT_TARGET
-		(cpr_vreg->cpr_fuse_ro_sel[CPR_CORNER_TURBO]);
+		(cpr_vreg->cpr_fuse_ro_sel[CPR_FUSE_CORNER_TURBO]);
 
 	cpr_irq_set(cpr_vreg, CPR_INT_DEFAULT);
 
-	cpr_corner_save(cpr_vreg, CPR_CORNER_SVS);
-	cpr_corner_save(cpr_vreg, CPR_CORNER_NORMAL);
-	cpr_corner_save(cpr_vreg, CPR_CORNER_TURBO);
+	val = cpr_read(cpr_vreg, REG_RBCPR_VERSION);
+	if (val <= RBCPR_VER_2)
+		cpr_vreg->flags |= FLAGS_IGNORE_1ST_IRQ_STATUS;
+
+	size = cpr_vreg->num_corners + 1;
+	cpr_vreg->save_ctl = devm_kzalloc(dev, sizeof(int) * size, GFP_KERNEL);
+	cpr_vreg->save_irq = devm_kzalloc(dev, sizeof(int) * size, GFP_KERNEL);
+	if (!cpr_vreg->save_ctl || !cpr_vreg->save_irq)
+		return -ENOMEM;
+
+	for (i = 1; i < size; i++)
+		cpr_corner_save(cpr_vreg, i);
 
 	return 0;
 }
@@ -1053,13 +1056,13 @@
 	int rc, i;
 
 	rc = of_property_read_u32(of_node,
-		"qti,cpr-uplift-voltage", &uplift_voltage);
+		"qcom,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);
+		"qcom,cpr-uplift-max-volt", &uplift_max_volt);
 	if (rc < 0) {
 		pr_err("cpr-uplift-max-volt is missing, rc = %d", rc);
 		return rc;
@@ -1081,11 +1084,11 @@
 	u64 efuse_bits;
 	int rc, process;
 	u32 pvs_fuse[4], pvs_fuse_redun_sel[5];
-	u32 init_v;
+	u32 init_v, quot_adjust;
 	bool redundant;
 	size_t pvs_bins;
 
-	rc = of_property_read_u32_array(of_node, "qti,pvs-fuse-redun-sel",
+	rc = of_property_read_u32_array(of_node, "qcom,pvs-fuse-redun-sel",
 					pvs_fuse_redun_sel, 5);
 	if (rc < 0) {
 		pr_err("pvs-fuse-redun-sel missing: rc=%d\n", rc);
@@ -1095,14 +1098,14 @@
 	redundant = cpr_fuse_is_setting_expected(cpr_vreg, pvs_fuse_redun_sel);
 
 	if (redundant) {
-		rc = of_property_read_u32_array(of_node, "qti,pvs-fuse-redun",
+		rc = of_property_read_u32_array(of_node, "qcom,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, "qti,pvs-fuse",
+		rc = of_property_read_u32_array(of_node, "qcom,pvs-fuse",
 						pvs_fuse, 4);
 		if (rc < 0) {
 			pr_err("pvs-fuse missing: rc=%d\n", rc);
@@ -1118,7 +1121,7 @@
 
 	pvs_bins = 1 << pvs_fuse[2];
 
-	rc = of_property_read_u32_array(of_node, "qti,pvs-init-voltage",
+	rc = of_property_read_u32_array(of_node, "qcom,pvs-init-voltage",
 					cpr_vreg->pvs_init_v, pvs_bins);
 	if (rc < 0) {
 		pr_err("pvs-init-voltage missing: rc=%d\n", rc);
@@ -1135,16 +1138,18 @@
 
 	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])
+		if (init_v <= cpr_vreg->pvs_corner_v
+			[process][CPR_FUSE_CORNER_TURBO])
 			break;
 	}
 
 	if (process == APC_PVS_NO) {
 		process = APC_PVS_SLOW;
-		cpr_vreg->pvs_corner_v[process][CPR_CORNER_TURBO] = init_v;
+		cpr_vreg->pvs_corner_v[process][CPR_FUSE_CORNER_TURBO] = init_v;
 		cpr_vreg->ceiling_max = init_v;
 	} else if (process == APC_PVS_FAST &&
-		init_v < cpr_vreg->pvs_corner_v[APC_PVS_FAST][CPR_CORNER_SVS]) {
+		init_v < cpr_vreg->pvs_corner_v
+			[APC_PVS_FAST][CPR_FUSE_CORNER_SVS]) {
 		process = APC_PVS_SLOW;
 	}
 
@@ -1152,10 +1157,15 @@
 		pvs_fuse[0], efuse_bits, pvs_fuse[2],
 		cpr_vreg->pvs_bin, process);
 	pr_info("pvs initial turbo voltage_= from %u to %u\n",
-		init_v, cpr_vreg->pvs_corner_v[process][CPR_CORNER_TURBO]);
+		init_v, cpr_vreg->pvs_corner_v[process][CPR_FUSE_CORNER_TURBO]);
 
 	cpr_vreg->process = process;
 
+	rc = of_property_read_u32(of_node,
+			"qcom,cpr-quotient-adjustment", &quot_adjust);
+	if (!rc)
+		cpr_vreg->quotient_adjustment = quot_adjust;
+
 	return 0;
 }
 
@@ -1163,7 +1173,7 @@
 do {									\
 	if (!rc) {							\
 		rc = of_property_read_u32(of_node,			\
-				"qti," cpr_property,			\
+				"qcom," cpr_property,			\
 				cpr_config);				\
 		if (rc) {						\
 			pr_err("Missing " #cpr_property			\
@@ -1200,14 +1210,14 @@
 
 	/* Parse dependency parameters */
 	if (cpr_vreg->vdd_mx) {
-		rc = of_property_read_u32(of_node, "qti,vdd-mx-vmax",
+		rc = of_property_read_u32(of_node, "qcom,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, "qti,vdd-mx-vmin-method",
+		rc = of_property_read_u32(of_node, "qcom,vdd-mx-vmin-method",
 				 &cpr_vreg->vdd_mx_vmin_method);
 		if (rc < 0) {
 			pr_err("vdd-mx-vmin-method missing: rc=%d\n", rc);
@@ -1240,86 +1250,114 @@
 	int rc, i;
 
 	rc = of_property_read_u32_array(of_node,
-			"qti,cpr-uplift-quotient", delta_quot, 3);
+			"qcom,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++)
+	for (i = CPR_FUSE_CORNER_SVS; i < CPR_FUSE_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,
+static int cpr_get_of_corner_mappings(struct cpr_regulator *cpr_vreg,
 					struct device *dev)
 {
 	int rc = 0;
-	int i, j, size, stripe_size, length;
+	int i, size, stripe_size;
 	struct property *prop;
 	u32 *tmp;
+	bool corners_mapped;
 
-	prop = of_find_property(dev->of_node, "qti,cpr-quot-adjust-table",
-				NULL);
+	prop = of_find_property(dev->of_node, "qcom,cpr-corner-map", NULL);
+
 	if (prop) {
 		size = prop->length / sizeof(u32);
+		corners_mapped = true;
+	} else {
+		size = CPR_FUSE_CORNER_MAX - 1;
+		corners_mapped = false;
+	}
+
+	cpr_vreg->corner_map = devm_kzalloc(dev, sizeof(int) * (size + 1),
+					GFP_KERNEL);
+	if (!cpr_vreg->corner_map) {
+		pr_err("Can't allocate cpr_vreg->corner_map memory\n");
+		return -ENOMEM;
+	}
+	cpr_vreg->num_corners = size;
+
+	if (!corners_mapped) {
+		for (i = CPR_FUSE_CORNER_SVS; i < CPR_FUSE_CORNER_MAX; i++)
+			cpr_vreg->corner_map[i] = i;
+	} else {
+		rc = of_property_read_u32_array(dev->of_node,
+			"qcom,cpr-corner-map", &cpr_vreg->corner_map[1], size);
+
+		if (rc) {
+			pr_err("qcom,cpr-corner-map missing, rc = %d", rc);
+			return rc;
+		}
+	}
+
+	cpr_vreg->quot_adjust = devm_kzalloc(dev,
+			sizeof(int) * (cpr_vreg->num_corners + 1),
+			GFP_KERNEL);
+	if (!cpr_vreg->quot_adjust) {
+		pr_err("Can't allocate cpr_vreg->quot_adjust memory\n");
+		return -ENOMEM;
+	}
+
+	prop = of_find_property(dev->of_node, "qcom,cpr-quot-adjust-table",
+				NULL);
+
+	if (prop) {
+		if (!corners_mapped) {
+			pr_err("qcom,cpr-corner-map missing\n");
+			return -EINVAL;
+		}
+
+		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);
+				"qcom,cpr-quot-adjust-table", tmp, size);
 		if (rc) {
-			pr_err("qti,cpr-quot-adjust-table missing, rc = %d",
+			pr_err("qcom,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");
+		stripe_size = sizeof(struct quot_adjust_info) / sizeof(int);
+
+		if ((size % stripe_size) != 0) {
+			pr_err("qcom,cpr-quot-adjust-table data is not correct");
 			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;
+		for (i = 0; i < size; i += stripe_size) {
+			if (tmp[i] == cpr_vreg->speed_bin) {
+				if (tmp[i + 1] >= 1 &&
+					tmp[i + 1] <=
+					cpr_vreg->num_corners) {
+					cpr_vreg->quot_adjust[tmp[i + 1]] =
+					tmp[i + 2];
+				} else {
+					pr_err("qcom,cpr-quot-adjust-table data is not correct");
+					kfree(tmp);
+					return -EINVAL;
 				}
-
 			}
-
 		}
 
 		kfree(tmp);
 	}
 
-	return rc;
+	return 0;
 }
 
 static int __devinit cpr_init_cpr_efuse(struct platform_device *pdev,
@@ -1332,12 +1370,12 @@
 	char *targ_quot_str, *ro_sel_str;
 	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];
+	int bp_target_quot[CPR_FUSE_CORNER_MAX];
+	int bp_ro_sel[CPR_FUSE_CORNER_MAX];
 	u32 ro_sel, val;
 	u64 fuse_bits, fuse_bits_2;
 
-	rc = of_property_read_u32_array(of_node, "qti,cpr-fuse-redun-sel",
+	rc = of_property_read_u32_array(of_node, "qcom,cpr-fuse-redun-sel",
 					cpr_fuse_redun_sel, 5);
 	if (rc < 0) {
 		pr_err("cpr-fuse-redun-sel missing: rc=%d\n", rc);
@@ -1348,24 +1386,24 @@
 
 	if (redundant) {
 		rc = of_property_read_u32_array(of_node,
-				"qti,cpr-fuse-redun-row",
+				"qcom,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";
+		targ_quot_str = "qcom,cpr-fuse-redun-target-quot";
+		ro_sel_str = "qcom,cpr-fuse-redun-ro-sel";
 	} else {
 		rc = of_property_read_u32_array(of_node,
-				"qti,cpr-fuse-row",
+				"qcom,cpr-fuse-row",
 				cpr_fuse_row, 2);
-		targ_quot_str = "qti,cpr-fuse-target-quot";
-		ro_sel_str = "qti,cpr-fuse-ro-sel";
+		targ_quot_str = "qcom,cpr-fuse-target-quot";
+		ro_sel_str = "qcom,cpr-fuse-ro-sel";
 	}
 	if (rc)
 		return rc;
 
 	rc = of_property_read_u32_array(of_node,
 		targ_quot_str,
-		&bp_target_quot[CPR_CORNER_SVS],
-		CPR_CORNER_MAX - CPR_CORNER_SVS);
+		&bp_target_quot[CPR_FUSE_CORNER_SVS],
+		CPR_FUSE_CORNER_MAX - CPR_FUSE_CORNER_SVS);
 	if (rc < 0) {
 		pr_err("missing %s: rc=%d\n", targ_quot_str, rc);
 		return rc;
@@ -1373,8 +1411,8 @@
 
 	rc = of_property_read_u32_array(of_node,
 		ro_sel_str,
-		&bp_ro_sel[CPR_CORNER_SVS],
-		CPR_CORNER_MAX - CPR_CORNER_SVS);
+		&bp_ro_sel[CPR_FUSE_CORNER_SVS],
+		CPR_FUSE_CORNER_MAX - CPR_FUSE_CORNER_SVS);
 	if (rc < 0) {
 		pr_err("missing %s: rc=%d\n", ro_sel_str, rc);
 		return rc;
@@ -1387,7 +1425,7 @@
 
 	if (redundant) {
 		if (of_property_read_bool(of_node,
-				"qti,cpr-fuse-redun-bp-cpr-disable")) {
+				"qcom,cpr-fuse-redun-bp-cpr-disable")) {
 			CPR_PROP_READ_U32(of_node,
 					  "cpr-fuse-redun-bp-cpr-disable",
 					  &bp_cpr_disable, rc);
@@ -1406,7 +1444,7 @@
 			CPR_PROP_READ_U32(of_node, "cpr-fuse-bp-scheme",
 					  &bp_scheme, rc);
 			rc = of_property_read_u32_array(of_node,
-					"qti,cpr-fuse-row",
+					"qcom,cpr-fuse-row",
 					temp_row, 2);
 			if (rc)
 				return rc;
@@ -1432,11 +1470,12 @@
 	pr_info("disable = %d, local = %d\n",
 		cpr_vreg->cpr_fuse_disable, cpr_vreg->cpr_fuse_local);
 
-	for (i = CPR_CORNER_SVS; i < CPR_CORNER_MAX; i++) {
+	for (i = CPR_FUSE_CORNER_SVS; i < CPR_FUSE_CORNER_MAX; i++) {
 		ro_sel = (fuse_bits >> bp_ro_sel[i])
 				& CPR_FUSE_RO_SEL_BITS_MASK;
 		val = (fuse_bits >> bp_target_quot[i])
 				& CPR_FUSE_TARGET_QUOT_BITS_MASK;
+		val += cpr_vreg->quotient_adjustment;
 		cpr_vreg->cpr_fuse_target_quot[i] = val;
 		cpr_vreg->cpr_fuse_ro_sel[i] = ro_sel;
 		pr_info("Corner[%d]: ro_sel = %d, target quot = %d\n",
@@ -1445,18 +1484,13 @@
 
 	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++) {
+		for (i = CPR_FUSE_CORNER_SVS; i < CPR_FUSE_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);
+	rc = cpr_get_of_corner_mappings(cpr_vreg, &pdev->dev);
 	if (rc)
 		return rc;
 
@@ -1469,10 +1503,12 @@
 		int *quot = cpr_vreg->cpr_fuse_target_quot;
 		bool valid_fuse = true;
 
-		if ((quot[CPR_CORNER_TURBO] > quot[CPR_CORNER_NORMAL]) &&
-		    (quot[CPR_CORNER_NORMAL] > quot[CPR_CORNER_SVS])) {
-			if ((quot[CPR_CORNER_TURBO] -
-			     quot[CPR_CORNER_NORMAL])
+		if ((quot[CPR_FUSE_CORNER_TURBO] >
+			quot[CPR_FUSE_CORNER_NORMAL]) &&
+		    (quot[CPR_FUSE_CORNER_NORMAL] >
+			quot[CPR_FUSE_CORNER_SVS])) {
+			if ((quot[CPR_FUSE_CORNER_TURBO] -
+			     quot[CPR_FUSE_CORNER_NORMAL])
 					<= CPR_FUSE_MIN_QUOT_DIFF)
 				valid_fuse = false;
 		} else {
@@ -1488,18 +1524,27 @@
 	return 0;
 }
 
-static int __devinit cpr_init_cpr_voltages(struct cpr_regulator *cpr_vreg)
+static int __devinit cpr_init_cpr_voltages(struct cpr_regulator *cpr_vreg,
+			struct device *dev)
 {
 	int i;
+	int size = cpr_vreg->num_corners + 1;
+
+	cpr_vreg->last_volt = devm_kzalloc(dev, sizeof(int) * size, GFP_KERNEL);
+	if (!cpr_vreg->last_volt)
+		return -EINVAL;
 
 	/* Construct CPR voltage limits */
-	for (i = CPR_CORNER_SVS; i < CPR_CORNER_MAX; i++) {
+	for (i = CPR_FUSE_CORNER_SVS; i < CPR_FUSE_CORNER_MAX; i++) {
 		cpr_vreg->floor_volt[i] =
 			cpr_vreg->pvs_corner_v[APC_PVS_FAST][i];
 		cpr_vreg->ceiling_volt[i] =
 			cpr_vreg->pvs_corner_v[APC_PVS_SLOW][i];
-		cpr_vreg->last_volt[i] =
-			cpr_vreg->pvs_corner_v[cpr_vreg->process][i];
+	}
+
+	for (i = 1; i < size; i++) {
+		cpr_vreg->last_volt[i] = cpr_vreg->pvs_corner_v
+				[cpr_vreg->process][cpr_vreg->corner_map[i]];
 	}
 
 	return 0;
@@ -1565,7 +1610,7 @@
 		return rc;
 
 	/* Init module parameter with the DT value */
-	cpr_vreg->enable = of_property_read_bool(of_node, "qti,cpr-enable");
+	cpr_vreg->enable = of_property_read_bool(of_node, "qcom,cpr-enable");
 	cpr_enable = (int) cpr_vreg->enable;
 	pr_info("CPR is %s by default.\n",
 		cpr_vreg->enable ? "enabled" : "disabled");
@@ -1599,7 +1644,9 @@
 					    resource_size(res));
 
 	/* Init all voltage set points of APC regulator for CPR */
-	cpr_init_cpr_voltages(cpr_vreg);
+	rc = cpr_init_cpr_voltages(cpr_vreg, &pdev->dev);
+	if (rc)
+		return rc;
 
 	/* Init CPR configuration parameters */
 	rc = cpr_init_cpr_parameters(pdev, cpr_vreg);
@@ -1614,7 +1661,7 @@
 	}
 
 	/* Configure CPR HW but keep it disabled */
-	rc = cpr_config(cpr_vreg);
+	rc = cpr_config(cpr_vreg, &pdev->dev);
 	if (rc)
 		return rc;
 
@@ -1668,12 +1715,12 @@
 	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
+	 * qcom,cpr-cond-min-voltage if the fuse defined in
+	 * qcom,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);
+			"qcom,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;
@@ -1689,7 +1736,7 @@
 	u32 speed_bits;
 
 	rc = of_property_read_u32_array(of_node,
-			"qti,speed-bin-fuse-sel", fuse_sel, 4);
+			"qcom,speed-bin-fuse-sel", fuse_sel, 4);
 
 	if (!rc) {
 		fuse_bits = cpr_read_efuse_row(cpr_vreg,
@@ -1712,13 +1759,13 @@
 	u32 uplift_speed_bin;
 
 	rc = of_property_read_u32_array(of_node,
-			"qti,cpr-fuse-uplift-sel", fuse_sel, 5);
+			"qcom,cpr-fuse-uplift-sel", fuse_sel, 5);
 	if (!rc) {
 		rc = of_property_read_u32(of_node,
-				"qti,cpr-uplift-speed-bin",
+				"qcom,cpr-uplift-speed-bin",
 				&uplift_speed_bin);
 		if (rc < 0) {
-			pr_err("qti,cpr-uplift-speed-bin missing\n");
+			pr_err("qcom,cpr-uplift-speed-bin missing\n");
 			return rc;
 		}
 		if (cpr_fuse_is_setting_expected(cpr_vreg, fuse_sel)
@@ -1738,27 +1785,27 @@
 	u32 min_uv = 0;
 
 	rc = of_property_read_u32_array(of_node,
-		"qti,pvs-corner-ceiling-slow",
-		&cpr_vreg->pvs_corner_v[APC_PVS_SLOW][CPR_CORNER_SVS],
-		CPR_CORNER_MAX - CPR_CORNER_SVS);
+		"qcom,pvs-corner-ceiling-slow",
+		&cpr_vreg->pvs_corner_v[APC_PVS_SLOW][CPR_FUSE_CORNER_SVS],
+		CPR_FUSE_CORNER_MAX - CPR_FUSE_CORNER_SVS);
 	if (rc < 0) {
 		pr_err("pvs-corner-ceiling-slow missing: rc=%d\n", rc);
 		return rc;
 	}
 
 	rc = of_property_read_u32_array(of_node,
-		"qti,pvs-corner-ceiling-nom",
-		&cpr_vreg->pvs_corner_v[APC_PVS_NOM][CPR_CORNER_SVS],
-		CPR_CORNER_MAX - CPR_CORNER_SVS);
+		"qcom,pvs-corner-ceiling-nom",
+		&cpr_vreg->pvs_corner_v[APC_PVS_NOM][CPR_FUSE_CORNER_SVS],
+		CPR_FUSE_CORNER_MAX - CPR_FUSE_CORNER_SVS);
 	if (rc < 0) {
 		pr_err("pvs-corner-ceiling-norm missing: rc=%d\n", rc);
 		return rc;
 	}
 
 	rc = of_property_read_u32_array(of_node,
-		"qti,pvs-corner-ceiling-fast",
-		&cpr_vreg->pvs_corner_v[APC_PVS_FAST][CPR_CORNER_SVS],
-		CPR_CORNER_MAX - CPR_CORNER_SVS);
+		"qcom,pvs-corner-ceiling-fast",
+		&cpr_vreg->pvs_corner_v[APC_PVS_FAST][CPR_FUSE_CORNER_SVS],
+		CPR_FUSE_CORNER_MAX - CPR_FUSE_CORNER_SVS);
 	if (rc < 0) {
 		pr_err("pvs-corner-ceiling-fast missing: rc=%d\n", rc);
 		return rc;
@@ -1772,73 +1819,29 @@
 		return rc;
 	}
 	if (cpr_vreg->flags & FLAGS_SET_MIN_VOLTAGE) {
-		of_property_read_u32(of_node, "qti,cpr-cond-min-voltage",
+		of_property_read_u32(of_node, "qcom,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++)
+			for (j = CPR_FUSE_CORNER_SVS; j < CPR_FUSE_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];
+		cpr_vreg->pvs_corner_v[APC_PVS_SLOW][CPR_FUSE_CORNER_TURBO];
 
 	for (i = APC_PVS_SLOW; i < NUM_APC_PVS; i++) {
 		pr_info("[%d] [%d %d %d] uV\n", i,
-			cpr_vreg->pvs_corner_v[i][CPR_CORNER_SVS],
-			cpr_vreg->pvs_corner_v[i][CPR_CORNER_NORMAL],
-			cpr_vreg->pvs_corner_v[i][CPR_CORNER_TURBO]);
+			cpr_vreg->pvs_corner_v[i][CPR_FUSE_CORNER_SVS],
+			cpr_vreg->pvs_corner_v[i][CPR_FUSE_CORNER_NORMAL],
+			cpr_vreg->pvs_corner_v[i][CPR_FUSE_CORNER_TURBO]);
 	}
 
 	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;
@@ -1922,10 +1925,6 @@
 
 	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;
 
@@ -1946,9 +1945,6 @@
 			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/cpufreq.c b/arch/arm/mach-msm/cpufreq.c
index 60856c2..0978a2d 100644
--- a/arch/arm/mach-msm/cpufreq.c
+++ b/arch/arm/mach-msm/cpufreq.c
@@ -32,7 +32,7 @@
 #include <linux/platform_device.h>
 #include <trace/events/power.h>
 #include <mach/socinfo.h>
-#include <mach/msm_bus.h>
+#include <mach/cpufreq.h>
 
 #include "acpuclock.h"
 
@@ -47,16 +47,12 @@
 static struct clk *cpu_clk[NR_CPUS];
 static struct clk *l2_clk;
 static unsigned int freq_index[NR_CPUS];
+static unsigned int max_freq_index;
 static struct cpufreq_frequency_table *freq_table;
 static unsigned int *l2_khz;
 static bool is_clk;
 static bool is_sync;
-static struct msm_bus_vectors *bus_vec_lst;
-static struct msm_bus_scale_pdata bus_bw = {
-	.name = "msm-cpufreq",
-	.active_only = 1,
-};
-static u32 bus_client;
+static unsigned long *mem_bw;
 
 struct cpufreq_work_struct {
 	struct work_struct work;
@@ -77,6 +73,11 @@
 
 static DEFINE_PER_CPU(struct cpufreq_suspend_t, cpufreq_suspend);
 
+unsigned long msm_cpufreq_get_bw(void)
+{
+	return mem_bw[max_freq_index];
+}
+
 static void update_l2_bw(int *also_cpu)
 {
 	int rc = 0, cpu;
@@ -98,10 +99,10 @@
 		goto out;
 	}
 
-	if (bus_client)
-		rc = msm_bus_scale_client_update_request(bus_client, index);
+	max_freq_index = index;
+	rc = devfreq_msm_cpufreq_update_bw();
 	if (rc)
-		pr_err("Bandwidth req failed (%d)\n", rc);
+		pr_err("Unable to update BW (%d)\n", rc);
 
 out:
 	mutex_unlock(&l2bw_lock);
@@ -397,33 +398,14 @@
 };
 
 #define PROP_TBL "qcom,cpufreq-table"
-#define PROP_PORTS "qcom,cpu-mem-ports"
 static int cpufreq_parse_dt(struct device *dev)
 {
-	int ret, len, nf, num_cols = 1, num_paths = 0, i, j, k;
-	u32 *data, *ports = NULL;
-	struct msm_bus_vectors *v = NULL;
+	int ret, len, nf, num_cols = 2, i, j;
+	u32 *data;
 
 	if (l2_clk)
 		num_cols++;
 
-	/* Parse optional bus ports parameter */
-	if (of_find_property(dev->of_node, PROP_PORTS, &len)) {
-		len /= sizeof(*ports);
-		if (len % 2)
-			return -EINVAL;
-
-		ports = devm_kzalloc(dev, len * sizeof(*ports), GFP_KERNEL);
-		if (!ports)
-			return -ENOMEM;
-		ret = of_property_read_u32_array(dev->of_node, PROP_PORTS,
-						 ports, len);
-		if (ret)
-			return ret;
-		num_paths = len / 2;
-		num_cols++;
-	}
-
 	/* Parse CPU freq -> L2/Mem BW map table. */
 	if (!of_find_property(dev->of_node, PROP_TBL, &len))
 		return -EINVAL;
@@ -444,7 +426,9 @@
 	/* Allocate all data structures. */
 	freq_table = devm_kzalloc(dev, (nf + 1) * sizeof(*freq_table),
 				  GFP_KERNEL);
-	if (!freq_table)
+	mem_bw = devm_kzalloc(dev, nf * sizeof(*mem_bw), GFP_KERNEL);
+
+	if (!freq_table || !mem_bw)
 		return -ENOMEM;
 
 	if (l2_clk) {
@@ -453,15 +437,6 @@
 			return -ENOMEM;
 	}
 
-	if (num_paths) {
-		int sz_u = nf * sizeof(*bus_bw.usecase);
-		int sz_v = nf * num_paths * sizeof(*bus_vec_lst);
-		bus_bw.usecase = devm_kzalloc(dev, sz_u, GFP_KERNEL);
-		v = bus_vec_lst = devm_kzalloc(dev, sz_v, GFP_KERNEL);
-		if (!bus_bw.usecase || !bus_vec_lst)
-			return -ENOMEM;
-	}
-
 	j = 0;
 	for (i = 0; i < nf; i++) {
 		unsigned long f;
@@ -504,25 +479,12 @@
 			}
 		}
 
-		if (num_paths) {
-			unsigned int bw_mbps = data[j++];
-			bus_bw.usecase[i].num_paths = num_paths;
-			bus_bw.usecase[i].vectors = v;
-			for (k = 0; k < num_paths; k++) {
-				v->src = ports[k * 2];
-				v->dst = ports[k * 2 + 1];
-				v->ib = bw_mbps * 1000000ULL;
-				v++;
-			}
-		}
+		mem_bw[i] = data[j++];
 	}
 
-	bus_bw.num_usecases = i;
 	freq_table[i].index = i;
 	freq_table[i].frequency = CPUFREQ_TABLE_END;
 
-	if (ports)
-		devm_kfree(dev, ports);
 	devm_kfree(dev, data);
 
 	return 0;
@@ -532,15 +494,12 @@
 static int msm_cpufreq_show(struct seq_file *m, void *unused)
 {
 	unsigned int i, cpu_freq;
-	uint64_t ib;
 
 	if (!freq_table)
 		return 0;
 
 	seq_printf(m, "%10s%10s", "CPU (KHz)", "L2 (KHz)");
-	if (bus_bw.usecase)
-		seq_printf(m, "%12s", "Mem (MBps)");
-	seq_printf(m, "\n");
+	seq_printf(m, "%12s\n", "Mem (MBps)");
 
 	for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
 		cpu_freq = freq_table[i].frequency;
@@ -548,11 +507,7 @@
 			continue;
 		seq_printf(m, "%10d", cpu_freq);
 		seq_printf(m, "%10d", l2_khz ? l2_khz[i] : cpu_freq);
-		if (bus_bw.usecase) {
-			ib = bus_bw.usecase[i].vectors[0].ib;
-			do_div(ib, 1000000);
-			seq_printf(m, "%12llu", ib);
-		}
+		seq_printf(m, "%12lu", mem_bw[i]);
 		seq_printf(m, "\n");
 	}
 	return 0;
@@ -602,10 +557,10 @@
 		cpufreq_frequency_table_get_attr(freq_table, cpu);
 	}
 
-	if (bus_bw.usecase) {
-		bus_client = msm_bus_scale_register_client(&bus_bw);
-		if (!bus_client)
-			dev_warn(dev, "Unable to register bus client\n");
+	ret = register_devfreq_msm_cpufreq();
+	if (ret) {
+		pr_err("devfreq governor registration failed\n");
+		return ret;
 	}
 
 	is_clk = true;
diff --git a/arch/arm/mach-msm/devfreq_cpubw.c b/arch/arm/mach-msm/devfreq_cpubw.c
new file mode 100644
index 0000000..4b2d7ea
--- /dev/null
+++ b/arch/arm/mach-msm/devfreq_cpubw.c
@@ -0,0 +1,219 @@
+/*
+ * 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.
+ */
+
+#define pr_fmt(fmt) "cpubw: " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/ktime.h>
+#include <linux/time.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/interrupt.h>
+#include <linux/devfreq.h>
+#include <linux/of.h>
+#include <trace/events/power.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+
+/* Has to be ULL to prevent overflow where this macro is used. */
+#define MBYTE (1ULL << 20)
+#define MAX_PATHS	2
+
+static struct msm_bus_vectors vectors[MAX_PATHS * 2];
+static struct msm_bus_paths bw_levels[] = {
+	{ .vectors = &vectors[0] },
+	{ .vectors = &vectors[MAX_PATHS] },
+};
+static struct msm_bus_scale_pdata bw_data = {
+	.usecase = bw_levels,
+	.num_usecases = ARRAY_SIZE(bw_levels),
+	.name = "devfreq_cpubw",
+	.active_only = 1,
+};
+static int num_paths;
+static u32 bus_client;
+
+static int set_bw(int new_ib, int new_ab)
+{
+	static int cur_idx, cur_ab, cur_ib;
+	int i, ret;
+
+	if (cur_ib == new_ib && cur_ab == new_ab)
+		return 0;
+
+	i = (cur_idx + 1) % ARRAY_SIZE(bw_levels);
+
+	bw_levels[i].vectors[0].ib = new_ib * MBYTE;
+	bw_levels[i].vectors[0].ab = new_ab / num_paths * MBYTE;
+	bw_levels[i].vectors[1].ib = new_ib * MBYTE;
+	bw_levels[i].vectors[1].ab = new_ab / num_paths * MBYTE;
+
+	pr_debug("BW MBps: AB: %d IB: %d\n", new_ab, new_ib);
+
+	ret = msm_bus_scale_client_update_request(bus_client, i);
+	if (ret) {
+		pr_err("bandwidth request failed (%d)\n", ret);
+	} else {
+		cur_idx = i;
+		cur_ib = new_ib;
+		cur_ab = new_ab;
+	}
+
+	return ret;
+}
+
+static void find_freq(struct devfreq_dev_profile *p, unsigned long *freq,
+			u32 flags)
+{
+	int i;
+	unsigned long atmost, atleast, f;
+
+	atmost = p->freq_table[0];
+	atleast = p->freq_table[p->max_state-1];
+	for (i = 0; i < p->max_state; i++) {
+		f = p->freq_table[i];
+		if (f <= *freq)
+			atmost = max(f, atmost);
+		if (f >= *freq)
+			atleast = min(f, atleast);
+	}
+
+	if (flags & DEVFREQ_FLAG_LEAST_UPPER_BOUND)
+		*freq = atmost;
+	else
+		*freq = atleast;
+}
+
+struct devfreq_dev_profile cpubw_profile;
+static long gov_ab;
+
+int cpubw_target(struct device *dev, unsigned long *freq, u32 flags)
+{
+	find_freq(&cpubw_profile, freq, flags);
+	return set_bw(*freq, gov_ab);
+}
+
+static struct devfreq_governor_data gov_data[] = {
+	{ .name = "performance" },
+	{ .name = "powersave" },
+	{ .name = "userspace" },
+	{ .name = "msm_cpufreq" },
+};
+struct devfreq_dev_profile cpubw_profile = {
+	.polling_ms = 50,
+	.target = cpubw_target,
+	.governor_data = gov_data,
+	.num_governor_data = ARRAY_SIZE(gov_data),
+};
+
+#define PROP_PORTS "qcom,cpu-mem-ports"
+#define PROP_TBL "qcom,bw-tbl"
+
+static int __init cpubw_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct devfreq_dev_profile *p = &cpubw_profile;
+	struct devfreq *df;
+	u32 *data, ports[MAX_PATHS * 2];
+	int ret, len, i;
+
+	if (of_find_property(dev->of_node, PROP_PORTS, &len)) {
+		len /= sizeof(ports[0]);
+		if (len % 2 || len > ARRAY_SIZE(ports)) {
+			dev_err(dev, "Unexpected number of ports\n");
+			return -EINVAL;
+		}
+
+		ret = of_property_read_u32_array(dev->of_node, PROP_PORTS,
+						 ports, len);
+		if (ret)
+			return ret;
+
+		num_paths = len / 2;
+	} else {
+		return -EINVAL;
+	}
+
+	for (i = 0; i < num_paths; i++) {
+		bw_levels[0].vectors[i].src = ports[2 * i];
+		bw_levels[0].vectors[i].dst = ports[2 * i + 1];
+		bw_levels[1].vectors[i].src = ports[2 * i];
+		bw_levels[1].vectors[i].dst = ports[2 * i + 1];
+	}
+	bw_levels[0].num_paths = num_paths;
+	bw_levels[1].num_paths = num_paths;
+
+	if (of_find_property(dev->of_node, PROP_TBL, &len)) {
+		len /= sizeof(*data);
+		data = devm_kzalloc(dev, len * sizeof(*data), GFP_KERNEL);
+		if (!data)
+			return -ENOMEM;
+
+		p->freq_table = devm_kzalloc(dev,
+					     len * sizeof(*p->freq_table),
+					     GFP_KERNEL);
+		if (!p->freq_table)
+			return -ENOMEM;
+
+		ret = of_property_read_u32_array(dev->of_node, PROP_TBL,
+						 data, len);
+		if (ret)
+			return ret;
+
+		for (i = 0; i < len; i++)
+			p->freq_table[i] = data[i];
+		p->max_state = len;
+	}
+
+	bus_client = msm_bus_scale_register_client(&bw_data);
+	if (!bus_client) {
+		dev_err(dev, "Unable to register bus client\n");
+		return -ENODEV;
+	}
+
+	df = devfreq_add_device(dev, &cpubw_profile, "msm_cpufreq", NULL);
+	if (IS_ERR(df)) {
+		msm_bus_scale_unregister_client(bus_client);
+		return PTR_ERR(df);
+	}
+
+	return 0;
+}
+
+static struct of_device_id match_table[] = {
+	{ .compatible = "qcom,cpubw" },
+	{}
+};
+
+static struct platform_driver cpubw_driver = {
+	.driver = {
+		.name = "cpubw",
+		.of_match_table = match_table,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init cpubw_init(void)
+{
+	platform_driver_probe(&cpubw_driver, cpubw_probe);
+	return 0;
+}
+device_initcall(cpubw_init);
+
+MODULE_DESCRIPTION("CPU DDR bandwidth voting driver MSM CPUs");
+MODULE_LICENSE("GPL v2");
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/cpufreq.h b/arch/arm/mach-msm/include/mach/cpufreq.h
new file mode 100644
index 0000000..46872d7
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/cpufreq.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __MACH_CPUFREQ_H
+#define __MACH_CPUFREQ_H
+
+#if defined(CONFIG_DEVFREQ_GOV_MSM_CPUFREQ)
+extern int devfreq_msm_cpufreq_update_bw(void);
+extern int register_devfreq_msm_cpufreq(void);
+#else
+static int devfreq_msm_cpufreq_update_bw(void)
+{
+	return 0;
+}
+static int register_devfreq_msm_cpufreq(void)
+{
+	return 0;
+}
+#endif
+
+#if defined(CONFIG_CPU_FREQ_MSM)
+extern unsigned long msm_cpufreq_get_bw(void);
+#else
+extern unsigned long msm_cpufreq_get_bw(void)
+{
+	return ULONG_MAX;
+}
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/rtac.h b/arch/arm/mach-msm/include/mach/qdsp6v2/rtac.h
index 0a1cdd4..42cf6f9 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/rtac.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/rtac.h
@@ -45,7 +45,7 @@
 };
 
 void rtac_add_adm_device(u32 port_id, u32 copp_id, u32 path_id, u32 popp_id);
-void rtac_remove_adm_device(u32 port_id);
+void rtac_remove_adm_device(u32 port_id, u32 copp_id);
 void rtac_remove_popp_from_adm_devices(u32 popp_id);
 void rtac_add_voice(u32 cvs_handle, u32 cvp_handle, u32 rx_afe_port,
 	u32 tx_afe_port, u32 session_id);
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/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index ce66531..6bb4011 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -434,7 +434,7 @@
 				       unsigned int len)
 {
 	struct sk_buff *temp;
-	int offset = 0, buf_len = 0, copy_len;
+	unsigned int offset = 0, buf_len = 0, copy_len;
 	void *buf;
 
 	if (!skb_head) {
diff --git a/arch/arm/mach-msm/lpm_levels.c b/arch/arm/mach-msm/lpm_levels.c
index b707df1..06160f7 100644
--- a/arch/arm/mach-msm/lpm_levels.c
+++ b/arch/arm/mach-msm/lpm_levels.c
@@ -212,7 +212,6 @@
 
 	switch (sleep_mode) {
 	case MSM_SPM_L2_MODE_POWER_COLLAPSE:
-		pr_info("Configuring for L2 power collapse\n");
 		msm_pm_set_l2_flush_flag(MSM_SCM_L2_OFF);
 		break;
 	case MSM_SPM_L2_MODE_GDHS:
@@ -291,7 +290,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/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/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..a18d0f3 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 */
@@ -51,12 +51,19 @@
 #define Y_IND 1
 #define Z_IND 2
 
+/* Shared memory limits */
+/* max_buf_size = (port_size(65535*2) * port_num(8) * group_size(3) */
+#define USF_MAX_BUF_SIZE 3145680
+#define USF_MAX_BUF_NUM  32
+
 /* Place for opreation result, received from QDSP6 */
 #define APR_RESULT_IND 1
 
 /* 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 +124,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 +155,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 +191,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 +296,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 +314,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 +387,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,
@@ -436,6 +487,15 @@
 	    (config == NULL))
 		return -EINVAL;
 
+	if ((config->buf_size == 0) ||
+	    (config->buf_size > USF_MAX_BUF_SIZE) ||
+	    (config->buf_num == 0) ||
+	    (config->buf_num > USF_MAX_BUF_NUM)) {
+		pr_err("%s: wrong params: buf_size=%d; buf_num=%d\n",
+		       __func__, config->buf_size, config->buf_num);
+		return -EINVAL;
+	}
+
 	data_map_size = sizeof(usf_xx->encdec_cfg.cfg_common.data_map);
 	min_map_size = min(data_map_size, config->port_cnt);
 
@@ -748,6 +808,7 @@
 {
 	uint32_t timeout = 0;
 	struct us_detect_info_type detect_info;
+	struct usm_session_cmd_detect_info *p_allocated_memory = NULL;
 	struct usm_session_cmd_detect_info usm_detect_info;
 	struct usm_session_cmd_detect_info *p_usm_detect_info =
 						&usm_detect_info;
@@ -774,12 +835,13 @@
 		uint8_t *p_data = NULL;
 
 		detect_info_size += detect_info.params_data_size;
-		p_usm_detect_info = kzalloc(detect_info_size, GFP_KERNEL);
-		if (p_usm_detect_info == NULL) {
+		 p_allocated_memory = kzalloc(detect_info_size, GFP_KERNEL);
+		if (p_allocated_memory == NULL) {
 			pr_err("%s: detect_info[%d] allocation failed\n",
 			       __func__, detect_info_size);
 			return -ENOMEM;
 		}
+		p_usm_detect_info = p_allocated_memory;
 		p_data = (uint8_t *)p_usm_detect_info +
 			sizeof(struct usm_session_cmd_detect_info);
 
@@ -789,7 +851,7 @@
 		if (rc) {
 			pr_err("%s: copy params from user; rc=%d\n",
 				__func__, rc);
-			kfree(p_usm_detect_info);
+			kfree(p_allocated_memory);
 			return -EFAULT;
 		}
 		p_usm_detect_info->algorithm_cfg_size =
@@ -806,9 +868,7 @@
 				    p_usm_detect_info,
 				    detect_info_size);
 	if (rc || (detect_info.detect_timeout == USF_NO_WAIT_TIMEOUT)) {
-		if (detect_info_size >
-		    sizeof(struct usm_session_cmd_detect_info))
-			kfree(p_usm_detect_info);
+		kfree(p_allocated_memory);
 		return rc;
 	}
 
@@ -828,25 +888,24 @@
 					 USF_US_DETECT_UNDEF),
 					timeout);
 	/* In the case of timeout, "no US" is assumed */
-	if (rc < 0) {
+	if (rc < 0)
 		pr_err("%s: Getting US detection failed rc[%d]\n",
 		       __func__, rc);
-		return rc;
+	else {
+		usf->usf_rx.us_detect_type = usf->usf_tx.us_detect_type;
+		detect_info.is_us =
+			(usf_xx->us_detect_type == USF_US_DETECT_YES);
+		rc = copy_to_user((void __user *)arg,
+				  &detect_info,
+				  sizeof(detect_info));
+		if (rc) {
+			pr_err("%s: copy detect_info to user; rc=%d\n",
+				__func__, rc);
+			rc = -EFAULT;
+		}
 	}
 
-	usf->usf_rx.us_detect_type = usf->usf_tx.us_detect_type;
-	detect_info.is_us = (usf_xx->us_detect_type == USF_US_DETECT_YES);
-	rc = copy_to_user((void __user *)arg,
-			  &detect_info,
-			  sizeof(detect_info));
-	if (rc) {
-		pr_err("%s: copy detect_info to user; rc=%d\n",
-			__func__, rc);
-		rc = -EFAULT;
-	}
-
-	if (detect_info_size > sizeof(struct usm_session_cmd_detect_info))
-		kfree(p_usm_detect_info);
+	kfree(p_allocated_memory);
 
 	return rc;
 } /* usf_set_us_detection */
@@ -947,16 +1006,14 @@
 	if (rc)
 		return rc;
 
-	if (usf_xx->buffer_size && usf_xx->buffer_count) {
-		rc = q6usm_us_client_buf_alloc(
-					IN,
-					usf_xx->usc,
-					usf_xx->buffer_size,
-					usf_xx->buffer_count);
-		if (rc) {
-			(void)q6usm_cmd(usf_xx->usc, CMD_CLOSE);
-			return rc;
-		}
+	rc = q6usm_us_client_buf_alloc(
+				IN,
+				usf_xx->usc,
+				usf_xx->buffer_size,
+				usf_xx->buffer_count);
+	if (rc) {
+		(void)q6usm_cmd(usf_xx->usc, CMD_CLOSE);
+		return rc;
 	}
 
 	rc = q6usm_dec_cfg_blk(usf_xx->usc,
@@ -1175,10 +1232,15 @@
 		return -EFAULT;
 	}
 
-	/* version_info.buf is pointer to place for the version string */
+	if (version_info.buf_size < sizeof(DRV_VERSION)) {
+		pr_err("%s: buf_size (%d) < version string size (%d)\n",
+			__func__, version_info.buf_size, sizeof(DRV_VERSION));
+		return -EINVAL;
+	}
+
 	rc = copy_to_user(version_info.pbuf,
 			  DRV_VERSION,
-			  version_info.buf_size);
+			  sizeof(DRV_VERSION));
 	if (rc) {
 		pr_err("%s: copy to version_info.pbuf; rc=%d\n",
 			__func__, rc);
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/restart.c b/arch/arm/mach-msm/restart.c
index 37fd650..a96b02f 100644
--- a/arch/arm/mach-msm/restart.c
+++ b/arch/arm/mach-msm/restart.c
@@ -115,6 +115,10 @@
 		__raw_writel(EMERGENCY_DLOAD_MAGIC3,
 				emergency_dload_mode_addr +
 				(2 * sizeof(unsigned int)));
+
+		/* Need disable the pmic wdt, then the emergency dload mode
+		 * will not auto reset. */
+		qpnp_pon_wd_config(0);
 		mb();
 	}
 }
@@ -276,6 +280,8 @@
 			__raw_writel(0x77665500, restart_reason);
 		} else if (!strncmp(cmd, "recovery", 8)) {
 			__raw_writel(0x77665502, restart_reason);
+		} else if (!strcmp(cmd, "rtc")) {
+			__raw_writel(0x77665503, restart_reason);
 		} else if (!strncmp(cmd, "oem-", 4)) {
 			unsigned long code;
 			code = simple_strtoul(cmd + 4, NULL, 16) & 0xff;
diff --git a/arch/arm/mach-msm/rpcrouter_sdio_xprt.c b/arch/arm/mach-msm/rpcrouter_sdio_xprt.c
deleted file mode 100644
index e9818e5..0000000
--- a/arch/arm/mach-msm/rpcrouter_sdio_xprt.c
+++ /dev/null
@@ -1,655 +0,0 @@
-/* Copyright (c) 2010-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.
- */
-
-/*
- * RPCROUTER SDIO XPRT module.
- */
-
-#include <linux/platform_device.h>
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/err.h>
-#include <linux/sched.h>
-#include <linux/poll.h>
-#include <linux/wakelock.h>
-#include <asm/uaccess.h>
-#include <linux/slab.h>
-
-#include <mach/sdio_al.h>
-#include "smd_rpcrouter.h"
-
-enum {
-	MSM_SDIO_XPRT_DEBUG = 1U << 0,
-	MSM_SDIO_XPRT_INFO = 1U << 1,
-};
-
-static int msm_sdio_xprt_debug_mask;
-module_param_named(debug_mask, msm_sdio_xprt_debug_mask,
-		   int, S_IRUGO | S_IWUSR | S_IWGRP);
-
-#if defined(CONFIG_MSM_RPC_SDIO_DEBUG)
-#define SDIO_XPRT_DBG(x...) do {                \
-	if (msm_sdio_xprt_debug_mask & MSM_SDIO_XPRT_DEBUG)     \
-		printk(KERN_DEBUG x);           \
-	} while (0)
-
-#define SDIO_XPRT_INFO(x...) do {               \
-	if (msm_sdio_xprt_debug_mask & MSM_SDIO_XPRT_INFO)      \
-		printk(KERN_INFO x);            \
-	} while (0)
-#else
-#define SDIO_XPRT_DBG(x...) do { } while (0)
-#define SDIO_XPRT_INFO(x...) do { } while (0)
-#endif
-
-#define MAX_SDIO_WRITE_RETRY 5
-#define SDIO_BUF_SIZE (RPCROUTER_MSGSIZE_MAX + sizeof(struct rr_header) - 8)
-#define NUM_SDIO_BUFS 20
-#define MAX_TX_BUFS 10
-#define MAX_RX_BUFS 10
-
-struct sdio_xprt {
-	struct sdio_channel *handle;
-
-	struct list_head write_list;
-	spinlock_t write_list_lock;
-
-	struct list_head read_list;
-	spinlock_t read_list_lock;
-
-	struct list_head free_list;
-	spinlock_t free_list_lock;
-
-	struct wake_lock read_wakelock;
-};
-
-struct rpcrouter_sdio_xprt {
-	struct rpcrouter_xprt xprt;
-	struct sdio_xprt *channel;
-};
-
-static struct rpcrouter_sdio_xprt sdio_remote_xprt;
-
-static void sdio_xprt_read_data(struct work_struct *work);
-static DECLARE_DELAYED_WORK(work_read_data, sdio_xprt_read_data);
-static struct workqueue_struct *sdio_xprt_read_workqueue;
-
-struct sdio_buf_struct {
-	struct list_head list;
-	uint32_t size;
-	uint32_t read_index;
-	uint32_t write_index;
-	unsigned char data[SDIO_BUF_SIZE];
-};
-
-static void sdio_xprt_write_data(struct work_struct *work);
-static DECLARE_WORK(work_write_data, sdio_xprt_write_data);
-static wait_queue_head_t write_avail_wait_q;
-static uint32_t num_free_bufs;
-static uint32_t num_tx_bufs;
-static uint32_t num_rx_bufs;
-
-static DEFINE_MUTEX(modem_reset_lock);
-static uint32_t modem_reset;
-
-static void free_sdio_xprt(struct sdio_xprt *chnl)
-{
-	struct sdio_buf_struct *buf;
-	unsigned long flags;
-
-	if (!chnl) {
-		printk(KERN_ERR "Invalid chnl to free\n");
-		return;
-	}
-
-	spin_lock_irqsave(&chnl->free_list_lock, flags);
-	while (!list_empty(&chnl->free_list)) {
-		buf = list_first_entry(&chnl->free_list,
-					struct sdio_buf_struct, list);
-		list_del(&buf->list);
-		kfree(buf);
-	}
-	num_free_bufs = 0;
-	spin_unlock_irqrestore(&chnl->free_list_lock, flags);
-
-	spin_lock_irqsave(&chnl->write_list_lock, flags);
-	while (!list_empty(&chnl->write_list)) {
-		buf = list_first_entry(&chnl->write_list,
-					struct sdio_buf_struct, list);
-		list_del(&buf->list);
-		kfree(buf);
-	}
-	num_tx_bufs = 0;
-	spin_unlock_irqrestore(&chnl->write_list_lock, flags);
-
-	spin_lock_irqsave(&chnl->read_list_lock, flags);
-	while (!list_empty(&chnl->read_list)) {
-		buf = list_first_entry(&chnl->read_list,
-					struct sdio_buf_struct, list);
-		list_del(&buf->list);
-		kfree(buf);
-	}
-	num_rx_bufs = 0;
-	spin_unlock_irqrestore(&chnl->read_list_lock, flags);
-	wake_unlock(&chnl->read_wakelock);
-}
-
-static struct sdio_buf_struct *alloc_from_free_list(struct sdio_xprt *chnl)
-{
-	struct sdio_buf_struct *buf;
-	unsigned long flags;
-
-	spin_lock_irqsave(&chnl->free_list_lock, flags);
-	if (list_empty(&chnl->free_list)) {
-		spin_unlock_irqrestore(&chnl->free_list_lock, flags);
-		SDIO_XPRT_DBG("%s: Free list empty\n", __func__);
-		return NULL;
-	}
-	buf = list_first_entry(&chnl->free_list, struct sdio_buf_struct, list);
-	list_del(&buf->list);
-	num_free_bufs--;
-	spin_unlock_irqrestore(&chnl->free_list_lock, flags);
-
-	buf->size = 0;
-	buf->read_index = 0;
-	buf->write_index = 0;
-
-	return buf;
-}
-
-static void return_to_free_list(struct sdio_xprt *chnl,
-				struct sdio_buf_struct *buf)
-{
-	unsigned long flags;
-
-	if (!chnl || !buf) {
-		pr_err("%s: Invalid chnl or buf\n", __func__);
-		return;
-	}
-
-	buf->size = 0;
-	buf->read_index = 0;
-	buf->write_index = 0;
-
-	spin_lock_irqsave(&chnl->free_list_lock, flags);
-	list_add_tail(&buf->list, &chnl->free_list);
-	num_free_bufs++;
-	spin_unlock_irqrestore(&chnl->free_list_lock, flags);
-
-}
-
-static int rpcrouter_sdio_remote_read_avail(void)
-{
-	int read_avail = 0;
-	unsigned long flags;
-	struct sdio_buf_struct *buf;
-
-	spin_lock_irqsave(&sdio_remote_xprt.channel->read_list_lock, flags);
-	list_for_each_entry(buf, &sdio_remote_xprt.channel->read_list, list) {
-		read_avail += buf->size;
-	}
-	spin_unlock_irqrestore(&sdio_remote_xprt.channel->read_list_lock,
-				flags);
-	return read_avail;
-}
-
-static int rpcrouter_sdio_remote_read(void *data, uint32_t len)
-{
-	struct sdio_buf_struct *buf;
-	unsigned char *buf_data;
-	unsigned long flags;
-
-	SDIO_XPRT_DBG("sdio_xprt Called %s\n", __func__);
-	if (len < 0 || !data)
-		return -EINVAL;
-	else if (len == 0)
-		return 0;
-
-	spin_lock_irqsave(&sdio_remote_xprt.channel->read_list_lock, flags);
-	if (list_empty(&sdio_remote_xprt.channel->read_list)) {
-		spin_unlock_irqrestore(
-			&sdio_remote_xprt.channel->read_list_lock, flags);
-		return -EINVAL;
-	}
-
-	buf = list_first_entry(&sdio_remote_xprt.channel->read_list,
-				struct sdio_buf_struct, list);
-	if (buf->size < len) {
-		spin_unlock_irqrestore(
-			&sdio_remote_xprt.channel->read_list_lock, flags);
-		return -EINVAL;
-	}
-
-	buf_data = buf->data + buf->read_index;
-	memcpy(data, buf_data, len);
-	buf->read_index += len;
-	buf->size -= len;
-	if (buf->size == 0) {
-		list_del(&buf->list);
-		num_rx_bufs--;
-		return_to_free_list(sdio_remote_xprt.channel, buf);
-	}
-
-	if (list_empty(&sdio_remote_xprt.channel->read_list))
-		wake_unlock(&sdio_remote_xprt.channel->read_wakelock);
-	spin_unlock_irqrestore(&sdio_remote_xprt.channel->read_list_lock,
-				flags);
-	return len;
-}
-
-static int rpcrouter_sdio_remote_write_avail(void)
-{
-	uint32_t write_avail = 0;
-	unsigned long flags;
-
-	SDIO_XPRT_DBG("sdio_xprt Called %s\n", __func__);
-	spin_lock_irqsave(&sdio_remote_xprt.channel->write_list_lock, flags);
-	write_avail = (MAX_TX_BUFS - num_tx_bufs) * SDIO_BUF_SIZE;
-	spin_unlock_irqrestore(&sdio_remote_xprt.channel->write_list_lock,
-				flags);
-	return write_avail;
-}
-
-static int rpcrouter_sdio_remote_write(void *data, uint32_t len,
-					enum write_data_type type)
-{
-	unsigned long flags;
-	static struct sdio_buf_struct *buf;
-	unsigned char *buf_data;
-
-	switch (type) {
-	case HEADER:
-		spin_lock_irqsave(&sdio_remote_xprt.channel->write_list_lock,
-				  flags);
-		if (num_tx_bufs == MAX_TX_BUFS) {
-			spin_unlock_irqrestore(
-				&sdio_remote_xprt.channel->write_list_lock,
-				flags);
-			return -ENOMEM;
-		}
-		spin_unlock_irqrestore(
-			&sdio_remote_xprt.channel->write_list_lock, flags);
-
-		SDIO_XPRT_DBG("sdio_xprt WRITE HEADER %s\n", __func__);
-		buf = alloc_from_free_list(sdio_remote_xprt.channel);
-		if (!buf) {
-			pr_err("%s: alloc_from_free_list failed\n", __func__);
-			return -ENOMEM;
-		}
-		buf_data = buf->data + buf->write_index;
-		memcpy(buf_data, data, len);
-		buf->write_index += len;
-		buf->size += len;
-		return len;
-	case PACKMARK:
-		SDIO_XPRT_DBG("sdio_xprt WRITE PACKMARK %s\n",	__func__);
-		if (!buf) {
-			pr_err("%s: HEADER not written or alloc failed\n",
-				__func__);
-			return -ENOMEM;
-		}
-		buf_data = buf->data + buf->write_index;
-		memcpy(buf_data, data, len);
-		buf->write_index += len;
-		buf->size += len;
-		return len;
-	case PAYLOAD:
-		SDIO_XPRT_DBG("sdio_xprt WRITE PAYLOAD %s\n",	__func__);
-		if (!buf) {
-			pr_err("%s: HEADER not written or alloc failed\n",
-				__func__);
-			return -ENOMEM;
-		}
-		buf_data = buf->data + buf->write_index;
-		memcpy(buf_data, data, len);
-		buf->write_index += len;
-		buf->size += len;
-
-		SDIO_XPRT_DBG("sdio_xprt flush %d bytes\n", buf->size);
-		spin_lock_irqsave(&sdio_remote_xprt.channel->write_list_lock,
-				   flags);
-		list_add_tail(&buf->list,
-			      &sdio_remote_xprt.channel->write_list);
-		num_tx_bufs++;
-		spin_unlock_irqrestore(
-			&sdio_remote_xprt.channel->write_list_lock, flags);
-		queue_work(sdio_xprt_read_workqueue, &work_write_data);
-		buf = NULL;
-		return len;
-	default:
-		return -EINVAL;
-	}
-}
-
-static void sdio_xprt_write_data(struct work_struct *work)
-{
-	int rc = 0, sdio_write_retry = 0;
-	unsigned long flags;
-	struct sdio_buf_struct *buf;
-
-	mutex_lock(&modem_reset_lock);
-	if (modem_reset) {
-		mutex_unlock(&modem_reset_lock);
-		return;
-	}
-
-	spin_lock_irqsave(&sdio_remote_xprt.channel->write_list_lock, flags);
-	while (!list_empty(&sdio_remote_xprt.channel->write_list)) {
-		buf = list_first_entry(&sdio_remote_xprt.channel->write_list,
-					struct sdio_buf_struct, list);
-		list_del(&buf->list);
-		spin_unlock_irqrestore(
-			&sdio_remote_xprt.channel->write_list_lock, flags);
-		mutex_unlock(&modem_reset_lock);
-
-		wait_event(write_avail_wait_q,
-			   (!(modem_reset) && (sdio_write_avail(
-			   sdio_remote_xprt.channel->handle) >=
-			   buf->size)));
-
-		mutex_lock(&modem_reset_lock);
-		while (!(modem_reset) &&
-			((rc = sdio_write(sdio_remote_xprt.channel->handle,
-					buf->data, buf->size)) < 0) &&
-			(sdio_write_retry++ < MAX_SDIO_WRITE_RETRY)) {
-			printk(KERN_ERR "sdio_write failed with RC %d\n", rc);
-			mutex_unlock(&modem_reset_lock);
-			msleep(250);
-			mutex_lock(&modem_reset_lock);
-		}
-		if (modem_reset) {
-			mutex_unlock(&modem_reset_lock);
-			kfree(buf);
-			return;
-		} else {
-			return_to_free_list(sdio_remote_xprt.channel, buf);
-		}
-
-		if (!rc)
-			SDIO_XPRT_DBG("sdio_write %d bytes completed\n",
-					buf->size);
-
-		spin_lock_irqsave(&sdio_remote_xprt.channel->write_list_lock,
-				   flags);
-		num_tx_bufs--;
-	}
-	spin_unlock_irqrestore(&sdio_remote_xprt.channel->write_list_lock,
-				flags);
-	mutex_unlock(&modem_reset_lock);
-}
-
-static int rpcrouter_sdio_remote_close(void)
-{
-	SDIO_XPRT_DBG("sdio_xprt Called %s\n", __func__);
-	flush_workqueue(sdio_xprt_read_workqueue);
-	sdio_close(sdio_remote_xprt.channel->handle);
-	free_sdio_xprt(sdio_remote_xprt.channel);
-	return 0;
-}
-
-static void sdio_xprt_read_data(struct work_struct *work)
-{
-	int size = 0, read_avail;
-	unsigned long flags;
-	struct sdio_buf_struct *buf;
-	SDIO_XPRT_DBG("sdio_xprt Called %s\n", __func__);
-
-	mutex_lock(&modem_reset_lock);
-	while (!(modem_reset) &&
-		((read_avail =
-		sdio_read_avail(sdio_remote_xprt.channel->handle)) > 0)) {
-		spin_lock_irqsave(&sdio_remote_xprt.channel->read_list_lock,
-				  flags);
-		if (num_rx_bufs == MAX_RX_BUFS) {
-			spin_unlock_irqrestore(
-				&sdio_remote_xprt.channel->read_list_lock,
-				flags);
-			queue_delayed_work(sdio_xprt_read_workqueue,
-					   &work_read_data,
-					   msecs_to_jiffies(100));
-			break;
-		}
-		spin_unlock_irqrestore(
-			&sdio_remote_xprt.channel->read_list_lock, flags);
-
-		buf = alloc_from_free_list(sdio_remote_xprt.channel);
-		if (!buf) {
-			SDIO_XPRT_DBG("%s: Failed to alloc_from_free_list"
-				      " Try again later\n", __func__);
-			queue_delayed_work(sdio_xprt_read_workqueue,
-					   &work_read_data,
-					   msecs_to_jiffies(100));
-			break;
-		}
-
-		size = sdio_read(sdio_remote_xprt.channel->handle,
-				 buf->data, read_avail);
-		if (size < 0) {
-			printk(KERN_ERR "sdio_read failed,"
-					" read %d bytes, expected %d\n",
-					size, read_avail);
-			return_to_free_list(sdio_remote_xprt.channel, buf);
-			queue_delayed_work(sdio_xprt_read_workqueue,
-					   &work_read_data,
-					   msecs_to_jiffies(100));
-			break;
-		}
-
-		if (size == 0)
-			size = read_avail;
-
-		buf->size = size;
-		buf->write_index = size;
-		spin_lock_irqsave(&sdio_remote_xprt.channel->read_list_lock,
-				   flags);
-		list_add_tail(&buf->list,
-			      &sdio_remote_xprt.channel->read_list);
-		num_rx_bufs++;
-		spin_unlock_irqrestore(
-			&sdio_remote_xprt.channel->read_list_lock, flags);
-		wake_lock(&sdio_remote_xprt.channel->read_wakelock);
-	}
-
-	if (!modem_reset && !list_empty(&sdio_remote_xprt.channel->read_list))
-		msm_rpcrouter_xprt_notify(&sdio_remote_xprt.xprt,
-				  RPCROUTER_XPRT_EVENT_DATA);
-	mutex_unlock(&modem_reset_lock);
-}
-
-static void rpcrouter_sdio_remote_notify(void *_dev, unsigned event)
-{
-	if (event == SDIO_EVENT_DATA_READ_AVAIL) {
-		SDIO_XPRT_DBG("%s Received Notify"
-			      "SDIO_EVENT_DATA_READ_AVAIL\n", __func__);
-		queue_delayed_work(sdio_xprt_read_workqueue,
-				   &work_read_data, 0);
-	}
-	if (event == SDIO_EVENT_DATA_WRITE_AVAIL) {
-		SDIO_XPRT_DBG("%s Received Notify"
-			      "SDIO_EVENT_DATA_WRITE_AVAIL\n", __func__);
-		wake_up(&write_avail_wait_q);
-	}
-}
-
-static int allocate_sdio_xprt(struct sdio_xprt **sdio_xprt_chnl)
-{
-	struct sdio_buf_struct *buf;
-	struct sdio_xprt *chnl;
-	int i;
-	unsigned long flags;
-	int rc = -ENOMEM;
-
-	if (!(*sdio_xprt_chnl)) {
-		chnl = kmalloc(sizeof(struct sdio_xprt), GFP_KERNEL);
-		if (!chnl) {
-			printk(KERN_ERR "sdio_xprt channel"
-					" allocation failed\n");
-			return rc;
-		}
-
-		spin_lock_init(&chnl->write_list_lock);
-		spin_lock_init(&chnl->read_list_lock);
-		spin_lock_init(&chnl->free_list_lock);
-
-		INIT_LIST_HEAD(&chnl->write_list);
-		INIT_LIST_HEAD(&chnl->read_list);
-		INIT_LIST_HEAD(&chnl->free_list);
-		wake_lock_init(&chnl->read_wakelock,
-				WAKE_LOCK_SUSPEND, "rpc_sdio_xprt_read");
-	} else {
-		chnl = *sdio_xprt_chnl;
-	}
-
-	for (i = 0; i < NUM_SDIO_BUFS; i++) {
-		buf = kzalloc(sizeof(struct sdio_buf_struct), GFP_KERNEL);
-		if (!buf) {
-			printk(KERN_ERR "sdio_buf_struct alloc failed\n");
-			goto alloc_failure;
-		}
-		spin_lock_irqsave(&chnl->free_list_lock, flags);
-		list_add_tail(&buf->list, &chnl->free_list);
-		spin_unlock_irqrestore(&chnl->free_list_lock, flags);
-	}
-	num_free_bufs = NUM_SDIO_BUFS;
-
-	*sdio_xprt_chnl = chnl;
-	return 0;
-
-alloc_failure:
-	spin_lock_irqsave(&chnl->free_list_lock, flags);
-	while (!list_empty(&chnl->free_list)) {
-		buf = list_first_entry(&chnl->free_list,
-					struct sdio_buf_struct,
-					list);
-		list_del(&buf->list);
-		kfree(buf);
-	}
-	spin_unlock_irqrestore(&chnl->free_list_lock, flags);
-	wake_lock_destroy(&chnl->read_wakelock);
-
-	kfree(chnl);
-	*sdio_xprt_chnl = NULL;
-	return rc;
-}
-
-static int rpcrouter_sdio_remote_probe(struct platform_device *pdev)
-{
-	int rc;
-
-	SDIO_XPRT_INFO("%s Called\n", __func__);
-
-	mutex_lock(&modem_reset_lock);
-	if (!modem_reset) {
-		sdio_xprt_read_workqueue =
-			create_singlethread_workqueue("sdio_xprt");
-		if (!sdio_xprt_read_workqueue) {
-			mutex_unlock(&modem_reset_lock);
-			return -ENOMEM;
-		}
-
-		sdio_remote_xprt.xprt.name = "rpcrotuer_sdio_xprt";
-		sdio_remote_xprt.xprt.read_avail =
-			rpcrouter_sdio_remote_read_avail;
-		sdio_remote_xprt.xprt.read = rpcrouter_sdio_remote_read;
-		sdio_remote_xprt.xprt.write_avail =
-			rpcrouter_sdio_remote_write_avail;
-		sdio_remote_xprt.xprt.write = rpcrouter_sdio_remote_write;
-		sdio_remote_xprt.xprt.close = rpcrouter_sdio_remote_close;
-		sdio_remote_xprt.xprt.priv = NULL;
-
-		init_waitqueue_head(&write_avail_wait_q);
-	}
-	modem_reset = 0;
-
-	rc = allocate_sdio_xprt(&sdio_remote_xprt.channel);
-	if (rc) {
-		destroy_workqueue(sdio_xprt_read_workqueue);
-		mutex_unlock(&modem_reset_lock);
-		return rc;
-	}
-
-	/* Open up SDIO channel */
-	rc = sdio_open("SDIO_RPC", &sdio_remote_xprt.channel->handle, NULL,
-		      rpcrouter_sdio_remote_notify);
-
-	if (rc < 0) {
-		free_sdio_xprt(sdio_remote_xprt.channel);
-		destroy_workqueue(sdio_xprt_read_workqueue);
-		mutex_unlock(&modem_reset_lock);
-		return rc;
-	}
-	mutex_unlock(&modem_reset_lock);
-
-	msm_rpcrouter_xprt_notify(&sdio_remote_xprt.xprt,
-				  RPCROUTER_XPRT_EVENT_OPEN);
-
-	SDIO_XPRT_INFO("%s Completed\n", __func__);
-
-	return 0;
-}
-
-static int rpcrouter_sdio_remote_remove(struct platform_device *pdev)
-{
-	SDIO_XPRT_INFO("%s Called\n", __func__);
-
-	mutex_lock(&modem_reset_lock);
-	modem_reset = 1;
-	wake_up(&write_avail_wait_q);
-	free_sdio_xprt(sdio_remote_xprt.channel);
-	mutex_unlock(&modem_reset_lock);
-
-	msm_rpcrouter_xprt_notify(&sdio_remote_xprt.xprt,
-				  RPCROUTER_XPRT_EVENT_CLOSE);
-
-	SDIO_XPRT_INFO("%s Completed\n", __func__);
-
-	return 0;
-}
-
-/*Remove this platform driver after mainline of SDIO_AL update*/
-static struct platform_driver rpcrouter_sdio_remote_driver = {
-	.probe		= rpcrouter_sdio_remote_probe,
-	.driver		= {
-			.name	= "SDIO_AL",
-			.owner	= THIS_MODULE,
-	},
-};
-
-static struct platform_driver rpcrouter_sdio_driver = {
-	.probe		= rpcrouter_sdio_remote_probe,
-	.remove		= rpcrouter_sdio_remote_remove,
-	.driver		= {
-			.name	= "SDIO_RPC",
-			.owner	= THIS_MODULE,
-	},
-};
-
-static int __init rpcrouter_sdio_init(void)
-{
-	int rc;
-	msm_sdio_xprt_debug_mask = 0x2;
-	rc = platform_driver_register(&rpcrouter_sdio_remote_driver);
-	if (rc < 0)
-		return rc;
-	return platform_driver_register(&rpcrouter_sdio_driver);
-}
-
-module_init(rpcrouter_sdio_init);
-MODULE_DESCRIPTION("RPC Router SDIO XPRT");
-MODULE_LICENSE("GPL v2");
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/sdio_al.c b/arch/arm/mach-msm/sdio_al.c
deleted file mode 100644
index bcfc556..0000000
--- a/arch/arm/mach-msm/sdio_al.c
+++ /dev/null
@@ -1,4365 +0,0 @@
-/* Copyright (c) 2010-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.
- */
-
-/*
- * SDIO-Abstraction-Layer Module.
- *
- * To be used with Qualcomm's SDIO-Client connected to this host.
- */
-#include "sdio_al_private.h"
-
-#include <linux/module.h>
-#include <linux/scatterlist.h>
-#include <linux/workqueue.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/wakelock.h>
-#include <linux/mmc/core.h>
-#include <linux/mmc/card.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/mmc.h>
-#include <linux/mmc/sdio.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio_ids.h>
-#include <linux/gpio.h>
-#include <linux/dma-mapping.h>
-#include <linux/earlysuspend.h>
-#include <linux/debugfs.h>
-#include <linux/uaccess.h>
-#include <linux/syscalls.h>
-#include <linux/time.h>
-#include <linux/spinlock.h>
-
-#include <mach/dma.h>
-#include <mach/gpio.h>
-#include <mach/subsystem_notif.h>
-
-#include "../../../drivers/mmc/host/msm_sdcc.h"
-
-/**
- *  Func#0 has SDIO standard registers
- *  Func#1 is for Mailbox.
- *  Functions 2..7 are for channels.
- *  Currently only functions 2..5 are active due to SDIO-Client
- *  number of pipes.
- *
- */
-#define SDIO_AL_MAX_CHANNELS 6
-
-/** Func 1..5 */
-#define SDIO_AL_MAX_FUNCS    (SDIO_AL_MAX_CHANNELS+1)
-#define SDIO_AL_WAKEUP_FUNC  6
-
-/** Number of SDIO-Client pipes */
-#define SDIO_AL_MAX_PIPES    16
-#define SDIO_AL_ACTIVE_PIPES 8
-
-/** CMD53/CMD54 Block size */
-#define SDIO_AL_BLOCK_SIZE   256
-
-/** Func#1 hardware Mailbox base address	 */
-#define HW_MAILBOX_ADDR			0x1000
-
-/** Func#1 peer sdioc software version.
- *  The header is duplicated also to the mailbox of the other
- *  functions. It can be used before other functions are enabled. */
-#define SDIOC_SW_HEADER_ADDR		0x0400
-
-/** Func#2..7 software Mailbox base address at 16K */
-#define SDIOC_SW_MAILBOX_ADDR			0x4000
-
-/** Some Mailbox registers address, written by host for
- control */
-#define PIPES_THRESHOLD_ADDR		0x01000
-
-#define PIPES_0_7_IRQ_MASK_ADDR 	0x01048
-
-#define PIPES_8_15_IRQ_MASK_ADDR	0x0104C
-
-#define FUNC_1_4_MASK_IRQ_ADDR		0x01040
-#define FUNC_5_7_MASK_IRQ_ADDR		0x01044
-#define FUNC_1_4_USER_IRQ_ADDR		0x01050
-#define FUNC_5_7_USER_IRQ_ADDR		0x01054
-
-#define EOT_PIPES_ENABLE		0x00
-
-/** Maximum read/write data available is SDIO-Client limitation */
-#define MAX_DATA_AVAILABLE   		(16*1024)
-#define INVALID_DATA_AVAILABLE  	(0x8000)
-
-/** SDIO-Client HW threshold to generate interrupt to the
- *  SDIO-Host on write available bytes.
- */
-#define DEFAULT_WRITE_THRESHOLD 	(1024)
-
-/** SDIO-Client HW threshold to generate interrupt to the
- *  SDIO-Host on read available bytes, for streaming (non
- *  packet) rx data.
- */
-#define DEFAULT_READ_THRESHOLD  	(1024)
-#define LOW_LATENCY_THRESHOLD		(1)
-
-/* Extra bytes to ensure getting the rx threshold interrupt on stream channels
-   when restoring the threshold after sleep */
-#define THRESHOLD_CHANGE_EXTRA_BYTES (100)
-
-/** SW threshold to trigger reading the mailbox. */
-#define DEFAULT_MIN_WRITE_THRESHOLD 	(1024)
-#define DEFAULT_MIN_WRITE_THRESHOLD_STREAMING	(1600)
-
-#define THRESHOLD_DISABLE_VAL  		(0xFFFFFFFF)
-
-/** Mailbox polling time for packet channels */
-#define DEFAULT_POLL_DELAY_MSEC		10
-/** Mailbox polling time for streaming channels */
-#define DEFAULT_POLL_DELAY_NOPACKET_MSEC 30
-
-/** The SDIO-Client prepares N buffers of size X per Tx pipe.
- *  Even when the transfer fills a partial buffer,
- *  that buffer becomes unusable for the next transfer. */
-#define DEFAULT_PEER_TX_BUF_SIZE	(128)
-
-#define ROUND_UP(x, n) (((x + n - 1) / n) * n)
-
-/** Func#2..7 FIFOs are r/w via
- sdio_readsb() & sdio_writesb(),when inc_addr=0 */
-#define PIPE_RX_FIFO_ADDR   0x00
-#define PIPE_TX_FIFO_ADDR   0x00
-
-/** Inactivity time to go to sleep in mseconds */
-#define INACTIVITY_TIME_MSEC 30
-#define INITIAL_INACTIVITY_TIME_MSEC 5000
-
-/** Context validity check */
-#define SDIO_AL_SIGNATURE 0xAABBCCDD
-
-/* Vendor Specific Command */
-#define SD_IO_RW_EXTENDED_QCOM 54
-
-#define TIME_TO_WAIT_US 500
-#define SDIO_CLOSE_FLUSH_TIMEOUT_MSEC   (10000)
-#define RX_FLUSH_BUFFER_SIZE (16*1024)
-
-#define SDIO_TEST_POSTFIX "_TEST"
-
-#define DATA_DEBUG(x, y...)						\
-	do {								\
-		if (sdio_al->debug.debug_data_on)			\
-			pr_info(y);					\
-		sdio_al_log(x, y);					\
-	} while (0)
-
-#define LPM_DEBUG(x, y...)						\
-	do {								\
-		if (sdio_al->debug.debug_lpm_on)			\
-			pr_info(y);					\
-		sdio_al_log(x, y);					\
-	} while (0)
-
-#define sdio_al_loge(x, y...)						\
-	do {								\
-		pr_err(y);						\
-		sdio_al_log(x, y);					\
-	} while (0)
-
-#define sdio_al_logi(x, y...)						\
-	do {								\
-		pr_info(y);						\
-		sdio_al_log(x, y);					\
-	} while (0)
-
-#define CLOSE_DEBUG(x, y...)						\
-	do {								\
-		if (sdio_al->debug.debug_close_on)			\
-			pr_info(y);					\
-		sdio_al_log(x, y);					\
-	} while (0)
-
-/* The index of the SDIO card used for the sdio_al_dloader */
-#define SDIO_BOOTLOADER_CARD_INDEX 1
-
-
-/* SDIO card state machine */
-enum sdio_al_device_state {
-	CARD_INSERTED,
-	CARD_REMOVED,
-	MODEM_RESTART
-};
-
-struct sdio_al_debug {
-	u8 debug_lpm_on;
-	u8 debug_data_on;
-	u8 debug_close_on;
-	struct dentry *sdio_al_debug_root;
-	struct dentry *sdio_al_debug_lpm_on;
-	struct dentry *sdio_al_debug_data_on;
-	struct dentry *sdio_al_debug_close_on;
-	struct dentry *sdio_al_debug_info;
-	struct dentry *sdio_al_debug_log_buffers[MAX_NUM_OF_SDIO_DEVICES + 1];
-};
-
-/* Polling time for the inactivity timer for devices that doesn't have
- * a streaming channel
- */
-#define SDIO_AL_POLL_TIME_NO_STREAMING 30
-
-#define CHAN_TO_FUNC(x) ((x) + 2 - 1)
-
-/**
- *  Mailbox structure.
- *  The Mailbox is located on the SDIO-Client Function#1.
- *  The mailbox size is 128 bytes, which is one block.
- *  The mailbox allows the host ton:
- *  1. Get the number of available bytes on the pipes.
- *  2. Enable/Disable SDIO-Client interrupt, related to pipes.
- *  3. Set the Threshold for generating interrupt.
- *
- */
-struct sdio_mailbox {
-	u32 pipe_bytes_threshold[SDIO_AL_MAX_PIPES]; /* Addr 0x1000 */
-
-	/* Mask USER interrupts generated towards host - Addr 0x1040 */
-	u32 mask_irq_func_1:8; /* LSB */
-	u32 mask_irq_func_2:8;
-	u32 mask_irq_func_3:8;
-	u32 mask_irq_func_4:8;
-
-	u32 mask_irq_func_5:8;
-	u32 mask_irq_func_6:8;
-	u32 mask_irq_func_7:8;
-	u32 mask_mutex_irq:8;
-
-	/* Mask PIPE interrupts generated towards host - Addr 0x1048 */
-	u32 mask_eot_pipe_0_7:8;
-	u32 mask_thresh_above_limit_pipe_0_7:8;
-	u32 mask_overflow_pipe_0_7:8;
-	u32 mask_underflow_pipe_0_7:8;
-
-	u32 mask_eot_pipe_8_15:8;
-	u32 mask_thresh_above_limit_pipe_8_15:8;
-	u32 mask_overflow_pipe_8_15:8;
-	u32 mask_underflow_pipe_8_15:8;
-
-	/* Status of User interrupts generated towards host - Addr 0x1050 */
-	u32 user_irq_func_1:8;
-	u32 user_irq_func_2:8;
-	u32 user_irq_func_3:8;
-	u32 user_irq_func_4:8;
-
-	u32 user_irq_func_5:8;
-	u32 user_irq_func_6:8;
-	u32 user_irq_func_7:8;
-	u32 user_mutex_irq:8;
-
-	/* Status of PIPE interrupts generated towards host */
-	/* Note: All sources are cleared once they read. - Addr 0x1058 */
-	u32 eot_pipe_0_7:8;
-	u32 thresh_above_limit_pipe_0_7:8;
-	u32 overflow_pipe_0_7:8;
-	u32 underflow_pipe_0_7:8;
-
-	u32 eot_pipe_8_15:8;
-	u32 thresh_above_limit_pipe_8_15:8;
-	u32 overflow_pipe_8_15:8;
-	u32 underflow_pipe_8_15:8;
-
-	u16 pipe_bytes_avail[SDIO_AL_MAX_PIPES];
-};
-
-/** Track pending Rx Packet size */
-struct rx_packet_size {
-	u32 size; /* in bytes */
-	struct list_head	list;
-};
-
-#define PEER_SDIOC_SW_MAILBOX_SIGNATURE 0xFACECAFE
-#define PEER_SDIOC_SW_MAILBOX_UT_SIGNATURE 0x5D107E57
-#define PEER_SDIOC_SW_MAILBOX_BOOT_SIGNATURE 0xDEADBEEF
-
-/* Allow support in old sdio version */
-#define PEER_SDIOC_OLD_VERSION_MAJOR	0x0002
-#define INVALID_SDIO_CHAN		0xFF
-
-/**
- * Peer SDIO-Client software header.
- */
-struct peer_sdioc_sw_header {
-	u32 signature;
-	u32 version;
-	u32 max_channels;
-	char channel_names[SDIO_AL_MAX_CHANNELS][PEER_CHANNEL_NAME_SIZE];
-	u32 reserved[23];
-};
-
-struct peer_sdioc_boot_sw_header {
-	u32 signature;
-	u32 version;
-	u32 boot_ch_num;
-	u32 reserved[29]; /* 32 - previous fields */
-};
-
-/**
- * Peer SDIO-Client software mailbox.
- */
-struct peer_sdioc_sw_mailbox {
-	struct peer_sdioc_sw_header sw_header;
-	struct peer_sdioc_channel_config ch_config[SDIO_AL_MAX_CHANNELS];
-};
-
-#define SDIO_AL_DEBUG_LOG_SIZE 3000
-struct sdio_al_local_log {
-	char buffer[SDIO_AL_DEBUG_LOG_SIZE];
-	unsigned int buf_cur_pos;
-	spinlock_t log_lock;
-};
-
-#define SDIO_AL_DEBUG_TMP_LOG_SIZE 250
-static int sdio_al_log(struct sdio_al_local_log *, const char *fmt, ...);
-
-/**
- *  SDIO Abstraction Layer driver context.
- *
- *  @pdata -
- *  @debug -
- *  @devices - an array of the the devices claimed by sdio_al
- *  @unittest_mode - a flag to indicate if sdio_al is in
- *		   unittest mode
- *  @bootloader_dev - the device which is used for the
- *                 bootloader
- *  @subsys_notif_handle - handle for modem restart
- *                 notifications
- *
- */
-struct sdio_al {
-	struct sdio_al_local_log gen_log;
-	struct sdio_al_local_log device_log[MAX_NUM_OF_SDIO_DEVICES];
-	struct sdio_al_platform_data *pdata;
-	struct sdio_al_debug debug;
-	struct sdio_al_device *devices[MAX_NUM_OF_SDIO_DEVICES];
-	int unittest_mode;
-	struct sdio_al_device *bootloader_dev;
-	void *subsys_notif_handle;
-	int sdioc_major;
-	int skip_print_info;
-};
-
-struct sdio_al_work {
-	struct work_struct work;
-	struct sdio_al_device *sdio_al_dev;
-};
-
-
-/**
- *  SDIO Abstraction Layer device context.
- *
- *  @card - card claimed.
- *
- *  @mailbox - A shadow of the SDIO-Client mailbox.
- *
- *  @channel - Channels context.
- *
- *  @workqueue - workqueue to read the mailbox and handle
- *     pending requests. Reading the mailbox should not happen
- *     in interrupt context.
- *
- *  @work - work to submit to workqueue.
- *
- *  @is_ready - driver is ready.
- *
- *  @ask_mbox - Flag to request reading the mailbox,
- *					  for different reasons.
- *
- *  @wake_lock - Lock when can't sleep.
- *
- *  @lpm_chan - Channel to use for LPM (low power mode)
- *            communication.
- *
- *  @is_ok_to_sleep - Mark if driver is OK with going to sleep
- * 			(no pending transactions).
- *
- *  @inactivity_time - time allowed to be in inactivity before
- * 		going to sleep
- *
- *  @timer - timer to use for polling the mailbox.
- *
- *  @poll_delay_msec - timer delay for polling the mailbox.
- *
- *  @is_err - error detected.
- *
- *  @signature - Context Validity Check.
- *
- *  @flashless_boot_on - flag to indicate if sdio_al is in
- *    flshless boot mode
- *
- */
-struct sdio_al_device {
-	struct sdio_al_local_log *dev_log;
-	struct mmc_card *card;
-	struct mmc_host *host;
-	struct sdio_mailbox *mailbox;
-	struct sdio_channel channel[SDIO_AL_MAX_CHANNELS];
-
-	struct peer_sdioc_sw_header *sdioc_sw_header;
-	struct peer_sdioc_boot_sw_header *sdioc_boot_sw_header;
-
-	struct workqueue_struct *workqueue;
-	struct sdio_al_work sdio_al_work;
-	struct sdio_al_work boot_work;
-
-	int is_ready;
-
-	wait_queue_head_t   wait_mbox;
-	int ask_mbox;
-	int bootloader_done;
-
-	struct wake_lock wake_lock;
-	int lpm_chan;
-	int is_ok_to_sleep;
-	unsigned long inactivity_time;
-
-	struct timer_list timer;
-	u32 poll_delay_msec;
-	int is_timer_initialized;
-
-	int is_err;
-
-	u32 signature;
-
-	unsigned int is_suspended;
-
-	int flashless_boot_on;
-	int ch_close_supported;
-	int state;
-	int (*lpm_callback)(void *, int);
-
-	int print_after_interrupt;
-
-	u8 *rx_flush_buf;
-};
-
-/*
- * Host operation:
- *   lower 16bits are operation code
- *   upper 16bits are operation state
- */
-#define PEER_OPERATION(op_code , op_state) ((op_code) | ((op_state) << 16))
-#define GET_PEER_OPERATION_CODE(op) ((op) & 0xffff)
-#define GET_PEER_OPERATION_STATE(op) ((op) >> 16)
-
-enum peer_op_code {
-	PEER_OP_CODE_CLOSE = 1
-};
-
-enum peer_op_state {
-	PEER_OP_STATE_INIT = 0,
-	PEER_OP_STATE_START = 1
-};
-
-
-/*
- * On the kernel command line specify
- * sdio_al.debug_lpm_on=1 to enable the LPM debug messages
- * By default the LPM debug messages are turned off
- */
-static int debug_lpm_on;
-module_param(debug_lpm_on, int, 0);
-
-/*
- * On the kernel command line specify
- * sdio_al.debug_data_on=1 to enable the DATA debug messages
- * By default the DATA debug messages are turned off
- */
-static int debug_data_on;
-module_param(debug_data_on, int, 0);
-
-/*
- * Enables / disables open close debug messages
- */
-static int debug_close_on = 1;
-module_param(debug_close_on, int, 0);
-
-/** The driver context */
-static struct sdio_al *sdio_al;
-
-/* Static functions declaration */
-static int enable_eot_interrupt(struct sdio_al_device *sdio_al_dev,
-				int pipe_index, int enable);
-static int enable_threshold_interrupt(struct sdio_al_device *sdio_al_dev,
-				      int pipe_index, int enable);
-static void sdio_func_irq(struct sdio_func *func);
-static void sdio_al_timer_handler(unsigned long data);
-static int get_min_poll_time_msec(struct sdio_al_device *sdio_al_dev);
-static u32 check_pending_rx_packet(struct sdio_channel *ch, u32 eot);
-static u32 remove_handled_rx_packet(struct sdio_channel *ch);
-static int set_pipe_threshold(struct sdio_al_device *sdio_al_dev,
-			      int pipe_index, int threshold);
-static int sdio_al_wake_up(struct sdio_al_device *sdio_al_dev,
-			   u32 not_from_int, struct sdio_channel *ch);
-static int sdio_al_client_setup(struct sdio_al_device *sdio_al_dev);
-static int enable_mask_irq(struct sdio_al_device *sdio_al_dev,
-			   int func_num, int enable, u8 bit_offset);
-static int sdio_al_enable_func_retry(struct sdio_func *func, const char *name);
-static void sdio_al_print_info(void);
-static int sdio_read_internal(struct sdio_channel *ch, void *data, int len);
-static int sdio_read_from_closed_ch(struct sdio_channel *ch, int len);
-static void stop_and_del_timer(struct sdio_al_device *sdio_al_dev);
-
-#define SDIO_AL_ERR(func)					\
-	do {							\
-		printk_once(KERN_ERR MODULE_NAME		\
-			":In Error state, ignore %s\n",		\
-			func);					\
-		sdio_al_print_info();				\
-	} while (0)
-
-#ifdef CONFIG_DEBUG_FS
-static int debug_info_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return 0;
-}
-
-static ssize_t debug_info_write(struct file *file,
-		const char __user *buf, size_t count, loff_t *ppos)
-{
-	sdio_al_print_info();
-	return 1;
-}
-
-const struct file_operations debug_info_ops = {
-	.open = debug_info_open,
-	.write = debug_info_write,
-};
-
-struct debugfs_blob_wrapper sdio_al_dbgfs_log[MAX_NUM_OF_SDIO_DEVICES + 1];
-
-/*
-*
-* Trigger on/off for debug messages
-* for trigger off the data messages debug level use:
-* echo 0 > /sys/kernel/debugfs/sdio_al/debug_data_on
-* for trigger on the data messages debug level use:
-* echo 1 > /sys/kernel/debugfs/sdio_al/debug_data_on
-* for trigger off the lpm messages debug level use:
-* echo 0 > /sys/kernel/debugfs/sdio_al/debug_lpm_on
-* for trigger on the lpm messages debug level use:
-* echo 1 > /sys/kernel/debugfs/sdio_al/debug_lpm_on
-*/
-static int sdio_al_debugfs_init(void)
-{
-	int i, blob_errs = 0;
-
-	sdio_al->debug.sdio_al_debug_root = debugfs_create_dir("sdio_al", NULL);
-	if (!sdio_al->debug.sdio_al_debug_root)
-		return -ENOENT;
-
-	sdio_al->debug.sdio_al_debug_lpm_on = debugfs_create_u8("debug_lpm_on",
-					S_IRUGO | S_IWUGO,
-					sdio_al->debug.sdio_al_debug_root,
-					&sdio_al->debug.debug_lpm_on);
-
-	sdio_al->debug.sdio_al_debug_data_on = debugfs_create_u8(
-					"debug_data_on",
-					S_IRUGO | S_IWUGO,
-					sdio_al->debug.sdio_al_debug_root,
-					&sdio_al->debug.debug_data_on);
-
-	sdio_al->debug.sdio_al_debug_close_on = debugfs_create_u8(
-					"debug_close_on",
-					S_IRUGO | S_IWUGO,
-					sdio_al->debug.sdio_al_debug_root,
-					&sdio_al->debug.debug_close_on);
-
-	sdio_al->debug.sdio_al_debug_info = debugfs_create_file(
-					"sdio_debug_info",
-					S_IRUGO | S_IWUGO,
-					sdio_al->debug.sdio_al_debug_root,
-					NULL,
-					&debug_info_ops);
-
-	for (i = 0; i < MAX_NUM_OF_SDIO_DEVICES; ++i) {
-		char temp[18];
-
-		scnprintf(temp, 18, "sdio_al_log_dev_%d", i + 1);
-		sdio_al->debug.sdio_al_debug_log_buffers[i] =
-			debugfs_create_blob(temp,
-					S_IRUGO | S_IWUGO,
-					sdio_al->debug.sdio_al_debug_root,
-					&sdio_al_dbgfs_log[i]);
-	}
-
-	sdio_al->debug.sdio_al_debug_log_buffers[MAX_NUM_OF_SDIO_DEVICES] =
-			debugfs_create_blob("sdio_al_gen_log",
-				S_IRUGO | S_IWUGO,
-				sdio_al->debug.sdio_al_debug_root,
-				&sdio_al_dbgfs_log[MAX_NUM_OF_SDIO_DEVICES]);
-
-	for (i = 0; i < (MAX_NUM_OF_SDIO_DEVICES + 1); ++i) {
-		if (!sdio_al->debug.sdio_al_debug_log_buffers[i]) {
-			pr_err(MODULE_NAME ": Failed to create debugfs buffer"
-				   " entry for "
-				   "sdio_al->debug.sdio_al_debug_log_buffers[%d]",
-				   i);
-			blob_errs = 1;
-		}
-	}
-
-	if (blob_errs) {
-		for (i = 0; i < (MAX_NUM_OF_SDIO_DEVICES + 1); ++i)
-			if (sdio_al->debug.sdio_al_debug_log_buffers[i])
-				debugfs_remove(
-					sdio_al->
-					debug.sdio_al_debug_log_buffers[i]);
-	}
-
-
-	if ((!sdio_al->debug.sdio_al_debug_data_on) &&
-	    (!sdio_al->debug.sdio_al_debug_lpm_on) &&
-	    (!sdio_al->debug.sdio_al_debug_close_on) &&
-	    (!sdio_al->debug.sdio_al_debug_info) &&
-		blob_errs) {
-		debugfs_remove(sdio_al->debug.sdio_al_debug_root);
-		sdio_al->debug.sdio_al_debug_root = NULL;
-		return -ENOENT;
-	}
-
-	sdio_al_dbgfs_log[MAX_NUM_OF_SDIO_DEVICES].data =
-						sdio_al->gen_log.buffer;
-	sdio_al_dbgfs_log[MAX_NUM_OF_SDIO_DEVICES].size =
-						SDIO_AL_DEBUG_LOG_SIZE;
-
-	return 0;
-}
-
-static void sdio_al_debugfs_cleanup(void)
-{
-	int i;
-
-	debugfs_remove(sdio_al->debug.sdio_al_debug_lpm_on);
-	debugfs_remove(sdio_al->debug.sdio_al_debug_data_on);
-	debugfs_remove(sdio_al->debug.sdio_al_debug_close_on);
-	debugfs_remove(sdio_al->debug.sdio_al_debug_info);
-
-	for (i = 0; i < (MAX_NUM_OF_SDIO_DEVICES + 1); ++i)
-		debugfs_remove(sdio_al->debug.sdio_al_debug_log_buffers[i]);
-
-	debugfs_remove(sdio_al->debug.sdio_al_debug_root);
-}
-#endif
-
-static int sdio_al_log(struct sdio_al_local_log *log, const char *fmt, ...)
-{
-	va_list args;
-	int r;
-	char *tp, *log_buf;
-	unsigned int *log_cur_pos;
-	struct timeval kt;
-	unsigned long flags;
-	static char sdio_al_log_tmp[SDIO_AL_DEBUG_TMP_LOG_SIZE];
-
-	spin_lock_irqsave(&log->log_lock, flags);
-
-	kt = ktime_to_timeval(ktime_get());
-	r = scnprintf(sdio_al_log_tmp, SDIO_AL_DEBUG_TMP_LOG_SIZE,
-			"[%8ld.%6ld] ", kt.tv_sec, kt.tv_usec);
-
-	va_start(args, fmt);
-	r += vscnprintf(&sdio_al_log_tmp[r], (SDIO_AL_DEBUG_TMP_LOG_SIZE - r),
-			fmt, args);
-	va_end(args);
-
-	log_buf = log->buffer;
-	log_cur_pos = &(log->buf_cur_pos);
-
-	for (tp = sdio_al_log_tmp; tp < (sdio_al_log_tmp + r); tp++) {
-		log_buf[(*log_cur_pos)++] = *tp;
-		if ((*log_cur_pos) == SDIO_AL_DEBUG_LOG_SIZE)
-			*log_cur_pos = 0;
-	}
-
-	spin_unlock_irqrestore(&log->log_lock, flags);
-
-	return r;
-}
-
-static int sdio_al_verify_func1(struct sdio_al_device *sdio_al_dev,
-				char const *func)
-{
-	if (sdio_al_dev == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL "
-				"sdio_al_dev\n", func);
-		return -ENODEV;
-	}
-
-	if (sdio_al_dev->signature != SDIO_AL_SIGNATURE) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": %s: Invalid "
-				"signature\n", func);
-		return -ENODEV;
-	}
-
-	if (!sdio_al_dev->card) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": %s: NULL "
-				"card\n", func);
-		return -ENODEV;
-	}
-	if (!sdio_al_dev->card->sdio_func[0]) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": %s: NULL "
-				"func1\n", func);
-		return -ENODEV;
-	}
-	return 0;
-}
-
-static int sdio_al_claim_mutex(struct sdio_al_device *sdio_al_dev,
-			       char const *func)
-{
-	if (!sdio_al_dev) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL "
-					"device\n", func);
-		return -ENODEV;
-	}
-
-	if (sdio_al_dev->signature != SDIO_AL_SIGNATURE) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": %s: Invalid "
-					"device signature\n", func);
-		return -ENODEV;
-	}
-
-	if (!sdio_al_dev->host) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": %s: NULL "
-					"host\n", func);
-		return -ENODEV;
-	}
-
-	mmc_claim_host(sdio_al_dev->host);
-
-	return 0;
-}
-
-static int sdio_al_release_mutex(struct sdio_al_device *sdio_al_dev,
-			       char const *func)
-{
-	if (!sdio_al_dev) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL "
-					"device\n", func);
-		return -ENODEV;
-	}
-
-	if (sdio_al_dev->signature != SDIO_AL_SIGNATURE) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": %s: Invalid "
-					"device signature\n", func);
-		return -ENODEV;
-	}
-
-	if (!sdio_al_dev->host) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": %s: NULL "
-					"host\n", func);
-		return -ENODEV;
-	}
-
-	mmc_release_host(sdio_al_dev->host);
-
-	return 0;
-}
-
-static int sdio_al_claim_mutex_and_verify_dev(
-	struct sdio_al_device *sdio_al_dev,
-	char const *func)
-{
-	if (sdio_al_claim_mutex(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	if (sdio_al_dev->state != CARD_INSERTED) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": %s: Invalid "
-				"device state %d\n", func, sdio_al_dev->state);
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-static void sdio_al_get_into_err_state(struct sdio_al_device *sdio_al_dev)
-{
-	if ((!sdio_al) || (!sdio_al_dev))
-		return;
-
-	sdio_al_dev->is_err = true;
-	sdio_al->debug.debug_data_on = 0;
-	sdio_al->debug.debug_lpm_on = 0;
-	sdio_al_print_info();
-}
-
-void sdio_al_register_lpm_cb(void *device_handle,
-				       int(*lpm_callback)(void *, int))
-{
-	struct sdio_al_device *sdio_al_dev =
-		(struct sdio_al_device *) device_handle;
-
-	if (!sdio_al_dev) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s - "
-				"device_handle is NULL\n", __func__);
-		return;
-	}
-
-	if (lpm_callback) {
-		sdio_al_dev->lpm_callback = lpm_callback;
-		lpm_callback((void *)sdio_al_dev,
-					   sdio_al_dev->is_ok_to_sleep);
-	}
-
-	LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ": %s - device %d "
-			"registered for wakeup callback\n", __func__,
-			sdio_al_dev->host->index);
-}
-
-void sdio_al_unregister_lpm_cb(void *device_handle)
-{
-	struct sdio_al_device *sdio_al_dev =
-		(struct sdio_al_device *) device_handle;
-
-	if (!sdio_al_dev) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s - "
-				"device_handle is NULL\n", __func__);
-		return;
-	}
-
-	sdio_al_dev->lpm_callback = NULL;
-	LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ": %s - device %d "
-		"unregister for wakeup callback\n", __func__,
-		sdio_al_dev->host->index);
-}
-
-static void sdio_al_vote_for_sleep(struct sdio_al_device *sdio_al_dev,
-				   int is_vote_for_sleep)
-{
-	pr_debug(MODULE_NAME ": %s()", __func__);
-
-	if (!sdio_al_dev) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s - sdio_al_dev"
-				" is NULL\n", __func__);
-		return;
-	}
-
-	if (is_vote_for_sleep) {
-		pr_debug(MODULE_NAME ": %s - sdio vote for Sleep", __func__);
-		wake_unlock(&sdio_al_dev->wake_lock);
-	} else {
-		pr_debug(MODULE_NAME ": %s - sdio vote against sleep",
-			  __func__);
-		wake_lock(&sdio_al_dev->wake_lock);
-	}
-
-	if (sdio_al_dev->lpm_callback != NULL) {
-		LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ": %s - "
-				"is_vote_for_sleep=%d for card#%d, "
-				"calling callback...", __func__,
-				is_vote_for_sleep,
-				sdio_al_dev->host->index);
-		sdio_al_dev->lpm_callback((void *)sdio_al_dev,
-					   is_vote_for_sleep);
-	}
-}
-
-/**
- *  Write SDIO-Client lpm information
- *  Should only be called with host claimed.
- */
-static int write_lpm_info(struct sdio_al_device *sdio_al_dev)
-{
-	struct sdio_func *lpm_func = NULL;
-	int offset = offsetof(struct peer_sdioc_sw_mailbox, ch_config)+
-		sizeof(struct peer_sdioc_channel_config) *
-		sdio_al_dev->lpm_chan+
-		offsetof(struct peer_sdioc_channel_config, is_host_ok_to_sleep);
-	int ret;
-
-	if (sdio_al_dev->lpm_chan == INVALID_SDIO_CHAN) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Invalid "
-				"lpm_chan for card %d\n",
-				sdio_al_dev->host->index);
-		return -EINVAL;
-	}
-
-	if (!sdio_al_dev->card ||
-		!sdio_al_dev->card->sdio_func[sdio_al_dev->lpm_chan+1]) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": NULL card or lpm_func\n");
-		return -ENODEV;
-	}
-	lpm_func = sdio_al_dev->card->sdio_func[sdio_al_dev->lpm_chan+1];
-
-	pr_debug(MODULE_NAME ":write_lpm_info is_ok_to_sleep=%d, device %d\n",
-		 sdio_al_dev->is_ok_to_sleep,
-		 sdio_al_dev->host->index);
-
-	ret = sdio_memcpy_toio(lpm_func, SDIOC_SW_MAILBOX_ADDR+offset,
-				&sdio_al_dev->is_ok_to_sleep, sizeof(u32));
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":failed to "
-				"write lpm info for card %d\n",
-				sdio_al_dev->host->index);
-		return ret;
-	}
-
-	return 0;
-}
-
-/* Set inactivity counter to intial value to allow clients come up */
-static inline void start_inactive_time(struct sdio_al_device *sdio_al_dev)
-{
-	sdio_al_dev->inactivity_time = jiffies +
-		msecs_to_jiffies(INITIAL_INACTIVITY_TIME_MSEC);
-}
-
-static inline void restart_inactive_time(struct sdio_al_device *sdio_al_dev)
-{
-	sdio_al_dev->inactivity_time = jiffies +
-		msecs_to_jiffies(INACTIVITY_TIME_MSEC);
-}
-
-static inline int is_inactive_time_expired(struct sdio_al_device *sdio_al_dev)
-{
-	return time_after(jiffies, sdio_al_dev->inactivity_time);
-}
-
-
-static int is_user_irq_enabled(struct sdio_al_device *sdio_al_dev,
-			       int func_num)
-{
-	int ret = 0;
-	struct sdio_func *func1;
-	u32 user_irq = 0;
-	u32 addr = 0;
-	u32 offset = 0;
-	u32 masked_user_irq = 0;
-
-	if (sdio_al_verify_func1(sdio_al_dev, __func__))
-		return 0;
-	func1 = sdio_al_dev->card->sdio_func[0];
-
-	if (func_num < 4) {
-		addr = FUNC_1_4_USER_IRQ_ADDR;
-		offset = func_num * 8;
-	} else {
-		addr = FUNC_5_7_USER_IRQ_ADDR;
-		offset = (func_num - 4) * 8;
-	}
-
-	user_irq = sdio_readl(func1, addr, &ret);
-	if (ret) {
-		pr_debug(MODULE_NAME ":read_user_irq fail\n");
-		return 0;
-	}
-
-	masked_user_irq = (user_irq >> offset) && 0xFF;
-	if (masked_user_irq == 0x1) {
-		sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":user_irq "
-				"enabled\n");
-		return 1;
-	}
-
-	return 0;
-}
-
-static void sdio_al_sleep(struct sdio_al_device *sdio_al_dev,
-			  struct mmc_host *host)
-{
-	int i;
-
-	/* Go to sleep */
-	pr_debug(MODULE_NAME  ":Inactivity timer expired."
-		" Going to sleep\n");
-	/* Stop mailbox timer */
-	stop_and_del_timer(sdio_al_dev);
-	/* Make sure we get interrupt for non-packet-mode right away */
-	for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++) {
-		struct sdio_channel *ch = &sdio_al_dev->channel[i];
-		if ((ch->state != SDIO_CHANNEL_STATE_OPEN) &&
-		    (ch->state != SDIO_CHANNEL_STATE_CLOSED)) {
-			pr_debug(MODULE_NAME  ":continue for channel %s in"
-					" state %d\n", ch->name, ch->state);
-			continue;
-		}
-		if (ch->is_packet_mode == false) {
-			ch->read_threshold = LOW_LATENCY_THRESHOLD;
-			set_pipe_threshold(sdio_al_dev,
-					   ch->rx_pipe_index,
-					   ch->read_threshold);
-		}
-	}
-	/* Prevent modem to go to sleep until we get the PROG_DONE on
-	   the dummy CMD52 */
-	msmsdcc_set_pwrsave(sdio_al_dev->host, 0);
-	/* Mark HOST_OK_TOSLEEP */
-	sdio_al_dev->is_ok_to_sleep = 1;
-	write_lpm_info(sdio_al_dev);
-
-	msmsdcc_lpm_enable(host);
-	LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":Finished sleep sequence"
-			" for card %d. Sleep now.\n",
-		sdio_al_dev->host->index);
-	/* Release wakelock */
-	sdio_al_vote_for_sleep(sdio_al_dev, 1);
-}
-
-
-/**
- *  Read SDIO-Client Mailbox from Function#1.thresh_pipe
- *
- *  The mailbox contain the bytes available per pipe,
- *  and the End-Of-Transfer indication per pipe (if available).
- *
- * WARNING: Each time the Mailbox is read from the client, the
- * read_bytes_avail is incremented with another pending
- * transfer. Therefore, a pending rx-packet should be added to a
- * list before the next read of the mailbox.
- *
- * This function should run from a workqueue context since it
- * notifies the clients.
- *
- * This function assumes that sdio_al_claim_mutex was called before
- * calling it.
- *
- */
-static int read_mailbox(struct sdio_al_device *sdio_al_dev, int from_isr)
-{
-	int ret;
-	struct sdio_func *func1 = NULL;
-	struct sdio_mailbox *mailbox = sdio_al_dev->mailbox;
-	struct mmc_host *host = sdio_al_dev->host;
-	u32 new_write_avail = 0;
-	u32 old_write_avail = 0;
-	u32 any_read_avail = 0;
-	u32 any_write_pending = 0;
-	int i;
-	u32 rx_notify_bitmask = 0;
-	u32 tx_notify_bitmask = 0;
-	u32 eot_pipe = 0;
-	u32 thresh_pipe = 0;
-	u32 overflow_pipe = 0;
-	u32 underflow_pipe = 0;
-	u32 thresh_intr_mask = 0;
-	int is_closing = 0;
-
-	if (sdio_al_dev->is_err) {
-		SDIO_AL_ERR(__func__);
-		return 0;
-	}
-
-	if (sdio_al_verify_func1(sdio_al_dev, __func__))
-		return -ENODEV;
-	func1 = sdio_al_dev->card->sdio_func[0];
-
-	pr_debug(MODULE_NAME ":start %s from_isr = %d for card %d.\n"
-		 , __func__, from_isr, sdio_al_dev->host->index);
-
-	pr_debug(MODULE_NAME ":before sdio_memcpy_fromio.\n");
-	memset(mailbox, 0, sizeof(struct sdio_mailbox));
-	ret = sdio_memcpy_fromio(func1, mailbox,
-			HW_MAILBOX_ADDR, sizeof(*mailbox));
-	pr_debug(MODULE_NAME ":after sdio_memcpy_fromio.\n");
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Fail to read "
-				"Mailbox for card %d, goto error state\n",
-				sdio_al_dev->host->index);
-		sdio_al_get_into_err_state(sdio_al_dev);
-		goto exit_err;
-	}
-
-	eot_pipe =	(mailbox->eot_pipe_0_7) |
-			(mailbox->eot_pipe_8_15<<8);
-	thresh_pipe = 	(mailbox->thresh_above_limit_pipe_0_7) |
-			(mailbox->thresh_above_limit_pipe_8_15<<8);
-
-	overflow_pipe = (mailbox->overflow_pipe_0_7) |
-			(mailbox->overflow_pipe_8_15<<8);
-	underflow_pipe = mailbox->underflow_pipe_0_7 |
-			(mailbox->underflow_pipe_8_15<<8);
-	thresh_intr_mask =
-		(mailbox->mask_thresh_above_limit_pipe_0_7) |
-		(mailbox->mask_thresh_above_limit_pipe_8_15<<8);
-
-	if (overflow_pipe || underflow_pipe)
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Mailbox ERROR "
-				"overflow=0x%x, underflow=0x%x\n",
-				overflow_pipe, underflow_pipe);
-
-	/* In case of modem reset we would like to read the daya from the modem
-	   to clear the interrupts but do not process it */
-	if (sdio_al_dev->state != CARD_INSERTED) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":sdio_al_device"
-				" (card %d) is in invalid state %d\n",
-				sdio_al_dev->host->index,
-				sdio_al_dev->state);
-		return -ENODEV;
-	}
-
-	pr_debug(MODULE_NAME ":card %d: eot=0x%x, thresh=0x%x\n",
-			sdio_al_dev->host->index,
-			eot_pipe, thresh_pipe);
-
-	/* Scan for Rx Packets available and update read available bytes */
-	for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++) {
-		struct sdio_channel *ch = &sdio_al_dev->channel[i];
-		u32 old_read_avail;
-		u32 read_avail;
-		u32 new_packet_size = 0;
-
-		if (ch->state == SDIO_CHANNEL_STATE_CLOSING)
-			is_closing = true; /* used to prevent sleep */
-
-		old_read_avail = ch->read_avail;
-		read_avail = mailbox->pipe_bytes_avail[ch->rx_pipe_index];
-
-		if ((ch->state == SDIO_CHANNEL_STATE_CLOSED) &&
-			(read_avail > 0)) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				 ":%s: Invalid read_avail 0x%x, for CLOSED ch %s\n",
-				 __func__, read_avail, ch->name);
-			sdio_read_from_closed_ch(ch, read_avail);
-		}
-		if ((ch->state != SDIO_CHANNEL_STATE_OPEN) &&
-		    (ch->state != SDIO_CHANNEL_STATE_CLOSING))
-			continue;
-
-		if (read_avail > INVALID_DATA_AVAILABLE) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				 ":Invalid read_avail 0x%x for pipe %d\n",
-				 read_avail, ch->rx_pipe_index);
-			continue;
-		}
-		any_read_avail |= read_avail | old_read_avail;
-		ch->statistics.last_any_read_avail = any_read_avail;
-		ch->statistics.last_read_avail = read_avail;
-		ch->statistics.last_old_read_avail = old_read_avail;
-
-		if (ch->is_packet_mode) {
-			if ((eot_pipe & (1<<ch->rx_pipe_index)) &&
-			    sdio_al_dev->print_after_interrupt) {
-				LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME
-					":Interrupt on ch %s, "
-					"card %d", ch->name,
-					sdio_al_dev->host->index);
-			}
-			new_packet_size = check_pending_rx_packet(ch, eot_pipe);
-		} else {
-			if ((thresh_pipe & (1<<ch->rx_pipe_index)) &&
-			    sdio_al_dev->print_after_interrupt) {
-				LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME
-					":Interrupt on ch %s, "
-					"card %d", ch->name,
-					sdio_al_dev->host->index);
-			}
-			ch->read_avail = read_avail;
-
-			/*
-			 * Restore default thresh for non packet channels.
-			 * in case it IS low latency channel then read_threshold
-			 * and def_read_threshold are both
-			 * LOW_LATENCY_THRESHOLD
-			 */
-			if ((ch->read_threshold != ch->def_read_threshold) &&
-			    (read_avail >= ch->threshold_change_cnt)) {
-				if (!ch->is_low_latency_ch) {
-					ch->read_threshold =
-						ch->def_read_threshold;
-					set_pipe_threshold(sdio_al_dev,
-							   ch->rx_pipe_index,
-							   ch->read_threshold);
-				}
-			}
-		}
-
-		if ((ch->is_packet_mode) && (new_packet_size > 0)) {
-			rx_notify_bitmask |= (1<<ch->num);
-			ch->statistics.total_notifs++;
-		}
-
-		if ((!ch->is_packet_mode) && (ch->read_avail > 0) &&
-		    (old_read_avail == 0)) {
-			rx_notify_bitmask |= (1<<ch->num);
-			ch->statistics.total_notifs++;
-		}
-	}
-	sdio_al_dev->print_after_interrupt = 0;
-
-	/* Update Write available */
-	for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++) {
-		struct sdio_channel *ch = &sdio_al_dev->channel[i];
-
-		if ((ch->state != SDIO_CHANNEL_STATE_OPEN) &&
-		    (ch->state != SDIO_CHANNEL_STATE_CLOSING))
-			continue;
-
-		new_write_avail = mailbox->pipe_bytes_avail[ch->tx_pipe_index];
-
-		if (new_write_avail > INVALID_DATA_AVAILABLE) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				 ":Invalid write_avail 0x%x for pipe %d\n",
-				 new_write_avail, ch->tx_pipe_index);
-			continue;
-		}
-
-		old_write_avail = ch->write_avail;
-		ch->write_avail = new_write_avail;
-
-		if ((old_write_avail <= ch->min_write_avail) &&
-			(new_write_avail >= ch->min_write_avail))
-			tx_notify_bitmask |= (1<<ch->num);
-
-		/* There is not enough write avail for this channel.
-		   We need to keep reading mailbox to wait for the appropriate
-		   write avail and cannot sleep. Ignore SMEM channel that has
-		   only one direction. */
-		if (strncmp(ch->name, "SDIO_SMEM", CHANNEL_NAME_SIZE))
-			any_write_pending |=
-			(new_write_avail < ch->ch_config.max_tx_threshold);
-	}
-	/* notify clients */
-	for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++) {
-		struct sdio_channel *ch = &sdio_al_dev->channel[i];
-
-		if ((ch->state != SDIO_CHANNEL_STATE_OPEN) ||
-				(ch->notify == NULL))
-			continue;
-
-		if (rx_notify_bitmask & (1<<ch->num))
-			ch->notify(ch->priv,
-					   SDIO_EVENT_DATA_READ_AVAIL);
-
-		if (tx_notify_bitmask & (1<<ch->num))
-			ch->notify(ch->priv,
-					   SDIO_EVENT_DATA_WRITE_AVAIL);
-	}
-
-
-	if ((rx_notify_bitmask == 0) && (tx_notify_bitmask == 0) &&
-	    !any_read_avail && !any_write_pending) {
-		DATA_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":Nothing to "
-				"Notify for card %d, is_closing=%d\n",
-				sdio_al_dev->host->index, is_closing);
-		if (is_closing)
-			restart_inactive_time(sdio_al_dev);
-		else if (is_inactive_time_expired(sdio_al_dev))
-			sdio_al_sleep(sdio_al_dev, host);
-	} else {
-		DATA_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":Notify bitmask"
-				" for card %d rx=0x%x, tx=0x%x.\n",
-				sdio_al_dev->host->index,
-				rx_notify_bitmask, tx_notify_bitmask);
-		/* Restart inactivity timer if any activity on the channel */
-		restart_inactive_time(sdio_al_dev);
-	}
-
-	pr_debug(MODULE_NAME ":end %s.\n", __func__);
-
-exit_err:
-	return ret;
-}
-
-/**
- *  Check pending rx packet when reading the mailbox.
- */
-static u32 check_pending_rx_packet(struct sdio_channel *ch, u32 eot)
-{
-	u32 rx_pending;
-	u32 rx_avail;
-	u32 new_packet_size = 0;
-	struct sdio_al_device *sdio_al_dev = ch->sdio_al_dev;
-
-
-	if (sdio_al_dev == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": NULL sdio_al_dev"
-				" for channel %s\n", ch->name);
-		return -EINVAL;
-	}
-
-	mutex_lock(&ch->ch_lock);
-
-	rx_pending = ch->rx_pending_bytes;
-	rx_avail = sdio_al_dev->mailbox->pipe_bytes_avail[ch->rx_pipe_index];
-
-	pr_debug(MODULE_NAME ":pipe %d of card %d rx_avail=0x%x, "
-			     "rx_pending=0x%x\n",
-	   ch->rx_pipe_index, sdio_al_dev->host->index, rx_avail,
-		 rx_pending);
-
-
-	/* new packet detected */
-	if (eot & (1<<ch->rx_pipe_index)) {
-		struct rx_packet_size *p = NULL;
-		new_packet_size = rx_avail - rx_pending;
-
-		if ((rx_avail <= rx_pending)) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					": Invalid new packet size."
-					" rx_avail=%d.\n", rx_avail);
-			new_packet_size = 0;
-			goto exit_err;
-		}
-
-		p = kzalloc(sizeof(*p), GFP_KERNEL);
-		if (p == NULL) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					": failed to allocate item for "
-					"rx_pending list. rx_avail=%d, "
-					"rx_pending=%d.\n",
-					rx_avail, rx_pending);
-			new_packet_size = 0;
-			goto exit_err;
-		}
-		p->size = new_packet_size;
-		/* Add new packet as last */
-		list_add_tail(&p->list, &ch->rx_size_list_head);
-		ch->rx_pending_bytes += new_packet_size;
-
-		if (ch->read_avail == 0)
-			ch->read_avail = new_packet_size;
-	}
-
-exit_err:
-	mutex_unlock(&ch->ch_lock);
-
-	return new_packet_size;
-}
-
-
-
-/**
- *  Remove first pending packet from the list.
- */
-static u32 remove_handled_rx_packet(struct sdio_channel *ch)
-{
-	struct rx_packet_size *p = NULL;
-
-	mutex_lock(&ch->ch_lock);
-
-	ch->rx_pending_bytes -= ch->read_avail;
-
-	if (!list_empty(&ch->rx_size_list_head)) {
-		p = list_first_entry(&ch->rx_size_list_head,
-			struct rx_packet_size, list);
-		list_del(&p->list);
-		kfree(p);
-	} else {
-		sdio_al_loge(ch->sdio_al_dev->dev_log, MODULE_NAME ":%s: ch "
-				"%s: unexpected empty list!!\n",
-				__func__, ch->name);
-	}
-
-	if (list_empty(&ch->rx_size_list_head))	{
-		ch->read_avail = 0;
-	} else {
-		p = list_first_entry(&ch->rx_size_list_head,
-			struct rx_packet_size, list);
-		ch->read_avail = p->size;
-	}
-
-	mutex_unlock(&ch->ch_lock);
-
-	return ch->read_avail;
-}
-
-
-/**
- *  Bootloader worker function.
- *
- *  @note: clear the bootloader_done flag only after reading the
- *  mailbox, to ignore more requests while reading the mailbox.
- */
-static void boot_worker(struct work_struct *work)
-{
-	int ret = 0;
-	int func_num = 0;
-	int i;
-	struct sdio_al_device *sdio_al_dev = NULL;
-	struct sdio_al_work *sdio_al_work = container_of(work,
-							 struct sdio_al_work,
-							 work);
-
-	if (sdio_al_work == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL "
-				"sdio_al_work\n", __func__);
-		return;
-	}
-
-	sdio_al_dev = sdio_al_work->sdio_al_dev;
-	if (sdio_al_dev == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL "
-				"sdio_al_dev\n", __func__);
-		return;
-	}
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ":Bootloader Worker Started"
-			", wait for bootloader_done event..\n");
-	wait_event(sdio_al_dev->wait_mbox,
-		   sdio_al_dev->bootloader_done);
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ":Got bootloader_done "
-			"event..\n");
-	/* Do polling until MDM is up */
-	for (i = 0; i < 5000; ++i) {
-		if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-			return;
-		if (is_user_irq_enabled(sdio_al_dev, func_num)) {
-			sdio_al_release_mutex(sdio_al_dev, __func__);
-			sdio_al_dev->bootloader_done = 0;
-			ret = sdio_al_client_setup(sdio_al_dev);
-			if (ret) {
-				sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					": sdio_al_client_setup failed, "
-					"for card %d ret=%d\n",
-					sdio_al_dev->host->index, ret);
-				sdio_al_get_into_err_state(sdio_al_dev);
-			}
-			goto done;
-		}
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-		msleep(100);
-	}
-	sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Timeout waiting for "
-			"user_irq for card %d\n",
-			sdio_al_dev->host->index);
-	sdio_al_get_into_err_state(sdio_al_dev);
-
-done:
-	pr_debug(MODULE_NAME ":Boot Worker for card %d Exit!\n",
-		sdio_al_dev->host->index);
-}
-
-/**
- *  Worker function.
- *
- *  @note: clear the ask_mbox flag only after
- *  	 reading the mailbox, to ignore more requests while
- *  	 reading the mailbox.
- */
-static void worker(struct work_struct *work)
-{
-	int ret = 0;
-	struct sdio_al_device *sdio_al_dev = NULL;
-	struct sdio_al_work *sdio_al_work = container_of(work,
-							 struct sdio_al_work,
-							 work);
-	if (sdio_al_work == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": worker: NULL "
-				"sdio_al_work\n");
-		return;
-	}
-
-	sdio_al_dev = sdio_al_work->sdio_al_dev;
-	if (sdio_al_dev == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": worker: NULL "
-				"sdio_al_dev\n");
-		return;
-	}
-	pr_debug(MODULE_NAME ":Worker Started..\n");
-	while ((sdio_al_dev->is_ready) && (ret == 0)) {
-		pr_debug(MODULE_NAME ":Wait for read mailbox request..\n");
-		wait_event(sdio_al_dev->wait_mbox, sdio_al_dev->ask_mbox);
-		if (!sdio_al_dev->is_ready)
-			break;
-		if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-			break;
-		if (sdio_al_dev->is_ok_to_sleep) {
-			ret = sdio_al_wake_up(sdio_al_dev, 1, NULL);
-			if (ret) {
-				sdio_al_release_mutex(sdio_al_dev, __func__);
-				return;
-			}
-		}
-		ret = read_mailbox(sdio_al_dev, false);
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-		sdio_al_dev->ask_mbox = false;
-	}
-
-	pr_debug(MODULE_NAME ":Worker Exit!\n");
-}
-
-/**
- *  Write command using CMD54 rather than CMD53.
- *  Writing with CMD54 generate EOT interrupt at the
- *  SDIO-Client.
- *  Based on mmc_io_rw_extended()
- */
-static int sdio_write_cmd54(struct mmc_card *card, unsigned fn,
-	unsigned addr, const u8 *buf,
-	unsigned blocks, unsigned blksz)
-{
-	struct mmc_request mrq;
-	struct mmc_command cmd;
-	struct mmc_data data;
-	struct scatterlist sg;
-	int incr_addr = 1; /* MUST */
-	int write = 1;
-
-	BUG_ON(!card);
-	BUG_ON(fn > 7);
-	BUG_ON(blocks == 1 && blksz > 512);
-	WARN_ON(blocks == 0);
-	WARN_ON(blksz == 0);
-
-	write = true;
-	pr_debug(MODULE_NAME ":sdio_write_cmd54()"
-		"fn=%d,buf=0x%x,blocks=%d,blksz=%d\n",
-		fn, (u32) buf, blocks, blksz);
-
-	memset(&mrq, 0, sizeof(struct mmc_request));
-	memset(&cmd, 0, sizeof(struct mmc_command));
-	memset(&data, 0, sizeof(struct mmc_data));
-
-	mrq.cmd = &cmd;
-	mrq.data = &data;
-
-	cmd.opcode = SD_IO_RW_EXTENDED_QCOM;
-
-	cmd.arg = write ? 0x80000000 : 0x00000000;
-	cmd.arg |= fn << 28;
-	cmd.arg |= incr_addr ? 0x04000000 : 0x00000000;
-	cmd.arg |= addr << 9;
-	if (blocks == 1 && blksz <= 512)
-		cmd.arg |= (blksz == 512) ? 0 : blksz;  /* byte mode */
-	else
-		cmd.arg |= 0x08000000 | blocks; 	/* block mode */
-	cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
-
-	data.blksz = blksz;
-	data.blocks = blocks;
-	data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
-	data.sg = &sg;
-	data.sg_len = 1;
-
-	sg_init_one(&sg, buf, blksz * blocks);
-
-	mmc_set_data_timeout(&data, card);
-
-	mmc_wait_for_req(card->host, &mrq);
-
-	if (cmd.error)
-		return cmd.error;
-	if (data.error)
-		return data.error;
-
-	if (mmc_host_is_spi(card->host)) {
-		/* host driver already reported errors */
-	} else {
-		if (cmd.resp[0] & R5_ERROR) {
-			sdio_al_loge(&sdio_al->gen_log, MODULE_NAME
-						":%s: R5_ERROR for card %d",
-						__func__, card->host->index);
-			return -EIO;
-		}
-		if (cmd.resp[0] & R5_FUNCTION_NUMBER) {
-			sdio_al_loge(&sdio_al->gen_log, MODULE_NAME
-						":%s: R5_FUNCTION_NUMBER for card %d",
-						__func__, card->host->index);
-			return -EINVAL;
-		}
-		if (cmd.resp[0] & R5_OUT_OF_RANGE) {
-			sdio_al_loge(&sdio_al->gen_log, MODULE_NAME
-						":%s: R5_OUT_OF_RANGE for card %d",
-						__func__, card->host->index);
-			return -ERANGE;
-		}
-	}
-
-	return 0;
-}
-
-
-/**
- *  Write data to channel.
- *  Handle different data size types.
- *
- */
-static int sdio_ch_write(struct sdio_channel *ch, const u8 *buf, u32 len)
-{
-	int ret = 0;
-	unsigned blksz = ch->func->cur_blksize;
-	int blocks = len / blksz;
-	int remain_bytes = len % blksz;
-	struct mmc_card *card = NULL;
-	u32 fn = ch->func->num;
-
-	if (!ch) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL "
-				"channel\n", __func__);
-		return -ENODEV;
-	}
-
-	if (!ch->sdio_al_dev) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL "
-				"sdio_al_dev\n", __func__);
-		return -ENODEV;
-	}
-
-	if (len == 0) {
-		sdio_al_loge(ch->sdio_al_dev->dev_log, MODULE_NAME ":channel "
-				"%s trying to write 0 bytes\n", ch->name);
-		return -EINVAL;
-	}
-
-	card = ch->func->card;
-
-	if (remain_bytes) {
-		/* CMD53 */
-		if (blocks) {
-			ret = sdio_memcpy_toio(ch->func, PIPE_TX_FIFO_ADDR,
-					       (void *) buf, blocks*blksz);
-			if (ret != 0) {
-				sdio_al_loge(ch->sdio_al_dev->dev_log,
-					MODULE_NAME ":%s: sdio_memcpy_toio "
-					"failed for channel %s\n",
-					__func__, ch->name);
-				sdio_al_get_into_err_state(ch->sdio_al_dev);
-				return ret;
-			}
-		}
-
-		buf += (blocks*blksz);
-
-		ret = sdio_write_cmd54(card, fn, PIPE_TX_FIFO_ADDR,
-				buf, 1, remain_bytes);
-	} else {
-		ret = sdio_write_cmd54(card, fn, PIPE_TX_FIFO_ADDR,
-				buf, blocks, blksz);
-	}
-
-	if (ret != 0) {
-		sdio_al_loge(ch->sdio_al_dev->dev_log, MODULE_NAME ":%s: "
-				"sdio_write_cmd54 failed for channel %s\n",
-				__func__, ch->name);
-		ch->sdio_al_dev->is_err = true;
-		return ret;
-	}
-
-	return ret;
-}
-
-static int sdio_al_bootloader_completed(void)
-{
-	int i;
-
-	pr_debug(MODULE_NAME ":sdio_al_bootloader_completed was called\n");
-
-	for (i = 0; i < MAX_NUM_OF_SDIO_DEVICES; ++i) {
-		struct sdio_al_device *dev = NULL;
-		if (sdio_al->devices[i] == NULL)
-			continue;
-		dev = sdio_al->devices[i];
-		dev->bootloader_done = 1;
-		wake_up(&dev->wait_mbox);
-	}
-
-	return 0;
-}
-
-static int sdio_al_wait_for_bootloader_comp(struct sdio_al_device *sdio_al_dev)
-{
-	int ret = 0;
-
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	/*
-	 * Enable function 0 interrupt mask to allow 9k to raise this interrupt
-	 * in power-up. When sdio_downloader will notify its completion
-	 * we will poll on this interrupt to wait for 9k power-up
-	 */
-	ret = enable_mask_irq(sdio_al_dev, 0, 1, 0);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": Enable_mask_irq for card %d failed, "
-				"ret=%d\n",
-				sdio_al_dev->host->index, ret);
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-		return ret;
-	}
-
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-
-	/*
-	 * Start bootloader worker that will wait for the bootloader
-	 * completion
-	 */
-	sdio_al_dev->boot_work.sdio_al_dev = sdio_al_dev;
-	INIT_WORK(&sdio_al_dev->boot_work.work, boot_worker);
-	sdio_al_dev->bootloader_done = 0;
-	queue_work(sdio_al_dev->workqueue, &sdio_al_dev->boot_work.work);
-
-	return 0;
-}
-
-static int sdio_al_bootloader_setup(void)
-{
-	int ret = 0;
-	struct sdio_al_device *bootloader_dev = sdio_al->bootloader_dev;
-	struct sdio_func *func1 = NULL;
-
-	if (sdio_al_claim_mutex_and_verify_dev(bootloader_dev, __func__))
-		return -ENODEV;
-
-	if (bootloader_dev->flashless_boot_on) {
-		sdio_al_loge(bootloader_dev->dev_log, MODULE_NAME ":Already "
-			"in boot process.\n");
-		sdio_al_release_mutex(bootloader_dev, __func__);
-		return 0;
-	}
-
-	bootloader_dev->sdioc_boot_sw_header
-		= kzalloc(sizeof(*bootloader_dev->sdioc_boot_sw_header),
-			  GFP_KERNEL);
-	if (bootloader_dev->sdioc_boot_sw_header == NULL) {
-		sdio_al_loge(bootloader_dev->dev_log, MODULE_NAME ":fail to "
-			"allocate sdioc boot sw header.\n");
-		sdio_al_release_mutex(bootloader_dev, __func__);
-		return -ENOMEM;
-	}
-
-	if (sdio_al_verify_func1(bootloader_dev, __func__)) {
-		sdio_al_release_mutex(bootloader_dev, __func__);
-		goto exit_err;
-	}
-	func1 = bootloader_dev->card->sdio_func[0];
-
-	ret = sdio_memcpy_fromio(func1,
-				 bootloader_dev->sdioc_boot_sw_header,
-				 SDIOC_SW_HEADER_ADDR,
-				 sizeof(struct peer_sdioc_boot_sw_header));
-	if (ret) {
-		sdio_al_loge(bootloader_dev->dev_log, MODULE_NAME ":fail to "
-			"read sdioc boot sw header.\n");
-		sdio_al_release_mutex(bootloader_dev, __func__);
-		goto exit_err;
-	}
-
-	if (bootloader_dev->sdioc_boot_sw_header->signature !=
-	    (u32) PEER_SDIOC_SW_MAILBOX_BOOT_SIGNATURE) {
-		sdio_al_loge(bootloader_dev->dev_log, MODULE_NAME ":invalid "
-			"mailbox signature 0x%x.\n",
-			bootloader_dev->sdioc_boot_sw_header->signature);
-		sdio_al_release_mutex(bootloader_dev, __func__);
-		ret = -EINVAL;
-		goto exit_err;
-	}
-
-	/* Upper byte has to be equal - no backward compatibility for unequal */
-	if ((bootloader_dev->sdioc_boot_sw_header->version >> 16) !=
-	    (sdio_al->pdata->peer_sdioc_boot_version_major)) {
-		sdio_al_loge(bootloader_dev->dev_log, MODULE_NAME ": HOST(0x%x)"
-			" and CLIENT(0x%x) SDIO_AL BOOT VERSION don't match\n",
-			((sdio_al->pdata->peer_sdioc_boot_version_major<<16)+
-			sdio_al->pdata->peer_sdioc_boot_version_minor),
-			bootloader_dev->sdioc_boot_sw_header->version);
-		sdio_al_release_mutex(bootloader_dev, __func__);
-		ret = -EIO;
-		goto exit_err;
-	}
-
-	sdio_al_logi(bootloader_dev->dev_log, MODULE_NAME ": SDIOC BOOT SW "
-			"version 0x%x\n",
-			bootloader_dev->sdioc_boot_sw_header->version);
-
-	bootloader_dev->flashless_boot_on = true;
-
-	sdio_al_release_mutex(bootloader_dev, __func__);
-
-	ret = sdio_al_wait_for_bootloader_comp(bootloader_dev);
-	if (ret) {
-		sdio_al_loge(bootloader_dev->dev_log, MODULE_NAME
-				": sdio_al_wait_for_bootloader_comp failed, "
-				"err=%d\n", ret);
-		goto exit_err;
-	}
-
-	ret = sdio_downloader_setup(bootloader_dev->card, 1,
-			bootloader_dev->sdioc_boot_sw_header->boot_ch_num,
-			sdio_al_bootloader_completed);
-
-	if (ret) {
-		sdio_al_loge(bootloader_dev->dev_log, MODULE_NAME
-			": sdio_downloader_setup failed, err=%d\n", ret);
-		goto exit_err;
-	}
-
-	sdio_al_logi(bootloader_dev->dev_log, MODULE_NAME ":In Flashless boot,"
-		" waiting for its completion\n");
-
-
-exit_err:
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ":free "
-			"sdioc_boot_sw_header.\n");
-	kfree(bootloader_dev->sdioc_boot_sw_header);
-	bootloader_dev->sdioc_boot_sw_header = NULL;
-	bootloader_dev = NULL;
-
-	return ret;
-}
-
-
-/**
- *  Read SDIO-Client software header
- *
- */
-static int read_sdioc_software_header(struct sdio_al_device *sdio_al_dev,
-				      struct peer_sdioc_sw_header *header)
-{
-	int ret;
-	int i;
-	int test_version = 0;
-	int sdioc_test_version = 0;
-	struct sdio_func *func1 = NULL;
-
-	pr_debug(MODULE_NAME ":reading sdioc sw header.\n");
-
-	if (sdio_al_verify_func1(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	func1 = sdio_al_dev->card->sdio_func[0];
-
-	ret = sdio_memcpy_fromio(func1, header,
-			SDIOC_SW_HEADER_ADDR, sizeof(*header));
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":fail to read "
-				"sdioc sw header.\n");
-		goto exit_err;
-	}
-
-	if (header->signature == (u32)PEER_SDIOC_SW_MAILBOX_UT_SIGNATURE) {
-		sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":SDIOC SW "
-				"unittest signature. 0x%x\n",
-				header->signature);
-		sdio_al->unittest_mode = true;
-		/* Verify test code compatibility with the modem */
-		sdioc_test_version = (header->version & 0xFF00) >> 8;
-		test_version = sdio_al->pdata->peer_sdioc_version_minor >> 8;
-		if (test_version != sdioc_test_version) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": HOST(0x%x) and CLIENT(0x%x) "
-				"testing VERSION don't match\n",
-				test_version,
-				sdioc_test_version);
-			msleep(500);
-			BUG();
-		}
-	}
-
-	if ((header->signature != (u32) PEER_SDIOC_SW_MAILBOX_SIGNATURE) &&
-	    (header->signature != (u32) PEER_SDIOC_SW_MAILBOX_UT_SIGNATURE)) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":SDIOC SW "
-				"invalid signature. 0x%x\n", header->signature);
-		goto exit_err;
-	}
-	/* Upper byte has to be equal - no backward compatibility for unequal */
-	sdio_al->sdioc_major = header->version >> 16;
-	if (sdio_al->pdata->allow_sdioc_version_major_2) {
-		if ((sdio_al->sdioc_major !=
-		    sdio_al->pdata->peer_sdioc_version_major) &&
-		    (sdio_al->sdioc_major != PEER_SDIOC_OLD_VERSION_MAJOR)) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": HOST(0x%x) and CLIENT(0x%x) "
-				"SDIO_AL VERSION don't match\n",
-				((sdio_al->pdata->peer_sdioc_version_major<<16)+
-				sdio_al->pdata->peer_sdioc_version_minor),
-				header->version);
-			goto exit_err;
-		}
-	} else {
-		if (sdio_al->sdioc_major !=
-		    sdio_al->pdata->peer_sdioc_version_major) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": HOST(0x%x) and CLIENT(0x%x) "
-				"SDIO_AL VERSION don't match\n",
-				((sdio_al->pdata->peer_sdioc_version_major<<16)+
-				sdio_al->pdata->peer_sdioc_version_minor),
-				header->version);
-			goto exit_err;
-		}
-	}
-	sdio_al_dev->ch_close_supported = (header->version & 0x000F) >=
-		(sdio_al->pdata->peer_sdioc_version_minor & 0xF);
-
-	sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":SDIOC SW version 0x%x,"
-			" sdio_al major 0x%x minor 0x%x\n", header->version,
-			sdio_al->sdioc_major,
-			sdio_al->pdata->peer_sdioc_version_minor);
-
-	sdio_al_dev->flashless_boot_on = false;
-	for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++) {
-		struct sdio_channel *ch = &sdio_al_dev->channel[i];
-
-		/* Set default values */
-		ch->read_threshold  = DEFAULT_READ_THRESHOLD;
-		ch->write_threshold = DEFAULT_WRITE_THRESHOLD;
-		ch->min_write_avail = DEFAULT_MIN_WRITE_THRESHOLD;
-		ch->is_packet_mode = true;
-		ch->peer_tx_buf_size = DEFAULT_PEER_TX_BUF_SIZE;
-		ch->poll_delay_msec = 0;
-
-		ch->num = i;
-		ch->func = NULL;
-		ch->rx_pipe_index = ch->num*2;
-		ch->tx_pipe_index = ch->num*2+1;
-
-		memset(ch->name, 0, sizeof(ch->name));
-
-		if (header->channel_names[i][0]) {
-			memcpy(ch->name, SDIO_PREFIX,
-			       strlen(SDIO_PREFIX));
-			memcpy(ch->name + strlen(SDIO_PREFIX),
-			       header->channel_names[i],
-			       PEER_CHANNEL_NAME_SIZE);
-
-			ch->state = SDIO_CHANNEL_STATE_IDLE;
-			ch->sdio_al_dev = sdio_al_dev;
-			if (sdio_al_dev->card->sdio_func[ch->num+1]) {
-				ch->func =
-				sdio_al_dev->card->sdio_func[ch->num+1];
-			} else {
-				sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					": NULL func for channel %s\n",
-					ch->name);
-				goto exit_err;
-			}
-		} else {
-			ch->state = SDIO_CHANNEL_STATE_INVALID;
-		}
-
-		sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":Channel=%s, "
-				"state=%d\n", ch->name,	ch->state);
-	}
-
-	return 0;
-
-exit_err:
-	sdio_al_get_into_err_state(sdio_al_dev);
-	memset(header, 0, sizeof(*header));
-
-	return -EIO;
-}
-
-/**
- *  Read SDIO-Client channel configuration
- *
- */
-static int read_sdioc_channel_config(struct sdio_channel *ch)
-{
-	int ret;
-	struct peer_sdioc_sw_mailbox *sw_mailbox = NULL;
-	struct peer_sdioc_channel_config *ch_config = NULL;
-	struct sdio_al_device *sdio_al_dev = ch->sdio_al_dev;
-
-	if (sdio_al_dev == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": NULL sdio_al_dev"
-				" for channel %s\n", ch->name);
-		return -EINVAL;
-	}
-
-	if (sdio_al_dev->sdioc_sw_header->version == 0)
-		return -1;
-
-	pr_debug(MODULE_NAME ":reading sw mailbox %s channel.\n", ch->name);
-
-	sw_mailbox = kzalloc(sizeof(*sw_mailbox), GFP_KERNEL);
-	if (sw_mailbox == NULL)
-		return -ENOMEM;
-
-	ret = sdio_memcpy_fromio(ch->func, sw_mailbox,
-			SDIOC_SW_MAILBOX_ADDR, sizeof(*sw_mailbox));
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":fail to read "
-				"sw mailbox.\n");
-		goto exit_err;
-	}
-
-	ch_config = &sw_mailbox->ch_config[ch->num];
-	memcpy(&ch->ch_config, ch_config,
-		sizeof(struct peer_sdioc_channel_config));
-
-	if (!ch_config->is_ready) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":sw mailbox "
-				"channel not ready.\n");
-		goto exit_err;
-	}
-
-	ch->read_threshold = LOW_LATENCY_THRESHOLD;
-	ch->is_low_latency_ch = ch_config->is_low_latency_ch;
-	/* Threshold on 50% of the maximum size , sdioc uses double-buffer */
-	ch->write_threshold = (ch_config->max_tx_threshold * 5) / 10;
-	ch->threshold_change_cnt = ch->ch_config.max_rx_threshold -
-			ch->read_threshold + THRESHOLD_CHANGE_EXTRA_BYTES;
-
-	if (ch->is_low_latency_ch)
-		ch->def_read_threshold = LOW_LATENCY_THRESHOLD;
-	else /* Aggregation up to 90% of the maximum size */
-		ch->def_read_threshold = (ch_config->max_rx_threshold * 9) / 10;
-
-	ch->is_packet_mode = ch_config->is_packet_mode;
-	if (!ch->is_packet_mode) {
-		ch->poll_delay_msec = DEFAULT_POLL_DELAY_NOPACKET_MSEC;
-		ch->min_write_avail = DEFAULT_MIN_WRITE_THRESHOLD_STREAMING;
-	}
-	/* The max_packet_size is set by the modem in version 3 and on */
-	if (sdio_al->sdioc_major > PEER_SDIOC_OLD_VERSION_MAJOR)
-		ch->min_write_avail = ch_config->max_packet_size;
-
-	if (ch->min_write_avail > ch->write_threshold)
-		ch->min_write_avail = ch->write_threshold;
-
-	CLOSE_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":ch %s "
-			"read_threshold=%d, write_threshold=%d,"
-			" min_write_avail=%d, max_rx_threshold=%d,"
-			" max_tx_threshold=%d\n", ch->name, ch->read_threshold,
-			ch->write_threshold, ch->min_write_avail,
-			ch_config->max_rx_threshold,
-			ch_config->max_tx_threshold);
-
-	ch->peer_tx_buf_size = ch_config->tx_buf_size;
-
-	kfree(sw_mailbox);
-
-	return 0;
-
-exit_err:
-	sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":Reading SW Mailbox "
-			"error.\n");
-	kfree(sw_mailbox);
-
-	return -1;
-}
-
-
-/**
- *  Enable/Disable EOT interrupt of a pipe.
- *
- */
-static int enable_eot_interrupt(struct sdio_al_device *sdio_al_dev,
-				int pipe_index, int enable)
-{
-	int ret = 0;
-	struct sdio_func *func1;
-	u32 mask;
-	u32 pipe_mask;
-	u32 addr;
-
-	if (sdio_al_verify_func1(sdio_al_dev, __func__))
-		return -ENODEV;
-	func1 = sdio_al_dev->card->sdio_func[0];
-
-	if (pipe_index < 8) {
-		addr = PIPES_0_7_IRQ_MASK_ADDR;
-		pipe_mask = (1<<pipe_index);
-	} else {
-		addr = PIPES_8_15_IRQ_MASK_ADDR;
-		pipe_mask = (1<<(pipe_index-8));
-	}
-
-	mask = sdio_readl(func1, addr, &ret);
-	if (ret) {
-		pr_debug(MODULE_NAME ":enable_eot_interrupt fail\n");
-		goto exit_err;
-	}
-
-	if (enable)
-		mask &= (~pipe_mask); /* 0 = enable */
-	else
-		mask |= (pipe_mask);  /* 1 = disable */
-
-	sdio_writel(func1, mask, addr, &ret);
-
-exit_err:
-	return ret;
-}
-
-
-/**
- *  Enable/Disable mask interrupt of a function.
- *
- */
-static int enable_mask_irq(struct sdio_al_device *sdio_al_dev,
-			   int func_num, int enable, u8 bit_offset)
-{
-	int ret = 0;
-	struct sdio_func *func1 = NULL;
-	u32 mask = 0;
-	u32 func_mask = 0;
-	u32 addr = 0;
-	u32 offset = 0;
-
-	if (sdio_al_verify_func1(sdio_al_dev, __func__))
-		return -ENODEV;
-	func1 = sdio_al_dev->card->sdio_func[0];
-
-	if (func_num < 4) {
-		addr = FUNC_1_4_MASK_IRQ_ADDR;
-		offset = func_num * 8 + bit_offset;
-	} else {
-		addr = FUNC_5_7_MASK_IRQ_ADDR;
-		offset = (func_num - 4) * 8 + bit_offset;
-	}
-
-	func_mask = 1<<offset;
-
-	mask = sdio_readl(func1, addr, &ret);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": "
-				"enable_mask_irq fail\n");
-		goto exit_err;
-	}
-
-	if (enable)
-		mask &= (~func_mask); /* 0 = enable */
-	else
-		mask |= (func_mask);  /* 1 = disable */
-
-	pr_debug(MODULE_NAME ":enable_mask_irq,  writing mask = 0x%x\n", mask);
-
-	sdio_writel(func1, mask, addr, &ret);
-
-exit_err:
-	return ret;
-}
-
-/**
- *  Enable/Disable Threshold interrupt of a pipe.
- *
- */
-static int enable_threshold_interrupt(struct sdio_al_device *sdio_al_dev,
-				      int pipe_index, int enable)
-{
-	int ret = 0;
-	struct sdio_func *func1;
-	u32 mask;
-	u32 pipe_mask;
-	u32 addr;
-
-	if (sdio_al_verify_func1(sdio_al_dev, __func__))
-		return -ENODEV;
-	func1 = sdio_al_dev->card->sdio_func[0];
-
-	if (pipe_index < 8) {
-		addr = PIPES_0_7_IRQ_MASK_ADDR;
-		pipe_mask = (1<<pipe_index);
-	} else {
-		addr = PIPES_8_15_IRQ_MASK_ADDR;
-		pipe_mask = (1<<(pipe_index-8));
-	}
-
-	mask = sdio_readl(func1, addr, &ret);
-	if (ret) {
-		pr_debug(MODULE_NAME ":enable_threshold_interrupt fail\n");
-		goto exit_err;
-	}
-
-	pipe_mask = pipe_mask<<8; /* Threshold bits 8..15 */
-	if (enable)
-		mask &= (~pipe_mask); /* 0 = enable */
-	else
-		mask |= (pipe_mask);  /* 1 = disable */
-
-	sdio_writel(func1, mask, addr, &ret);
-
-exit_err:
-	return ret;
-}
-
-/**
- *  Set the threshold to trigger interrupt from SDIO-Card on
- *  pipe available bytes.
- *
- */
-static int set_pipe_threshold(struct sdio_al_device *sdio_al_dev,
-			      int pipe_index, int threshold)
-{
-	int ret = 0;
-	struct sdio_func *func1;
-
-	if (sdio_al_verify_func1(sdio_al_dev, __func__))
-		return -ENODEV;
-	func1 = sdio_al_dev->card->sdio_func[0];
-
-	sdio_writel(func1, threshold,
-			PIPES_THRESHOLD_ADDR+pipe_index*4, &ret);
-	if (ret)
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": "
-				"set_pipe_threshold err=%d\n", -ret);
-
-	return ret;
-}
-
-/**
- *  Enable func w/ retries
- *
- */
-static int sdio_al_enable_func_retry(struct sdio_func *func, const char *name)
-{
-	int ret, i;
-	for (i = 0; i < 200; i++) {
-		ret = sdio_enable_func(func);
-		if (ret) {
-			pr_debug(MODULE_NAME ":retry enable %s func#%d "
-					     "ret=%d\n",
-					 name, func->num, ret);
-			msleep(10);
-		} else
-			break;
-	}
-
-	return ret;
-}
-
-/**
- *  Open Channel
- *
- *  1. Init Channel Context.
- *  2. Init the Channel SDIO-Function.
- *  3. Init the Channel Pipes on Mailbox.
- */
-static int open_channel(struct sdio_channel *ch)
-{
-	int ret = 0;
-	struct sdio_al_device *sdio_al_dev = ch->sdio_al_dev;
-
-	if (sdio_al_dev == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": NULL "
-				"sdio_al_dev for channel %s\n", ch->name);
-		return -EINVAL;
-	}
-
-	/* Init channel Context */
-	/** Func#1 is reserved for mailbox */
-	ch->func = sdio_al_dev->card->sdio_func[ch->num+1];
-	ch->rx_pipe_index = ch->num*2;
-	ch->tx_pipe_index = ch->num*2+1;
-	ch->signature = SDIO_AL_SIGNATURE;
-
-	ch->total_rx_bytes = 0;
-	ch->total_tx_bytes = 0;
-
-	ch->write_avail = 0;
-	ch->read_avail = 0;
-	ch->rx_pending_bytes = 0;
-
-	mutex_init(&ch->ch_lock);
-
-	pr_debug(MODULE_NAME ":open_channel %s func#%d\n",
-			 ch->name, ch->func->num);
-
-	INIT_LIST_HEAD(&(ch->rx_size_list_head));
-
-	/* Init SDIO Function */
-	ret = sdio_al_enable_func_retry(ch->func, ch->name);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": "
-				"sdio_enable_func() err=%d\n", -ret);
-		goto exit_err;
-	}
-
-	/* Note: Patch Func CIS tuple issue */
-	ret = sdio_set_block_size(ch->func, SDIO_AL_BLOCK_SIZE);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": "
-				"sdio_set_block_size()failed, err=%d\n", -ret);
-		goto exit_err;
-	}
-
-	ch->func->max_blksize = SDIO_AL_BLOCK_SIZE;
-
-	sdio_set_drvdata(ch->func, ch);
-
-	/* Get channel parameters from the peer SDIO-Client */
-	read_sdioc_channel_config(ch);
-
-	/* Set Pipes Threshold on Mailbox */
-	ret = set_pipe_threshold(sdio_al_dev,
-				 ch->rx_pipe_index, ch->read_threshold);
-	if (ret)
-		goto exit_err;
-	ret = set_pipe_threshold(sdio_al_dev,
-				 ch->tx_pipe_index, ch->write_threshold);
-	if (ret)
-		goto exit_err;
-
-	/* Set flag before interrupts are enabled to allow notify */
-	ch->state = SDIO_CHANNEL_STATE_OPEN;
-	pr_debug(MODULE_NAME ":channel %s is in OPEN state now\n", ch->name);
-
-	sdio_al_dev->poll_delay_msec = get_min_poll_time_msec(sdio_al_dev);
-
-	/* lpm mechanism lives under the assumption there is always a timer */
-	/* Check if need to start the timer */
-	if  ((sdio_al_dev->poll_delay_msec) &&
-	     (sdio_al_dev->is_timer_initialized == false)) {
-
-		init_timer(&sdio_al_dev->timer);
-		sdio_al_dev->timer.data = (unsigned long) sdio_al_dev;
-		sdio_al_dev->timer.function = sdio_al_timer_handler;
-		sdio_al_dev->timer.expires = jiffies +
-			msecs_to_jiffies(sdio_al_dev->poll_delay_msec);
-		add_timer(&sdio_al_dev->timer);
-		sdio_al_dev->is_timer_initialized = true;
-	}
-
-	/* Enable Pipes Interrupts */
-	enable_eot_interrupt(sdio_al_dev, ch->rx_pipe_index, true);
-	enable_eot_interrupt(sdio_al_dev, ch->tx_pipe_index, true);
-
-	enable_threshold_interrupt(sdio_al_dev, ch->rx_pipe_index, true);
-	enable_threshold_interrupt(sdio_al_dev, ch->tx_pipe_index, true);
-
-exit_err:
-
-	return ret;
-}
-
-/**
- *  Ask the worker to read the mailbox.
- */
-static void ask_reading_mailbox(struct sdio_al_device *sdio_al_dev)
-{
-	if (!sdio_al_dev->ask_mbox) {
-		pr_debug(MODULE_NAME ":ask_reading_mailbox for card %d\n",
-			 sdio_al_dev->host->index);
-		sdio_al_dev->ask_mbox = true;
-		wake_up(&sdio_al_dev->wait_mbox);
-	}
-}
-
-/**
- *  Start the timer
- */
-static void start_timer(struct sdio_al_device *sdio_al_dev)
-{
-	if ((sdio_al_dev->poll_delay_msec)  &&
-		(sdio_al_dev->state == CARD_INSERTED)) {
-		sdio_al_dev->timer.expires = jiffies +
-			msecs_to_jiffies(sdio_al_dev->poll_delay_msec);
-		add_timer(&sdio_al_dev->timer);
-	}
-}
-
-/**
- *  Restart(postpone) the already working timer
- */
-static void restart_timer(struct sdio_al_device *sdio_al_dev)
-{
-	if ((sdio_al_dev->poll_delay_msec) &&
-		(sdio_al_dev->state == CARD_INSERTED)) {
-		ulong expires =	jiffies +
-			msecs_to_jiffies(sdio_al_dev->poll_delay_msec);
-		mod_timer(&sdio_al_dev->timer, expires);
-	}
-}
-
-/**
- *  Stop and delete the timer
- */
-static void stop_and_del_timer(struct sdio_al_device *sdio_al_dev)
-{
-	if (sdio_al_dev->is_timer_initialized) {
-		sdio_al_dev->poll_delay_msec = 0;
-		del_timer_sync(&sdio_al_dev->timer);
-	}
-}
-
-/**
- *  Do the wakup sequence.
- *  This function should be called after claiming the host!
- *  The caller is responsible for releasing the host.
- *
- *  Wake up sequence
- *  1. Get lock
- *  2. Enable wake up function if needed
- *  3. Mark NOT OK to sleep and write it
- *  4. Restore default thresholds
- *  5. Start the mailbox and inactivity timer again
- */
-static int sdio_al_wake_up(struct sdio_al_device *sdio_al_dev,
-			   u32 not_from_int, struct sdio_channel *ch)
-{
-	int ret = 0;
-	struct sdio_func *wk_func = NULL;
-	unsigned long time_to_wait;
-	struct mmc_host *host = sdio_al_dev->host;
-
-	if (sdio_al_dev->is_err) {
-		SDIO_AL_ERR(__func__);
-		return -ENODEV;
-	}
-
-	if (!sdio_al_dev->is_ok_to_sleep) {
-		LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":card %d "
-				"already awake, no need to wake up\n",
-				sdio_al_dev->host->index);
-		return 0;
-	}
-
-	/* Wake up sequence */
-	if (not_from_int) {
-		if (ch) {
-			LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ": Wake up"
-					" card %d (not by interrupt), ch %s",
-					sdio_al_dev->host->index,
-					ch->name);
-		} else {
-			LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ": Wake up"
-					  " card %d (not	by interrupt)",
-					  sdio_al_dev->host->index);
-		}
-	} else {
-		LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ": Wake up card "
-				"%d by interrupt",
-				sdio_al_dev->host->index);
-		sdio_al_dev->print_after_interrupt = 1;
-	}
-
-	sdio_al_vote_for_sleep(sdio_al_dev, 0);
-
-	msmsdcc_lpm_disable(host);
-	msmsdcc_set_pwrsave(host, 0);
-	/* Poll the GPIO */
-	time_to_wait = jiffies + msecs_to_jiffies(1000);
-	while (time_before(jiffies, time_to_wait)) {
-		if (sdio_al->pdata->get_mdm2ap_status())
-			break;
-		udelay(TIME_TO_WAIT_US);
-	}
-
-	pr_debug(MODULE_NAME ":GPIO mdm2ap_status=%d\n",
-		       sdio_al->pdata->get_mdm2ap_status());
-
-	/* Here get_mdm2ap_status() returning 0 is not an error condition */
-	if (sdio_al->pdata->get_mdm2ap_status() == 0)
-		LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ": "
-				"get_mdm2ap_status() is 0\n");
-
-	/* Enable Wake up Function */
-	if (!sdio_al_dev->card ||
-	    !sdio_al_dev->card->sdio_func[SDIO_AL_WAKEUP_FUNC-1]) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": NULL card or wk_func\n");
-		return -ENODEV;
-	}
-	wk_func = sdio_al_dev->card->sdio_func[SDIO_AL_WAKEUP_FUNC-1];
-	ret = sdio_al_enable_func_retry(wk_func, "wakeup func");
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": "
-				"sdio_enable_func() err=%d\n", -ret);
-		goto error_exit;
-	}
-	/* Mark NOT OK_TOSLEEP */
-	sdio_al_dev->is_ok_to_sleep = 0;
-	ret = write_lpm_info(sdio_al_dev);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": "
-				"write_lpm_info() failed, err=%d\n", -ret);
-		sdio_al_dev->is_ok_to_sleep = 1;
-		sdio_disable_func(wk_func);
-		goto error_exit;
-	}
-	sdio_disable_func(wk_func);
-
-	/* Start the timer again*/
-	restart_inactive_time(sdio_al_dev);
-	sdio_al_dev->poll_delay_msec = get_min_poll_time_msec(sdio_al_dev);
-	start_timer(sdio_al_dev);
-
-	LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME "Finished Wake up sequence"
-			" for card %d", sdio_al_dev->host->index);
-
-	msmsdcc_set_pwrsave(host, 1);
-	pr_debug(MODULE_NAME ":Turn clock off\n");
-
-	return ret;
-error_exit:
-	sdio_al_vote_for_sleep(sdio_al_dev, 1);
-	msmsdcc_set_pwrsave(host, 1);
-	WARN_ON(ret);
-	sdio_al_get_into_err_state(sdio_al_dev);
-	return ret;
-}
-
-
-/**
- *  SDIO Function Interrupt handler.
- *
- *  Interrupt shall be triggered by SDIO-Client when:
- *  1. End-Of-Transfer (EOT) detected in packet mode.
- *  2. Bytes-available reached the threshold.
- *
- *  Reading the mailbox clears the EOT/Threshold interrupt
- *  source.
- *  The interrupt source should be cleared before this ISR
- *  returns. This ISR is called from IRQ Thread and not
- *  interrupt, so it may sleep.
- *
- */
-static void sdio_func_irq(struct sdio_func *func)
-{
-	struct sdio_al_device *sdio_al_dev = sdio_get_drvdata(func);
-
-	pr_debug(MODULE_NAME ":start %s.\n", __func__);
-
-	if (sdio_al_dev == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": NULL device");
-		return;
-	}
-
-	if (sdio_al_dev->is_ok_to_sleep)
-		sdio_al_wake_up(sdio_al_dev, 0, NULL);
-	else
-		restart_timer(sdio_al_dev);
-
-	read_mailbox(sdio_al_dev, true);
-
-	pr_debug(MODULE_NAME ":end %s.\n", __func__);
-}
-
-/**
- *  Timer Expire Handler
- *
- */
-static void sdio_al_timer_handler(unsigned long data)
-{
-	struct sdio_al_device *sdio_al_dev = (struct sdio_al_device *)data;
-	if (sdio_al_dev == NULL) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": NULL "
-				"sdio_al_dev for data %lu\n", data);
-		return;
-	}
-	if (sdio_al_dev->state != CARD_INSERTED) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": sdio_al_dev "
-				"is in invalid state %d\n", sdio_al_dev->state);
-		return;
-	}
-	pr_debug(MODULE_NAME " Timer Expired\n");
-
-	ask_reading_mailbox(sdio_al_dev);
-
-	restart_timer(sdio_al_dev);
-}
-
-/**
- *  Driver Setup.
- *
- */
-static int sdio_al_setup(struct sdio_al_device *sdio_al_dev)
-{
-	int ret = 0;
-	struct mmc_card *card = sdio_al_dev->card;
-	struct sdio_func *func1 = NULL;
-	int i = 0;
-	int fn = 0;
-
-	if (sdio_al_verify_func1(sdio_al_dev, __func__))
-		return -ENODEV;
-	func1 = card->sdio_func[0];
-
-	sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":sdio_al_setup for "
-			"card %d\n", sdio_al_dev->host->index);
-
-	ret = sdio_al->pdata->config_mdm2ap_status(1);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME "Could not "
-				"request GPIO\n");
-		return ret;
-	}
-
-	INIT_WORK(&sdio_al_dev->sdio_al_work.work, worker);
-	/* disable all pipes interrupts before claim irq.
-	   since all are enabled by default. */
-	for (i = 0 ; i < SDIO_AL_MAX_PIPES; i++) {
-		enable_eot_interrupt(sdio_al_dev, i, false);
-		enable_threshold_interrupt(sdio_al_dev, i, false);
-	}
-
-	/* Disable all SDIO Functions before claim irq. */
-	for (fn = 1 ; fn <= card->sdio_funcs; fn++)
-		sdio_disable_func(card->sdio_func[fn-1]);
-
-	sdio_set_drvdata(func1, sdio_al_dev);
-	sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":claim IRQ for card "
-			"%d\n",	sdio_al_dev->host->index);
-
-	ret = sdio_claim_irq(func1, sdio_func_irq);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Fail to claim"
-				" IRQ for card %d\n",
-				sdio_al_dev->host->index);
-		return ret;
-	}
-
-	sdio_al_dev->is_ready = true;
-
-	/* Start worker before interrupt might happen */
-	queue_work(sdio_al_dev->workqueue, &sdio_al_dev->sdio_al_work.work);
-
-	start_inactive_time(sdio_al_dev);
-
-	pr_debug(MODULE_NAME ":Ready.\n");
-
-	return 0;
-}
-
-/**
- *  Driver Tear-Down.
- *
- */
-static void sdio_al_tear_down(void)
-{
-	int i, j;
-	struct sdio_al_device *sdio_al_dev = NULL;
-	struct sdio_func *func1;
-
-	for (i = 0; i < MAX_NUM_OF_SDIO_DEVICES; ++i) {
-		if (sdio_al->devices[i] == NULL)
-			continue;
-		sdio_al_dev = sdio_al->devices[i];
-
-		if (sdio_al_dev->is_ready) {
-			sdio_al_dev->is_ready = false; /* Flag worker to exit */
-			sdio_al_dev->ask_mbox = false;
-			ask_reading_mailbox(sdio_al_dev); /* Wakeup worker */
-			/* allow gracefully exit of the worker thread */
-			msleep(100);
-
-			flush_workqueue(sdio_al_dev->workqueue);
-			destroy_workqueue(sdio_al_dev->workqueue);
-
-			sdio_al_vote_for_sleep(sdio_al_dev, 1);
-
-			if (!sdio_al_claim_mutex_and_verify_dev(sdio_al_dev,
-								__func__)) {
-				if (!sdio_al_dev->card ||
-				    !sdio_al_dev->card->sdio_func[0]) {
-					sdio_al_loge(sdio_al_dev->dev_log,
-						     MODULE_NAME
-							": %s: Invalid func1",
-							__func__);
-					return;
-				}
-				func1 = sdio_al_dev->card->sdio_func[0];
-				sdio_release_irq(func1);
-				sdio_disable_func(func1);
-				sdio_al_release_mutex(sdio_al_dev, __func__);
-			}
-		}
-
-		for (j = 0; j < SDIO_AL_MAX_CHANNELS; j++)
-			sdio_al_dev->channel[j].signature = 0x0;
-		sdio_al_dev->signature = 0;
-
-		kfree(sdio_al_dev->sdioc_sw_header);
-		kfree(sdio_al_dev->mailbox);
-		kfree(sdio_al_dev->rx_flush_buf);
-		kfree(sdio_al_dev);
-	}
-
-	sdio_al->pdata->config_mdm2ap_status(0);
-}
-
-/**
- *  Find channel by name.
- *
- */
-static struct sdio_channel *find_channel_by_name(const char *name)
-{
-	struct sdio_channel *ch = NULL;
-	int i, j;
-	struct sdio_al_device *sdio_al_dev = NULL;
-
-	for (j = 0; j < MAX_NUM_OF_SDIO_DEVICES; ++j) {
-		if (sdio_al->devices[j] == NULL)
-			continue;
-		sdio_al_dev = sdio_al->devices[j];
-		for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++) {
-			if (sdio_al_dev->channel[i].state ==
-					SDIO_CHANNEL_STATE_INVALID)
-				continue;
-			if (strncmp(sdio_al_dev->channel[i].name, name,
-					CHANNEL_NAME_SIZE) == 0) {
-				ch = &sdio_al_dev->channel[i];
-				break;
-			}
-		}
-		if (ch != NULL)
-			break;
-	}
-
-	return ch;
-}
-
-/**
- *  Find the minimal poll time.
- *
- */
-static int get_min_poll_time_msec(struct sdio_al_device *sdio_sl_dev)
-{
-	int i;
-	int poll_delay_msec = 0x0FFFFFFF;
-
-	for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++)
-		if ((sdio_sl_dev->channel[i].state ==
-					SDIO_CHANNEL_STATE_OPEN) &&
-		(sdio_sl_dev->channel[i].poll_delay_msec > 0) &&
-		(sdio_sl_dev->channel[i].poll_delay_msec < poll_delay_msec))
-			poll_delay_msec =
-				sdio_sl_dev->channel[i].poll_delay_msec;
-
-	if (poll_delay_msec == 0x0FFFFFFF)
-		poll_delay_msec = SDIO_AL_POLL_TIME_NO_STREAMING;
-
-	pr_debug(MODULE_NAME ":poll delay time is %d msec\n", poll_delay_msec);
-
-	return poll_delay_msec;
-}
-
-/**
- *  Open SDIO Channel.
- *
- *  Enable the channel.
- *  Set the channel context.
- *  Trigger reading the mailbox to check available bytes.
- *
- */
-int sdio_open(const char *name, struct sdio_channel **ret_ch, void *priv,
-		 void (*notify)(void *priv, unsigned ch_event))
-{
-	int ret = 0;
-	struct sdio_channel *ch = NULL;
-	struct sdio_al_device *sdio_al_dev = NULL;
-
-	*ret_ch = NULL; /* default */
-
-	ch = find_channel_by_name(name);
-	if (ch == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":Can't find "
-			"channel name %s\n", name);
-		return -EINVAL;
-	}
-
-	sdio_al_dev = ch->sdio_al_dev;
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	if ((ch->state != SDIO_CHANNEL_STATE_IDLE) &&
-		(ch->state != SDIO_CHANNEL_STATE_CLOSED)) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Wrong ch %s "
-				"state %d\n", name, ch->state);
-		ret = -EPERM;
-		goto exit_err;
-	}
-
-	if (sdio_al_dev->is_err) {
-		SDIO_AL_ERR(__func__);
-		ret = -ENODEV;
-		goto exit_err;
-	}
-
-	ret = sdio_al_wake_up(sdio_al_dev, 1, ch);
-	if (ret)
-		goto exit_err;
-
-	ch->notify = notify;
-	ch->priv = priv;
-
-	/* Note: Set caller returned context before interrupts are enabled */
-	*ret_ch = ch;
-
-	ret = open_channel(ch);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":sdio_open %s "
-				"err=%d\n", name, -ret);
-		goto exit_err;
-	}
-
-	CLOSE_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":sdio_open %s "
-							"completed OK\n", name);
-	if (sdio_al_dev->lpm_chan == INVALID_SDIO_CHAN) {
-		if (sdio_al->sdioc_major == PEER_SDIOC_OLD_VERSION_MAJOR) {
-			if (!ch->is_packet_mode) {
-				sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME
-						":setting channel %s as "
-						"lpm_chan\n", name);
-				sdio_al_dev->lpm_chan = ch->num;
-			}
-		} else {
-			sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ": "
-					"setting channel %s as lpm_chan\n",
-					name);
-			sdio_al_dev->lpm_chan = ch->num;
-		}
-	}
-
-exit_err:
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-	return ret;
-}
-EXPORT_SYMBOL(sdio_open);
-
-/**
- *  Request peer operation
- *  note: sanity checks of parameters done by caller
- *        called under bus locked
- */
-static int peer_set_operation(u32 opcode,
-		struct sdio_al_device *sdio_al_dev,
-		struct sdio_channel *ch)
-{
-	int ret;
-	int offset;
-	struct sdio_func *wk_func = NULL;
-	u32 peer_operation;
-	int loop_count = 0;
-
-	if (!sdio_al_dev->card ||
-	    !sdio_al_dev->card->sdio_func[SDIO_AL_WAKEUP_FUNC-1]) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": NULL card or wk_func\n");
-		ret = -ENODEV;
-		goto exit;
-	}
-	wk_func = sdio_al_dev->card->sdio_func[SDIO_AL_WAKEUP_FUNC-1];
-
-	/* calculate offset of peer_operation field in sw mailbox struct */
-	offset = offsetof(struct peer_sdioc_sw_mailbox, ch_config) +
-		sizeof(struct peer_sdioc_channel_config) * ch->num +
-		offsetof(struct peer_sdioc_channel_config, peer_operation);
-
-	ret = sdio_al_wake_up(sdio_al_dev, 1, ch);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Fail to "
-				"wake up\n");
-		goto exit;
-	}
-	/* request operation from MDM peer */
-	peer_operation = PEER_OPERATION(opcode, PEER_OP_STATE_INIT);
-	ret = sdio_memcpy_toio(ch->func, SDIOC_SW_MAILBOX_ADDR+offset,
-			&peer_operation, sizeof(u32));
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":failed to "
-				"request close operation\n");
-		goto exit;
-	}
-	ret = sdio_al_enable_func_retry(wk_func, "wk_func");
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Fail to enable"
-				" Func#%d\n", wk_func->num);
-		goto exit;
-	}
-	pr_debug(MODULE_NAME ":%s: wk_func enabled on ch %s\n",
-			__func__, ch->name);
-	/* send "start" operation to MDM */
-	peer_operation = PEER_OPERATION(opcode, PEER_OP_STATE_START);
-	ret  =  sdio_memcpy_toio(ch->func, SDIOC_SW_MAILBOX_ADDR+offset,
-			&peer_operation, sizeof(u32));
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":failed to "
-				"send start close operation\n");
-		goto exit;
-	}
-	ret = sdio_disable_func(wk_func);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Fail to "
-				"disable Func#%d\n", wk_func->num);
-		goto exit;
-	}
-	/* poll for peer operation ack */
-	while (peer_operation != 0) {
-		ret  =  sdio_memcpy_fromio(ch->func,
-				&peer_operation,
-				SDIOC_SW_MAILBOX_ADDR+offset,
-				sizeof(u32));
-		if (ret) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					":failed to request ack on close"
-					" operation, loop_count = %d\n",
-					loop_count);
-			goto exit;
-		}
-		loop_count++;
-		if (loop_count > 10) {
-			sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":%s: "
-					"peer_operation=0x%x wait loop"
-					" %d on ch %s\n", __func__,
-					peer_operation, loop_count, ch->name);
-		}
-	}
-exit:
-	return ret;
-}
-
-static int channel_close(struct sdio_channel *ch, int flush_flag)
-{
-	int ret;
-	struct sdio_al_device *sdio_al_dev = NULL;
-	int flush_len;
-	ulong flush_expires;
-
-	if (!ch) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: NULL "
-				"channel\n",  __func__);
-		return -ENODEV;
-	}
-
-	if (!ch->func) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":%s: NULL func"
-				" on channel:%d\n", __func__, ch->num);
-		return -ENODEV;
-	}
-
-	sdio_al_dev = ch->sdio_al_dev;
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	if (!sdio_al_dev->ch_close_supported) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":%s: Not "
-			"supported by mdm, ch %s\n",
-			__func__, ch->name);
-		ret = -ENOTSUPP;
-		goto error_exit;
-	}
-
-	if (sdio_al_dev->is_err) {
-		SDIO_AL_ERR(__func__);
-		ret = -ENODEV;
-		goto error_exit;
-	}
-	if (ch->state != SDIO_CHANNEL_STATE_OPEN) {
-		sdio_al_loge(sdio_al_dev->dev_log,
-				MODULE_NAME ":%s: ch %s is not in "
-				"open state (%d)\n",
-				__func__, ch->name, ch->state);
-		ret = -ENODEV;
-		goto error_exit;
-	}
-	ch->state = SDIO_CHANNEL_STATE_CLOSING;
-	ret = peer_set_operation(PEER_OP_CODE_CLOSE, sdio_al_dev, ch);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":%s: "
-				"peer_set_operation() failed: %d\n",
-				__func__, ret);
-		ret = -ENODEV;
-		goto error_exit;
-	}
-	/* udate poll time for opened channels */
-	if  (ch->poll_delay_msec > 0) {
-		sdio_al_dev->poll_delay_msec =
-			get_min_poll_time_msec(sdio_al_dev);
-	}
-	sdio_al_release_mutex(ch->sdio_al_dev, __func__);
-
-	flush_expires = jiffies +
-		msecs_to_jiffies(SDIO_CLOSE_FLUSH_TIMEOUT_MSEC);
-	/* flush rx packets of the channel */
-	if (flush_flag) {
-		do {
-			while (ch->read_avail > 0) {
-				flush_len = ch->read_avail;
-				ret = sdio_read_internal(ch,
-						sdio_al_dev->rx_flush_buf,
-						flush_len);
-				if (ret) {
-					sdio_al_loge(&sdio_al->gen_log,
-						MODULE_NAME ":%s sdio_read"
-						" failed: %d, ch %s\n",
-						__func__, ret,
-						ch->name);
-					return ret;
-				}
-
-				if (time_after(jiffies, flush_expires) != 0) {
-					sdio_al_loge(&sdio_al->gen_log,
-						MODULE_NAME ":%s flush rx "
-						"packets timeout: ch %s\n",
-						__func__, ch->name);
-					sdio_al_get_into_err_state(sdio_al_dev);
-					return -EBUSY;
-				}
-			}
-			msleep(100);
-			if (ch->signature != SDIO_AL_SIGNATURE) {
-					sdio_al_loge(&sdio_al->gen_log,
-						MODULE_NAME ":%s: after sleep,"
-						" invalid signature"
-						" 0x%x\n", __func__,
-						ch->signature);
-				return -ENODEV;
-			}
-			if (sdio_al_claim_mutex_and_verify_dev(ch->sdio_al_dev,
-							       __func__))
-				return -ENODEV;
-
-			ret = read_mailbox(sdio_al_dev, false);
-			if (ret) {
-				sdio_al_loge(&sdio_al->gen_log,
-						MODULE_NAME ":%s: failed to"
-						" read mailbox", __func__);
-				goto error_exit;
-			}
-			sdio_al_release_mutex(ch->sdio_al_dev, __func__);
-		} while (ch->read_avail > 0);
-	}
-	if (sdio_al_claim_mutex_and_verify_dev(ch->sdio_al_dev,
-					       __func__))
-		return -ENODEV;
-	/* disable function to be able to open the channel again */
-	ret = sdio_disable_func(ch->func);
-	if (ret) {
-		sdio_al_loge(&sdio_al->gen_log,
-			MODULE_NAME ":Fail to disable Func#%d\n",
-			ch->func->num);
-		goto error_exit;
-	}
-	ch->state = SDIO_CHANNEL_STATE_CLOSED;
-	CLOSE_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":%s: Ch %s closed "
-				"successfully\n", __func__, ch->name);
-
-error_exit:
-	sdio_al_release_mutex(ch->sdio_al_dev, __func__);
-
-	return ret;
-}
-
-/**
- *  Close SDIO Channel.
- *
- */
-int sdio_close(struct sdio_channel *ch)
-{
-	return channel_close(ch, true);
-}
-EXPORT_SYMBOL(sdio_close);
-
-/**
- *  Get the number of available bytes to write.
- *
- */
-int sdio_write_avail(struct sdio_channel *ch)
-{
-	if (!ch) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: NULL "
-				"channel\n", __func__);
-		return -ENODEV;
-	}
-	if (ch->signature != SDIO_AL_SIGNATURE) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: "
-				"Invalid signature 0x%x\n",  __func__,
-				ch->signature);
-		return -ENODEV;
-	}
-	if (ch->state != SDIO_CHANNEL_STATE_OPEN) {
-		sdio_al_loge(ch->sdio_al_dev->dev_log, MODULE_NAME ":%s: "
-				"channel %s state is not open (%d)\n",
-				__func__, ch->name, ch->state);
-		return -ENODEV;
-	}
-	pr_debug(MODULE_NAME ":sdio_write_avail %s 0x%x\n",
-			 ch->name, ch->write_avail);
-
-	return ch->write_avail;
-}
-EXPORT_SYMBOL(sdio_write_avail);
-
-/**
- *  Get the number of available bytes to read.
- *
- */
-int sdio_read_avail(struct sdio_channel *ch)
-{
-	if (!ch) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: NULL "
-				"channel\n", __func__);
-		return -ENODEV;
-	}
-	if (ch->signature != SDIO_AL_SIGNATURE) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: "
-				"Invalid signature 0x%x\n",  __func__,
-				ch->signature);
-		return -ENODEV;
-	}
-	if (ch->state != SDIO_CHANNEL_STATE_OPEN) {
-		sdio_al_loge(ch->sdio_al_dev->dev_log, MODULE_NAME ":%s: "
-				"channel %s state is not open (%d)\n",
-				__func__, ch->name, ch->state);
-		return -ENODEV;
-	}
-	pr_debug(MODULE_NAME ":sdio_read_avail %s 0x%x\n",
-			 ch->name, ch->read_avail);
-
-	return ch->read_avail;
-}
-EXPORT_SYMBOL(sdio_read_avail);
-
-static int sdio_read_from_closed_ch(struct sdio_channel *ch, int len)
-{
-	int ret = 0;
-	struct sdio_al_device *sdio_al_dev = NULL;
-
-	if (!ch) {
-		sdio_al_loge(ch->sdio_al_dev->dev_log,
-			MODULE_NAME ":%s: NULL channel\n",  __func__);
-		return -ENODEV;
-	}
-
-	sdio_al_dev = ch->sdio_al_dev;
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	ret = sdio_memcpy_fromio(ch->func, sdio_al_dev->rx_flush_buf,
-				 PIPE_RX_FIFO_ADDR, len);
-
-	if (ret) {
-		sdio_al_loge(ch->sdio_al_dev->dev_log,
-				MODULE_NAME ":ch %s: %s err=%d, len=%d\n",
-				ch->name, __func__, -ret, len);
-		sdio_al_dev->is_err = true;
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-		return ret;
-	}
-
-	restart_inactive_time(sdio_al_dev);
-
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-
-	return 0;
-}
-
-/**
- *  Internal read from SDIO Channel.
- *
- *  Reading from the pipe will trigger interrupt if there are
- *  other pending packets on the SDIO-Client.
- *
- */
-static int sdio_read_internal(struct sdio_channel *ch, void *data, int len)
-{
-	int ret = 0;
-	struct sdio_al_device *sdio_al_dev = NULL;
-
-	if (!ch) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: NULL "
-				"channel\n",  __func__);
-		return -ENODEV;
-	}
-	if (!data) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: NULL data\n",
-				__func__);
-		return -ENODEV;
-	}
-	if (len == 0) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":channel %s trying"
-				" to read 0 bytes\n", ch->name);
-		return -EINVAL;
-	}
-
-	if (ch->signature != SDIO_AL_SIGNATURE) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: Invalid "
-				"signature 0x%x\n",  __func__, ch->signature);
-		return -ENODEV;
-	}
-
-	sdio_al_dev = ch->sdio_al_dev;
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	if (sdio_al_dev->is_err) {
-		SDIO_AL_ERR(__func__);
-		ret = -ENODEV;
-		goto exit;
-	}
-
-	/* lpm policy says we can't go to sleep when we have pending rx data,
-	   so either we had rx interrupt and woken up, or we never went to
-	   sleep */
-	if (sdio_al_dev->is_ok_to_sleep) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":%s: called "
-				"when is_ok_to_sleep is set for ch %s, len=%d,"
-				" last_any_read_avail=%d, last_read_avail=%d, "
-				"last_old_read_avail=%d", __func__, ch->name,
-				len, ch->statistics.last_any_read_avail,
-				ch->statistics.last_read_avail,
-				ch->statistics.last_old_read_avail);
-	}
-	BUG_ON(sdio_al_dev->is_ok_to_sleep);
-
-	if ((ch->state != SDIO_CHANNEL_STATE_OPEN) &&
-			(ch->state != SDIO_CHANNEL_STATE_CLOSING)) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":%s wrong "
-				"channel %s state %d\n",
-				__func__, ch->name, ch->state);
-		ret = -EINVAL;
-		goto exit;
-	}
-
-	DATA_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":start ch %s read %d "
-			"avail %d.\n", ch->name, len, ch->read_avail);
-
-	restart_inactive_time(sdio_al_dev);
-
-	if ((ch->is_packet_mode) && (len != ch->read_avail)) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":sdio_read ch "
-				"%s len != read_avail\n", ch->name);
-		ret = -EINVAL;
-		goto exit;
-	}
-
-	if (len > ch->read_avail) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":ERR ch %s: "
-				"reading more bytes (%d) than the avail(%d).\n",
-				ch->name, len, ch->read_avail);
-		ret = -ENOMEM;
-		goto exit;
-	}
-
-	ret = sdio_memcpy_fromio(ch->func, data, PIPE_RX_FIFO_ADDR, len);
-
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":ch %s: "
-				"sdio_read err=%d, len=%d, read_avail=%d, "
-				"last_read_avail=%d, last_old_read_avail=%d\n",
-				ch->name, -ret, len, ch->read_avail,
-				ch->statistics.last_read_avail,
-				ch->statistics.last_old_read_avail);
-		sdio_al_get_into_err_state(sdio_al_dev);
-		goto exit;
-	}
-
-	ch->statistics.total_read_times++;
-
-	/* Remove handled packet from the list regardless if ret is ok */
-	if (ch->is_packet_mode)
-		remove_handled_rx_packet(ch);
-	else
-		ch->read_avail -= len;
-
-	ch->total_rx_bytes += len;
-	DATA_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":end ch %s read %d "
-			"avail %d total %d.\n", ch->name, len,
-			ch->read_avail, ch->total_rx_bytes);
-
-	if ((ch->read_avail == 0) && !(ch->is_packet_mode))
-		ask_reading_mailbox(sdio_al_dev);
-
-exit:
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-
-	return ret;
-}
-
-/**
- *  Read from SDIO Channel.
- *
- *  Reading from the pipe will trigger interrupt if there are
- *  other pending packets on the SDIO-Client.
- *
- */
-int sdio_read(struct sdio_channel *ch, void *data, int len)
-{
-	if (!ch) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: NULL "
-				"channel\n", __func__);
-		return -ENODEV;
-	}
-	if (ch->signature != SDIO_AL_SIGNATURE) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: "
-			"Invalid signature 0x%x\n",  __func__, ch->signature);
-		return -ENODEV;
-	}
-	if (ch->state == SDIO_CHANNEL_STATE_OPEN) {
-		return sdio_read_internal(ch, data, len);
-	} else {
-		sdio_al_loge(ch->sdio_al_dev->dev_log, MODULE_NAME
-				":%s: Invalid channel %s state %d\n",
-				__func__, ch->name, ch->state);
-	}
-	return -ENODEV;
-}
-EXPORT_SYMBOL(sdio_read);
-
-/**
- *  Write to SDIO Channel.
- *
- */
-int sdio_write(struct sdio_channel *ch, const void *data, int len)
-{
-	int ret = 0;
-	struct sdio_al_device *sdio_al_dev = NULL;
-
-	if (!ch) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: NULL "
-				"channel\n",  __func__);
-		return -ENODEV;
-	}
-	if (!data) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: NULL data\n",
-				__func__);
-		return -ENODEV;
-	}
-	if (len == 0) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":channel %s trying"
-				" to write 0 bytes\n", ch->name);
-		return -EINVAL;
-	}
-
-	if (ch->signature != SDIO_AL_SIGNATURE) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: Invalid "
-				"signature 0x%x\n",  __func__, ch->signature);
-		return -ENODEV;
-	}
-
-	sdio_al_dev = ch->sdio_al_dev;
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	WARN_ON(len > ch->write_avail);
-
-	if (sdio_al_dev->is_err) {
-		SDIO_AL_ERR(__func__);
-		ret = -ENODEV;
-		goto exit;
-	}
-
-	if (ch->state != SDIO_CHANNEL_STATE_OPEN) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":writing to "
-				"closed channel %s\n", ch->name);
-		ret = -EINVAL;
-		goto exit;
-	}
-
-	if (sdio_al_dev->is_ok_to_sleep) {
-		ret = sdio_al_wake_up(sdio_al_dev, 1, ch);
-		if (ret)
-			goto exit;
-	} else {
-		restart_inactive_time(sdio_al_dev);
-	}
-
-	DATA_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":start ch %s write %d "
-			"avail %d.\n", ch->name, len, ch->write_avail);
-
-	if (len > ch->write_avail) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":ERR ch %s: "
-				"write more bytes (%d) than  available %d.\n",
-				ch->name, len, ch->write_avail);
-		ret = -ENOMEM;
-		goto exit;
-	}
-
-	ret = sdio_ch_write(ch, data, len);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":sdio_write "
-				"on channel %s err=%d\n", ch->name, -ret);
-		goto exit;
-	}
-
-	ch->total_tx_bytes += len;
-	DATA_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":end ch %s write %d "
-			"avail %d total %d.\n", ch->name, len,
-			ch->write_avail, ch->total_tx_bytes);
-
-	/* Round up to whole buffer size */
-	len = ROUND_UP(len, ch->peer_tx_buf_size);
-	/* Protect from wraparound */
-	len = min(len, (int) ch->write_avail);
-	ch->write_avail -= len;
-
-	if (ch->write_avail < ch->min_write_avail)
-		ask_reading_mailbox(sdio_al_dev);
-
-exit:
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-
-	return ret;
-}
-EXPORT_SYMBOL(sdio_write);
-
-static int __devinit msm_sdio_al_probe(struct platform_device *pdev)
-{
-	if (!sdio_al) {
-		pr_err(MODULE_NAME ": %s: NULL sdio_al\n", __func__);
-		return -ENODEV;
-	}
-
-	sdio_al->pdata = pdev->dev.platform_data;
-	return 0;
-}
-
-static int __devexit msm_sdio_al_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
-static void sdio_al_close_all_channels(struct sdio_al_device *sdio_al_dev)
-{
-	int j;
-	int ret;
-	struct sdio_channel *ch = NULL;
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s", __func__);
-
-	if (!sdio_al_dev) {
-		sdio_al_loge(sdio_al_dev->dev_log,
-			MODULE_NAME ": %s: NULL device", __func__);
-		return;
-	}
-	for (j = 0; j < SDIO_AL_MAX_CHANNELS; j++) {
-		ch = &sdio_al_dev->channel[j];
-
-		if (ch->state == SDIO_CHANNEL_STATE_OPEN) {
-			sdio_al_loge(sdio_al_dev->dev_log,
-				MODULE_NAME ": %s: Call to sdio_close() for"
-				" ch %s\n", __func__, ch->name);
-			ret = channel_close(ch, false);
-			if (ret) {
-				sdio_al_loge(sdio_al_dev->dev_log,
-					MODULE_NAME ": %s: failed sdio_close()"
-					" for ch %s (%d)\n",
-					__func__, ch->name, ret);
-			}
-		} else {
-			pr_debug(MODULE_NAME ": %s: skip sdio_close() ch %s"
-					" (state=%d)\n", __func__,
-					ch->name, ch->state);
-		}
-	}
-}
-
-static void sdio_al_invalidate_sdio_clients(struct sdio_al_device *sdio_al_dev,
-					    struct platform_device **pdev_arr)
-{
-	int j;
-
-	pr_debug(MODULE_NAME ": %s: Notifying SDIO clients for card %d",
-			__func__, sdio_al_dev->host->index);
-	for (j = 0; j < SDIO_AL_MAX_CHANNELS; ++j) {
-		if (sdio_al_dev->channel[j].state ==
-			SDIO_CHANNEL_STATE_INVALID)
-			continue;
-		pdev_arr[j] = sdio_al_dev->channel[j].pdev;
-		sdio_al_dev->channel[j].signature = 0x0;
-		sdio_al_dev->channel[j].state =
-			SDIO_CHANNEL_STATE_INVALID;
-	}
-}
-
-static void sdio_al_modem_reset_operations(struct sdio_al_device
-							*sdio_al_dev)
-{
-	int ret = 0;
-	struct platform_device *pdev_arr[SDIO_AL_MAX_CHANNELS];
-	int j;
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s", __func__);
-
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return;
-
-	if (sdio_al_dev->state == CARD_REMOVED) {
-		sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s: "
-			"card %d is already removed", __func__,
-			sdio_al_dev->host->index);
-		goto exit_err;
-	}
-
-	if (sdio_al_dev->state == MODEM_RESTART) {
-		sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ": %s: "
-			"card %d was already notified for modem reset",
-			__func__, sdio_al_dev->host->index);
-		goto exit_err;
-	}
-
-	sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ": %s: Set the "
-		"state to MODEM_RESTART for card %d",
-		__func__, sdio_al_dev->host->index);
-	sdio_al_dev->state = MODEM_RESTART;
-	sdio_al_dev->is_ready = false;
-
-	/* Stop mailbox timer */
-	stop_and_del_timer(sdio_al_dev);
-
-	if ((sdio_al_dev->is_ok_to_sleep) &&
-	    (!sdio_al_dev->is_err)) {
-		pr_debug(MODULE_NAME ": %s: wakeup modem for "
-				    "card %d", __func__,
-			sdio_al_dev->host->index);
-		ret = sdio_al_wake_up(sdio_al_dev, 1, NULL);
-	}
-
-	if (!ret && (!sdio_al_dev->is_err) && sdio_al_dev->card &&
-		sdio_al_dev->card->sdio_func[0]) {
-			sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME
-			": %s: sdio_release_irq for card %d",
-			__func__,
-			sdio_al_dev->host->index);
-			sdio_release_irq(sdio_al_dev->card->sdio_func[0]);
-	}
-
-	memset(pdev_arr, 0, sizeof(pdev_arr));
-	sdio_al_invalidate_sdio_clients(sdio_al_dev, pdev_arr);
-
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s: Notifying SDIO "
-						    "clients for card %d",
-			__func__, sdio_al_dev->host->index);
-	for (j = 0; j < SDIO_AL_MAX_CHANNELS; j++) {
-		if (!pdev_arr[j])
-			continue;
-		platform_device_unregister(pdev_arr[j]);
-	}
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s: Finished Notifying "
-						    "SDIO clients for card %d",
-			__func__, sdio_al_dev->host->index);
-
-	return;
-
-exit_err:
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-	return;
-}
-
-#ifdef CONFIG_MSM_SUBSYSTEM_RESTART
-static void sdio_al_reset(void)
-{
-	int i;
-	struct sdio_al_device *sdio_al_dev;
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s", __func__);
-
-	for (i = 0; i < MAX_NUM_OF_SDIO_DEVICES; i++) {
-		if (sdio_al->devices[i] == NULL) {
-			pr_debug(MODULE_NAME ": %s: NULL device in index %d",
-					__func__, i);
-			continue;
-		}
-		sdio_al_dev = sdio_al->devices[i];
-		sdio_al_modem_reset_operations(sdio_al->devices[i]);
-	}
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s completed", __func__);
-}
-#endif
-
-static void msm_sdio_al_shutdown(struct platform_device *pdev)
-{
-	int i;
-	struct sdio_al_device *sdio_al_dev;
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME
-			"Initiating msm_sdio_al_shutdown...");
-
-	for (i = 0; i < MAX_NUM_OF_SDIO_DEVICES; i++) {
-		if (sdio_al->devices[i] == NULL) {
-			pr_debug(MODULE_NAME ": %s: NULL device in index %d",
-					__func__, i);
-			continue;
-		}
-		sdio_al_dev = sdio_al->devices[i];
-
-		if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-			return;
-
-		if (sdio_al_dev->ch_close_supported)
-			sdio_al_close_all_channels(sdio_al_dev);
-
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-
-		sdio_al_modem_reset_operations(sdio_al_dev);
-	}
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s: "
-		"msm_sdio_al_shutdown complete.", __func__);
-}
-
-static struct platform_driver msm_sdio_al_driver = {
-	.probe          = msm_sdio_al_probe,
-	.remove         = __exit_p(msm_sdio_al_remove),
-	.shutdown	= msm_sdio_al_shutdown,
-	.driver         = {
-		.name   = "msm_sdio_al",
-	},
-};
-
-/**
- *  Initialize SDIO_AL channels.
- *
- */
-static int init_channels(struct sdio_al_device *sdio_al_dev)
-{
-	int ret = 0;
-	int i;
-
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	ret = read_sdioc_software_header(sdio_al_dev,
-					 sdio_al_dev->sdioc_sw_header);
-	if (ret)
-		goto exit;
-
-	ret = sdio_al_setup(sdio_al_dev);
-	if (ret)
-		goto exit;
-
-	for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++) {
-		int ch_name_size;
-		if (sdio_al_dev->channel[i].state == SDIO_CHANNEL_STATE_INVALID)
-			continue;
-		if (sdio_al->unittest_mode) {
-			memset(sdio_al_dev->channel[i].ch_test_name, 0,
-				sizeof(sdio_al_dev->channel[i].ch_test_name));
-			ch_name_size = strnlen(sdio_al_dev->channel[i].name,
-				       CHANNEL_NAME_SIZE);
-			strncpy(sdio_al_dev->channel[i].ch_test_name,
-			       sdio_al_dev->channel[i].name,
-			       ch_name_size);
-			strncat(sdio_al_dev->channel[i].ch_test_name +
-			       ch_name_size,
-			       SDIO_TEST_POSTFIX,
-			       SDIO_TEST_POSTFIX_SIZE);
-			pr_debug(MODULE_NAME ":pdev.name = %s\n",
-				sdio_al_dev->channel[i].ch_test_name);
-			sdio_al_dev->channel[i].pdev = platform_device_alloc(
-				sdio_al_dev->channel[i].ch_test_name, -1);
-		} else {
-			pr_debug(MODULE_NAME ":pdev.name = %s\n",
-				sdio_al_dev->channel[i].name);
-			sdio_al_dev->channel[i].pdev = platform_device_alloc(
-				sdio_al_dev->channel[i].name, -1);
-		}
-		if (!sdio_al_dev->channel[i].pdev) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					":NULL platform device for ch %s",
-					sdio_al_dev->channel[i].name);
-			sdio_al_dev->channel[i].state =
-				SDIO_CHANNEL_STATE_INVALID;
-			continue;
-		}
-		ret = platform_device_add(sdio_al_dev->channel[i].pdev);
-		if (ret) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					":platform_device_add failed, "
-					"ret=%d\n", ret);
-			sdio_al_dev->channel[i].state =
-				SDIO_CHANNEL_STATE_INVALID;
-		}
-	}
-
-exit:
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-	return ret;
-}
-
-/**
- *  Initialize SDIO_AL channels according to the client setup.
- *  This function also check if the client is in boot mode and
- *  flashless boot is required to be activated or the client is
- *  up and running.
- *
- */
-static int sdio_al_client_setup(struct sdio_al_device *sdio_al_dev)
-{
-	int ret = 0;
-	struct sdio_func *func1;
-	int signature = 0;
-
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	if (!sdio_al_dev->card || !sdio_al_dev->card->sdio_func[0]) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":NULL card or "
-							       "func1\n");
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-		return -ENODEV;
-	}
-	func1 = sdio_al_dev->card->sdio_func[0];
-
-	/* Read the header signature to determine the status of the MDM
-	 * SDIO Client
-	 */
-	signature = sdio_readl(func1, SDIOC_SW_HEADER_ADDR, &ret);
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":fail to read "
-				"signature from sw header.\n");
-		return ret;
-	}
-
-	switch (signature) {
-	case PEER_SDIOC_SW_MAILBOX_BOOT_SIGNATURE:
-		if (sdio_al_dev == sdio_al->bootloader_dev) {
-			sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":setup "
-					"bootloader on card %d\n",
-					sdio_al_dev->host->index);
-			return sdio_al_bootloader_setup();
-		} else {
-			sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":wait "
-					"for bootloader completion "
-					"on card %d\n",
-					sdio_al_dev->host->index);
-			return sdio_al_wait_for_bootloader_comp(sdio_al_dev);
-		}
-	case PEER_SDIOC_SW_MAILBOX_SIGNATURE:
-	case PEER_SDIOC_SW_MAILBOX_UT_SIGNATURE:
-		return init_channels(sdio_al_dev);
-	default:
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Invalid "
-				"signature 0x%x\n", signature);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static void clean_sdio_al_device_data(struct sdio_al_device *sdio_al_dev)
-{
-	sdio_al_dev->is_ready = 0;
-	sdio_al_dev->bootloader_done = 0;
-	sdio_al_dev->lpm_chan = 0;
-	sdio_al_dev->is_ok_to_sleep = 0;
-	sdio_al_dev->inactivity_time = 0;
-	sdio_al_dev->poll_delay_msec = 0;
-	sdio_al_dev->is_timer_initialized = 0;
-	sdio_al_dev->is_err = 0;
-	sdio_al_dev->is_suspended = 0;
-	sdio_al_dev->flashless_boot_on = 0;
-	sdio_al_dev->ch_close_supported = 0;
-	sdio_al_dev->print_after_interrupt = 0;
-	memset(sdio_al_dev->sdioc_sw_header, 0,
-	       sizeof(*sdio_al_dev->sdioc_sw_header));
-	memset(sdio_al_dev->mailbox, 0, sizeof(*sdio_al_dev->mailbox));
-	memset(sdio_al_dev->rx_flush_buf, 0,
-	       sizeof(*sdio_al_dev->rx_flush_buf));
-}
-
-/*
- * SDIO driver functions
- */
-static int sdio_al_sdio_probe(struct sdio_func *func,
-		const struct sdio_device_id *sdio_dev_id)
-{
-	int ret = 0;
-	struct sdio_al_device *sdio_al_dev = NULL;
-	int i;
-	struct mmc_card *card = NULL;
-
-	if (!func) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL func\n",
-				__func__);
-		return -ENODEV;
-	}
-	card = func->card;
-
-	if (!card) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL card\n",
-				__func__);
-		return -ENODEV;
-	}
-
-	if (!card->sdio_func[0]) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL "
-							    "func1\n",
-				__func__);
-		return -ENODEV;
-	}
-
-	if (card->sdio_funcs < SDIO_AL_MAX_FUNCS) {
-		dev_info(&card->dev,
-			 "SDIO-functions# %d less than expected.\n",
-			 card->sdio_funcs);
-		return -ENODEV;
-	}
-
-	/* Check if there is already a device for this card */
-	for (i = 0; i < MAX_NUM_OF_SDIO_DEVICES; ++i) {
-		if (sdio_al->devices[i] == NULL)
-			continue;
-		if (sdio_al->devices[i]->host == card->host) {
-			sdio_al_dev = sdio_al->devices[i];
-			if (sdio_al_dev->state == CARD_INSERTED)
-				return 0;
-			clean_sdio_al_device_data(sdio_al_dev);
-			break;
-		}
-	}
-
-	if (!sdio_al_dev) {
-		sdio_al_dev = kzalloc(sizeof(struct sdio_al_device),
-				      GFP_KERNEL);
-		if (sdio_al_dev == NULL)
-			return -ENOMEM;
-
-		for (i = 0; i < MAX_NUM_OF_SDIO_DEVICES ; ++i)
-			if (sdio_al->devices[i] == NULL) {
-				sdio_al->devices[i] = sdio_al_dev;
-				sdio_al_dev->dev_log = &sdio_al->device_log[i];
-				spin_lock_init(&sdio_al_dev->dev_log->log_lock);
-	#ifdef CONFIG_DEBUG_FS
-				sdio_al_dbgfs_log[i].data =
-						sdio_al_dev->dev_log->buffer;
-				sdio_al_dbgfs_log[i].size =
-					SDIO_AL_DEBUG_LOG_SIZE;
-	#endif
-				break;
-			}
-		if (i == MAX_NUM_OF_SDIO_DEVICES) {
-			sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":No space "
-					"in devices array for the device\n");
-			return -ENOMEM;
-		}
-	}
-
-	dev_info(&card->dev, "SDIO Card claimed.\n");
-	sdio_al->skip_print_info = 0;
-
-	sdio_al_dev->state = CARD_INSERTED;
-
-	if (card->host->index == SDIO_BOOTLOADER_CARD_INDEX)
-		sdio_al->bootloader_dev = sdio_al_dev;
-
-	sdio_al_dev->is_ready = false;
-
-	sdio_al_dev->signature = SDIO_AL_SIGNATURE;
-
-	sdio_al_dev->is_suspended = 0;
-	sdio_al_dev->is_timer_initialized = false;
-
-	sdio_al_dev->lpm_chan = INVALID_SDIO_CHAN;
-
-	sdio_al_dev->card = card;
-	sdio_al_dev->host = card->host;
-
-	if (!sdio_al_dev->mailbox) {
-		sdio_al_dev->mailbox = kzalloc(sizeof(struct sdio_mailbox),
-					       GFP_KERNEL);
-		if (sdio_al_dev->mailbox == NULL)
-			return -ENOMEM;
-	}
-
-	if (!sdio_al_dev->sdioc_sw_header) {
-		sdio_al_dev->sdioc_sw_header
-			= kzalloc(sizeof(*sdio_al_dev->sdioc_sw_header),
-				  GFP_KERNEL);
-		if (sdio_al_dev->sdioc_sw_header == NULL)
-			return -ENOMEM;
-	}
-
-	if (!sdio_al_dev->rx_flush_buf) {
-		sdio_al_dev->rx_flush_buf = kzalloc(RX_FLUSH_BUFFER_SIZE,
-						    GFP_KERNEL);
-		if (sdio_al_dev->rx_flush_buf == NULL) {
-			sdio_al_loge(&sdio_al->gen_log,
-					MODULE_NAME ":Fail to allocate "
-					   "rx_flush_buf for card %d\n",
-			       card->host->index);
-			return -ENOMEM;
-		}
-	}
-
-	sdio_al_dev->timer.data = (unsigned long)sdio_al_dev;
-
-	wake_lock_init(&sdio_al_dev->wake_lock, WAKE_LOCK_SUSPEND, MODULE_NAME);
-	/* Don't allow sleep until all required clients register */
-	sdio_al_vote_for_sleep(sdio_al_dev, 0);
-
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	/* Init Func#1 */
-	ret = sdio_al_enable_func_retry(card->sdio_func[0], "Init Func#1");
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Fail to "
-				"enable Func#%d\n", card->sdio_func[0]->num);
-		goto exit;
-	}
-
-	/* Patch Func CIS tuple issue */
-	ret = sdio_set_block_size(card->sdio_func[0], SDIO_AL_BLOCK_SIZE);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Fail to set "
-			"block size, Func#%d\n", card->sdio_func[0]->num);
-		goto exit;
-	}
-	sdio_al_dev->card->sdio_func[0]->max_blksize = SDIO_AL_BLOCK_SIZE;
-
-	sdio_al_dev->workqueue = create_singlethread_workqueue("sdio_al_wq");
-	sdio_al_dev->sdio_al_work.sdio_al_dev = sdio_al_dev;
-	init_waitqueue_head(&sdio_al_dev->wait_mbox);
-
-	ret = sdio_al_client_setup(sdio_al_dev);
-
-exit:
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-	return ret;
-}
-
-static void sdio_al_sdio_remove(struct sdio_func *func)
-{
-	struct sdio_al_device *sdio_al_dev = NULL;
-	int i;
-	struct mmc_card *card = NULL;
-	struct platform_device *pdev_arr[SDIO_AL_MAX_CHANNELS];
-
-	if (!func) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL func\n",
-				__func__);
-		return;
-	}
-	card = func->card;
-
-	if (!card) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL card\n",
-				__func__);
-		return;
-	}
-
-	/* Find the sdio_al_device of this card */
-	for (i = 0; i < MAX_NUM_OF_SDIO_DEVICES; ++i) {
-		if (sdio_al->devices[i] == NULL)
-			continue;
-		if (sdio_al->devices[i]->card == card) {
-			sdio_al_dev = sdio_al->devices[i];
-			break;
-		}
-	}
-	if (sdio_al_dev == NULL) {
-		pr_debug(MODULE_NAME ":%s :NULL sdio_al_dev for card %d\n",
-				 __func__, card->host->index);
-		return;
-	}
-
-	if (sdio_al_claim_mutex(sdio_al_dev, __func__))
-		return;
-
-	if (sdio_al_dev->state == CARD_REMOVED) {
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-		return;
-	}
-
-	if (!card->sdio_func[0]) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL "
-						"func1\n", __func__);
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-		return;
-	}
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ":%s for card %d\n",
-			 __func__, card->host->index);
-
-	sdio_al_dev->state = CARD_REMOVED;
-
-	memset(pdev_arr, 0, sizeof(pdev_arr));
-	sdio_al_invalidate_sdio_clients(sdio_al_dev, pdev_arr);
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ":%s: ask_reading_mailbox "
-			"for card %d\n", __func__, card->host->index);
-	sdio_al_dev->is_ready = false; /* Flag worker to exit */
-	sdio_al_dev->ask_mbox = false;
-	ask_reading_mailbox(sdio_al_dev); /* Wakeup worker */
-
-	stop_and_del_timer(sdio_al_dev);
-
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s: Notifying SDIO "
-						    "clients for card %d",
-			__func__, sdio_al_dev->host->index);
-	for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++) {
-		if (!pdev_arr[i])
-			continue;
-		platform_device_unregister(pdev_arr[i]);
-	}
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s: Finished Notifying "
-						    "SDIO clients for card %d",
-			__func__, sdio_al_dev->host->index);
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ":%s: vote for sleep for "
-			"card %d\n", __func__, card->host->index);
-	sdio_al_vote_for_sleep(sdio_al_dev, 1);
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ":%s: flush_workqueue for "
-			"card %d\n", __func__, card->host->index);
-	flush_workqueue(sdio_al_dev->workqueue);
-	destroy_workqueue(sdio_al_dev->workqueue);
-	wake_lock_destroy(&sdio_al_dev->wake_lock);
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ":%s: sdio card %d removed."
-			"\n", __func__,	card->host->index);
-}
-
-static void sdio_print_mailbox(char *prefix_str, struct sdio_mailbox *mailbox)
-{
-	int k = 0;
-	char buf[256];
-	char buf1[10];
-
-	if (!mailbox) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": mailbox is "
-				"NULL\n");
-		return;
-	}
-
-	sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: pipes 0_7: eot=0x%x,"
-		" thresh=0x%x, overflow=0x%x, "
-		"underflow=0x%x, mask_thresh=0x%x\n",
-		 prefix_str, mailbox->eot_pipe_0_7,
-		 mailbox->thresh_above_limit_pipe_0_7,
-		 mailbox->overflow_pipe_0_7,
-		 mailbox->underflow_pipe_0_7,
-		 mailbox->mask_thresh_above_limit_pipe_0_7);
-
-	memset(buf, 0, sizeof(buf));
-	strncat(buf, ": bytes_avail:", sizeof(buf));
-
-	for (k = 0 ; k < SDIO_AL_ACTIVE_PIPES ; ++k) {
-		snprintf(buf1, sizeof(buf1), "%d, ",
-			 mailbox->pipe_bytes_avail[k]);
-		strncat(buf, buf1, sizeof(buf));
-	}
-
-	sdio_al_loge(&sdio_al->gen_log, MODULE_NAME "%s", buf);
-}
-
-static void sdio_al_print_info(void)
-{
-	int i = 0;
-	int j = 0;
-	int ret = 0;
-	struct sdio_mailbox *mailbox = NULL;
-	struct sdio_mailbox *hw_mailbox = NULL;
-	struct peer_sdioc_channel_config *ch_config = NULL;
-	struct sdio_func *func1 = NULL;
-	struct sdio_func *lpm_func = NULL;
-	int offset = 0;
-	int is_ok_to_sleep = 0;
-	char buf[50];
-
-	if (sdio_al->skip_print_info == 1)
-		return;
-
-	sdio_al->skip_print_info = 1;
-
-	sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s - SDIO DEBUG INFO\n",
-			__func__);
-
-	if (!sdio_al) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s - ERROR - "
-				"sdio_al is NULL\n",  __func__);
-		return;
-	}
-
-	sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": GPIO mdm2ap_status=%d\n",
-				sdio_al->pdata->get_mdm2ap_status());
-
-	for (j = 0 ; j < MAX_NUM_OF_SDIO_DEVICES ; ++j) {
-		struct sdio_al_device *sdio_al_dev = sdio_al->devices[j];
-
-		if (sdio_al_dev == NULL) {
-			continue;
-		}
-
-		if (!sdio_al_dev->host) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": Host"
-					" is NULL\n);");
-			continue;
-		}
-
-		snprintf(buf, sizeof(buf), "Card#%d: Shadow HW MB",
-		       sdio_al_dev->host->index);
-
-		/* printing Shadowing HW Mailbox*/
-		mailbox = sdio_al_dev->mailbox;
-		sdio_print_mailbox(buf, mailbox);
-
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": Card#%d: "
-			"is_ok_to_sleep=%d\n",
-			sdio_al_dev->host->index,
-			sdio_al_dev->is_ok_to_sleep);
-
-
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": Card#%d: "
-				   "Shadow channels SW MB:",
-		       sdio_al_dev->host->index);
-
-		/* printing Shadowing SW Mailbox per channel*/
-		for (i = 0 ; i < SDIO_AL_MAX_CHANNELS ; ++i) {
-			struct sdio_channel *ch = &sdio_al_dev->channel[i];
-
-			if (ch == NULL) {
-				continue;
-			}
-
-			if (ch->state == SDIO_CHANNEL_STATE_INVALID)
-				continue;
-
-			ch_config = &sdio_al_dev->channel[i].ch_config;
-
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": Ch %s: max_rx_thres=0x%x, "
-				"max_tx_thres=0x%x, tx_buf=0x%x, "
-				"is_packet_mode=%d, "
-				"max_packet=0x%x, min_write=0x%x",
-				ch->name, ch_config->max_rx_threshold,
-				ch_config->max_tx_threshold,
-				ch_config->tx_buf_size,
-				ch_config->is_packet_mode,
-				ch_config->max_packet_size,
-				ch->min_write_avail);
-
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": total_rx=0x%x, total_tx=0x%x, "
-				"read_avail=0x%x, write_avail=0x%x, "
-				"rx_pending=0x%x, num_reads=0x%x, "
-				"num_notifs=0x%x", ch->total_rx_bytes,
-				ch->total_tx_bytes, ch->read_avail,
-				ch->write_avail, ch->rx_pending_bytes,
-				ch->statistics.total_read_times,
-				ch->statistics.total_notifs);
-		} /* end loop over all channels */
-
-	} /* end loop over all devices */
-
-	/* reading from client and printing is_host_ok_to_sleep per device */
-	for (j = 0 ; j < MAX_NUM_OF_SDIO_DEVICES ; ++j) {
-		struct sdio_al_device *sdio_al_dev = sdio_al->devices[j];
-
-		if (sdio_al_verify_func1(sdio_al_dev, __func__))
-			continue;
-
-		if (!sdio_al_dev->host) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					": Host is NULL");
-			continue;
-		}
-
-		if (sdio_al_dev->lpm_chan == INVALID_SDIO_CHAN) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": %s - for Card#%d, is lpm_chan=="
-				"INVALID_SDIO_CHAN. continuing...",
-				__func__, sdio_al_dev->host->index);
-			continue;
-		}
-
-		offset = offsetof(struct peer_sdioc_sw_mailbox, ch_config)+
-		sizeof(struct peer_sdioc_channel_config) *
-		sdio_al_dev->lpm_chan+
-		offsetof(struct peer_sdioc_channel_config, is_host_ok_to_sleep);
-
-		lpm_func = sdio_al_dev->card->sdio_func[sdio_al_dev->
-								lpm_chan+1];
-		if (!lpm_func) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					": %s - lpm_func is NULL for card#%d"
-					" continuing...\n", __func__,
-					sdio_al_dev->host->index);
-			continue;
-		}
-
-		if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-			return;
-		ret  =  sdio_memcpy_fromio(lpm_func,
-					    &is_ok_to_sleep,
-					    SDIOC_SW_MAILBOX_ADDR+offset,
-					    sizeof(int));
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-
-		if (ret)
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					": %s - fail to read "
-				"is_HOST_ok_to_sleep from mailbox for card %d",
-				__func__, sdio_al_dev->host->index);
-		else
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					": Card#%d: "
-				"is_HOST_ok_to_sleep=%d\n",
-				sdio_al_dev->host->index,
-				is_ok_to_sleep);
-	}
-
-	for (j = 0 ; j < MAX_NUM_OF_SDIO_DEVICES ; ++j) {
-		struct sdio_al_device *sdio_al_dev = sdio_al->devices[j];
-
-		if (!sdio_al_dev)
-			continue;
-
-		/* Reading HW Mailbox */
-		hw_mailbox = sdio_al_dev->mailbox;
-
-		if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-			return;
-
-		if (!sdio_al_dev->card || !sdio_al_dev->card->sdio_func[0]) {
-			sdio_al_release_mutex(sdio_al_dev, __func__);
-			return;
-		}
-		func1 = sdio_al_dev->card->sdio_func[0];
-		ret = sdio_memcpy_fromio(func1, hw_mailbox,
-			HW_MAILBOX_ADDR, sizeof(*hw_mailbox));
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-
-		if (ret) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					": fail to read "
-			       "mailbox for card#%d. "
-			       "continuing...\n",
-			       sdio_al_dev->host->index);
-			continue;
-		}
-
-		snprintf(buf, sizeof(buf), "Card#%d: Current HW MB",
-		       sdio_al_dev->host->index);
-
-		/* Printing HW Mailbox */
-		sdio_print_mailbox(buf, hw_mailbox);
-	}
-}
-
-static struct sdio_device_id sdio_al_sdioid[] = {
-    {.class = 0, .vendor = 0x70, .device = 0x2460},
-    {.class = 0, .vendor = 0x70, .device = 0x0460},
-    {.class = 0, .vendor = 0x70, .device = 0x23F1},
-    {.class = 0, .vendor = 0x70, .device = 0x23F0},
-    {}
-};
-
-static struct sdio_driver sdio_al_sdiofn_driver = {
-    .name      = "sdio_al_sdiofn",
-    .id_table  = sdio_al_sdioid,
-    .probe     = sdio_al_sdio_probe,
-    .remove    = sdio_al_sdio_remove,
-};
-
-#ifdef CONFIG_MSM_SUBSYSTEM_RESTART
-/*
- *  Callback for notifications from restart mudule.
- *  This function handles only the BEFORE_RESTART notification.
- *  Stop all the activity on the card and notify our clients.
- */
-static int sdio_al_subsys_notifier_cb(struct notifier_block *this,
-				  unsigned long notif_type,
-				  void *data)
-{
-	if (notif_type != SUBSYS_BEFORE_SHUTDOWN) {
-		sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s: got "
-				"notification %ld", __func__, notif_type);
-		return NOTIFY_DONE;
-	}
-
-	sdio_al_reset();
-	return NOTIFY_OK;
-}
-
-static struct notifier_block sdio_al_nb = {
-	.notifier_call = sdio_al_subsys_notifier_cb,
-};
-#endif
-
-/**
- *  Module Init.
- *
- *  @warn: allocate sdio_al context before registering driver.
- *
- */
-static int __init sdio_al_init(void)
-{
-	int ret = 0;
-	int i;
-
-	pr_debug(MODULE_NAME ":sdio_al_init\n");
-
-	pr_info(MODULE_NAME ":SDIO-AL SW version %s\n",
-		DRV_VERSION);
-
-	sdio_al = kzalloc(sizeof(struct sdio_al), GFP_KERNEL);
-	if (sdio_al == NULL)
-		return -ENOMEM;
-
-	for (i = 0; i < MAX_NUM_OF_SDIO_DEVICES ; ++i)
-		sdio_al->devices[i] = NULL;
-
-	sdio_al->unittest_mode = false;
-
-	sdio_al->debug.debug_lpm_on = debug_lpm_on;
-	sdio_al->debug.debug_data_on = debug_data_on;
-	sdio_al->debug.debug_close_on = debug_close_on;
-
-#ifdef CONFIG_DEBUG_FS
-	sdio_al_debugfs_init();
-#endif
-
-
-#ifdef CONFIG_MSM_SUBSYSTEM_RESTART
-	sdio_al->subsys_notif_handle = subsys_notif_register_notifier(
-		"external_modem", &sdio_al_nb);
-#endif
-
-	ret = platform_driver_register(&msm_sdio_al_driver);
-	if (ret) {
-		pr_err(MODULE_NAME ": platform_driver_register failed: %d\n",
-		       ret);
-		goto exit;
-	}
-
-	sdio_register_driver(&sdio_al_sdiofn_driver);
-
-	spin_lock_init(&sdio_al->gen_log.log_lock);
-
-exit:
-	if (ret)
-		kfree(sdio_al);
-	return ret;
-}
-
-/**
- *  Module Exit.
- *
- *  Free allocated memory.
- *  Disable SDIO-Card.
- *  Unregister driver.
- *
- */
-static void __exit sdio_al_exit(void)
-{
-	if (sdio_al == NULL)
-		return;
-
-	pr_debug(MODULE_NAME ":sdio_al_exit\n");
-
-#ifdef CONFIG_MSM_SUBSYSTEM_RESTART
-	subsys_notif_unregister_notifier(
-		sdio_al->subsys_notif_handle, &sdio_al_nb);
-#endif
-
-	sdio_al_tear_down();
-
-	sdio_unregister_driver(&sdio_al_sdiofn_driver);
-
-	kfree(sdio_al);
-
-#ifdef CONFIG_DEBUG_FS
-	sdio_al_debugfs_cleanup();
-#endif
-
-	platform_driver_unregister(&msm_sdio_al_driver);
-
-	pr_debug(MODULE_NAME ":sdio_al_exit complete\n");
-}
-
-module_init(sdio_al_init);
-module_exit(sdio_al_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("SDIO Abstraction Layer");
-MODULE_AUTHOR("Amir Samuelov <amirs@codeaurora.org>");
-MODULE_VERSION(DRV_VERSION);
-
diff --git a/arch/arm/mach-msm/sdio_al_dloader.c b/arch/arm/mach-msm/sdio_al_dloader.c
deleted file mode 100644
index f3effa8..0000000
--- a/arch/arm/mach-msm/sdio_al_dloader.c
+++ /dev/null
@@ -1,2574 +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.
- */
-
-/*
- * SDIO-Downloader
- *
- * To be used with Qualcomm's SDIO-Client connected to this host.
- */
-
-/* INCLUDES */
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/wakelock.h>
-#include <linux/workqueue.h>
-#include <linux/mmc/card.h>
-#include <linux/dma-mapping.h>
-#include <mach/dma.h>
-#include <linux/mmc/sdio_func.h>
-#include "sdio_al_private.h"
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/kthread.h>
-#include <linux/version.h>
-#include <linux/errno.h>
-#include <linux/debugfs.h>
-
-/* DEFINES AND MACROS */
-#define MAX_NUM_DEVICES		1
-#define TTY_SDIO_DEV			"tty_sdio_0"
-#define TTY_SDIO_DEV_TEST		"tty_sdio_test_0"
-#define SDIOC_MAILBOX_ADDRESS		0
-#define SDIO_DL_BLOCK_SIZE		512
-#define SDIO_DL_MAIN_THREAD_NAME	"sdio_tty_main_thread"
-#define SDIOC_DL_BUFF_ADDRESS		0
-#define SDIOC_UP_BUFF_ADDRESS		0x4
-#define SDIOC_DL_BUFF_SIZE_OFFSET	0x8
-#define SDIOC_UP_BUFF_SIZE_OFFSET	0xC
-#define SDIOC_DL_WR_PTR		0x10
-#define SDIOC_DL_RD_PTR		0x14
-#define SDIOC_UL_WR_PTR		0x18
-#define SDIOC_UL_RD_PTR		0x1C
-#define SDIOC_EXIT_PTR			0x20
-#define SDIOC_OP_MODE_PTR		0x24
-#define SDIOC_PTRS_OFFSET		0x10
-#define SDIOC_PTR_REGS_SIZE		0x10
-#define SDIOC_CFG_REGS_SIZE		0x10
-#define WRITE_RETRIES			0xFFFFFFFF
-#define INPUT_SPEED			4800
-#define OUTPUT_SPEED			4800
-#define SDIOC_EXIT_CODE		0xDEADDEAD
-#define SLEEP_MS			10
-#define PRINTING_GAP			200
-#define TIMER_DURATION			10
-#define PUSH_TIMER_DURATION		5000
-#define MULTIPLE_RATIO			1
-#define MS_IN_SEC			1000
-#define BITS_IN_BYTE			8
-#define BYTES_IN_KB			1024
-#define WRITE_TILL_END_RETRIES		5
-#define SDIO_DLD_NORMAL_MODE_NAME	"SDIO DLD NORMAL MODE"
-#define SDIO_DLD_BOOT_TEST_MODE_NAME	"SDIO DLD BOOT TEST MODE"
-#define SDIO_DLD_AMSS_TEST_MODE_NAME	"SDIO DLD AMSS TEST MODE"
-#define TEST_NAME_MAX_SIZE		30
-#define PUSH_STRING
-#define SDIO_DLD_OUTGOING_BUFFER_SIZE	(48*1024*MULTIPLE_RATIO)
-
-/* FORWARD DECLARATIONS */
-static int sdio_dld_open(struct tty_struct *tty, struct file *file);
-static void sdio_dld_close(struct tty_struct *tty, struct file *file);
-static int sdio_dld_write_callback(struct tty_struct *tty,
-				   const unsigned char *buf, int count);
-static int sdio_dld_write_room(struct tty_struct *tty);
-static int sdio_dld_main_task(void *card);
-static void sdio_dld_print_info(void);
-#ifdef CONFIG_DEBUG_FS
-static int sdio_dld_debug_info_open(struct inode *inode, struct file *file);
-static ssize_t sdio_dld_debug_info_write(struct file *file,
-		const char __user *buf, size_t count, loff_t *ppos);
-#endif
-
-static void sdio_dld_tear_down(struct work_struct *work);
-DECLARE_WORK(cleanup, sdio_dld_tear_down);
-
-/* STRUCTURES AND TYPES */
-enum sdio_dld_op_mode {
-	 SDIO_DLD_NO_MODE = 0,
-	 SDIO_DLD_NORMAL_MODE = 1,
-	 SDIO_DLD_BOOT_TEST_MODE = 2,
-	 SDIO_DLD_AMSS_TEST_MODE = 3,
-	 SDIO_DLD_NUM_OF_MODES,
-};
-
-struct sdioc_reg_sequential_chunk_ptrs {
-	unsigned int dl_wr_ptr;
-	unsigned int dl_rd_ptr;
-	unsigned int up_wr_ptr;
-	unsigned int up_rd_ptr;
-};
-
-struct sdioc_reg_sequential_chunk_cfg {
-	unsigned int dl_buff_address;
-	unsigned int up_buff_address;
-	unsigned int dl_buff_size;
-	unsigned int ul_buff_size;
-};
-
-struct sdioc_reg {
-	unsigned int reg_val;
-	unsigned int reg_offset;
-};
-
-struct sdioc_reg_chunk {
-	struct sdioc_reg dl_buff_address;
-	struct sdioc_reg up_buff_address;
-	struct sdioc_reg dl_buff_size;
-	struct sdioc_reg ul_buff_size;
-	struct sdioc_reg dl_wr_ptr;
-	struct sdioc_reg dl_rd_ptr;
-	struct sdioc_reg up_wr_ptr;
-	struct sdioc_reg up_rd_ptr;
-	struct sdioc_reg good_to_exit_ptr;
-};
-
-struct sdio_data {
-	char *data;
-	int offset_read_p;
-	int offset_write_p;
-	int buffer_size;
-	int num_of_bytes_in_use;
-};
-
-struct sdio_dld_data {
-	struct sdioc_reg_chunk sdioc_reg;
-	struct sdio_data incoming_data;
-	struct sdio_data outgoing_data;
-};
-
-struct sdio_dld_wait_event {
-	wait_queue_head_t wait_event;
-	int wake_up_signal;
-};
-
-struct sdio_dld_task {
-	struct task_struct *dld_task;
-	const char *task_name;
-	struct sdio_dld_wait_event exit_wait;
-	atomic_t please_close;
-};
-
-#ifdef CONFIG_DEBUG_FS
-struct sdio_dloader_debug {
-	struct dentry *sdio_dld_debug_root;
-	struct dentry *sdio_al_dloader;
-};
-
-const struct file_operations sdio_dld_debug_info_ops = {
-	.open = sdio_dld_debug_info_open,
-	.write = sdio_dld_debug_info_write,
-};
-#endif
-
-struct sdio_downloader {
-	int sdioc_boot_func;
-	struct sdio_dld_wait_event write_callback_event;
-	struct sdio_dld_task dld_main_thread;
-	struct tty_driver *tty_drv;
-	struct tty_struct *tty_str;
-	struct sdio_dld_data sdio_dloader_data;
-	struct mmc_card *card;
-	int(*done_callback)(void);
-	struct sdio_dld_wait_event main_loop_event;
-	struct timer_list timer;
-	unsigned int poll_ms;
-	struct timer_list push_timer;
-	unsigned int push_timer_ms;
-	enum sdio_dld_op_mode op_mode;
-	char op_mode_name[TEST_NAME_MAX_SIZE];
-};
-
-struct sdio_dld_global_info {
-	int global_bytes_write_toio;
-	int global_bytes_write_tty;
-	int global_bytes_read_fromio;
-	int global_bytes_push_tty;
-	u64 start_time;
-	u64 end_time;
-	u64 delta_jiffies;
-	unsigned int time_msec;
-	unsigned int throughput;
-	int cl_dl_wr_ptr;
-	int cl_dl_rd_ptr;
-	int cl_up_wr_ptr;
-	int cl_up_rd_ptr;
-	int host_read_ptr;
-	int host_write_ptr;
-	int cl_dl_buffer_size;
-	int cl_up_buffer_size;
-	int host_outgoing_buffer_size;
-	int cl_dl_buffer_address;
-	int cl_up_buffer_address;
-};
-
-static const struct tty_operations sdio_dloader_tty_ops = {
-	.open = sdio_dld_open,
-	.close = sdio_dld_close,
-	.write = sdio_dld_write_callback,
-	.write_room = sdio_dld_write_room,
-};
-
-/* GLOBAL VARIABLES */
-struct sdio_downloader *sdio_dld;
-struct sdio_dld_global_info sdio_dld_info;
-static char outgoing_data_buffer[SDIO_DLD_OUTGOING_BUFFER_SIZE];
-
-static DEFINE_SPINLOCK(lock1);
-static unsigned long lock_flags1;
-static DEFINE_SPINLOCK(lock2);
-static unsigned long lock_flags2;
-
-static atomic_t sdio_dld_in_use = ATOMIC_INIT(0);
-static atomic_t sdio_dld_setup_done = ATOMIC_INIT(0);
-
-/*
- * sdio_op_mode sets the operation mode of the sdio_dloader -
- * it may be in NORMAL_MODE, BOOT_TEST_MODE or AMSS_TEST_MODE
- */
-static int sdio_op_mode = (int)SDIO_DLD_NORMAL_MODE;
-module_param(sdio_op_mode, int, 0);
-
-#ifdef CONFIG_DEBUG_FS
-
-struct sdio_dloader_debug sdio_dld_debug;
-
-#define ARR_SIZE 30000
-#define SDIO_DLD_DEBUGFS_INIT_VALUE	87654321
-#define SDIO_DLD_DEBUGFS_CASE_1_CODE	11111111
-#define SDIO_DLD_DEBUGFS_CASE_2_CODE	22222222
-#define SDIO_DLD_DEBUGFS_CASE_3_CODE	33333333
-#define SDIO_DLD_DEBUGFS_CASE_4_CODE	44444444
-#define SDIO_DLD_DEBUGFS_CASE_5_CODE	55555555
-#define SDIO_DLD_DEBUGFS_CASE_6_CODE	66666666
-#define SDIO_DLD_DEBUGFS_CASE_7_CODE	77777777
-#define SDIO_DLD_DEBUGFS_CASE_8_CODE	88888888
-#define SDIO_DLD_DEBUGFS_CASE_9_CODE	99999999
-#define SDIO_DLD_DEBUGFS_CASE_10_CODE	10101010
-#define SDIO_DLD_DEBUGFS_CASE_11_CODE	11001100
-#define SDIO_DLD_DEBUGFS_CASE_12_CODE	12001200
-#define SDIO_DLD_DEBUGFS_LOOP_WAIT	7
-#define SDIO_DLD_DEBUGFS_LOOP_WAKEUP	8
-#define SDIO_DLD_DEBUGFS_CB_WAIT	3
-#define SDIO_DLD_DEBUGFS_CB_WAKEUP	4
-
-static int curr_index;
-struct ptrs {
-	int h_w_ptr;
-	int h_r_ptr;
-	int c_u_w_ptr;
-	int c_u_r_ptr;
-	int code;
-	int h_has_to_send;
-	int c_has_to_receive;
-	int min_of;
-	int reserve2;
-	int tty_count;
-	int write_tty;
-	int write_toio;
-	int loop_wait_wake;
-	int cb_wait_wake;
-	int c_d_w_ptr;
-	int c_d_r_ptr;
-	int to_read;
-	int push_to_tty;
-	int global_tty_send;
-	int global_sdio_send;
-	int global_tty_received;
-	int global_sdio_received;
-	int reserve22;
-	int reserve23;
-	int reserve24;
-	int reserve25;
-	int reserve26;
-	int reserve27;
-	int reserve28;
-	int reserve29;
-	int reserve30;
-	int reserve31;
-};
-
-struct global_data {
-	int curr_i;
-	int duration_ms;
-	int global_bytes_sent;
-	int throughput_Mbs;
-	int host_outgoing_buffer_size_KB;
-	int client_up_buffer_size_KB;
-	int client_dl_buffer_size_KB;
-	int client_dl_buffer_address;
-	int client_up_buffer_address;
-	int global_bytes_received;
-	int global_bytes_pushed;
-	int reserve11;
-	int reserve12;
-	int reserve13;
-	int reserve14;
-	int reserve15;
-	int reserve16;
-	int reserve17;
-	int reserve18;
-	int reserve19;
-	int reserve20;
-	int reserve21;
-	int reserve22;
-	int reserve23;
-	int reserve24;
-	int reserve25;
-	int reserve26;
-	int reserve27;
-	int reserve28;
-	int reserve29;
-	int reserve30;
-	int reserve31;
-	struct ptrs ptr_array[ARR_SIZE];
-};
-
-static struct global_data gd;
-static struct debugfs_blob_wrapper blob;
-static struct dentry *root;
-static struct dentry *dld;
-
-struct debugfs_global {
-	int global_8k_has;
-	int global_9k_has;
-	int global_min;
-	int global_count;
-	int global_write_tty;
-	int global_write_toio;
-	int global_bytes_cb_tty;
-	int global_to_read;
-	int global_push_to_tty;
-	int global_tty_send;
-	int global_sdio_send;
-	int global_sdio_received;
-	int global_tty_push;
-};
-
-static struct debugfs_global debugfs_glob;
-
-static void update_standard_fields(int index)
-{
-
-	gd.ptr_array[index].global_tty_send =
-		sdio_dld_info.global_bytes_write_tty;
-	gd.ptr_array[index].global_sdio_send =
-		sdio_dld_info.global_bytes_write_toio;
-	gd.ptr_array[index].global_tty_received =
-		sdio_dld_info.global_bytes_push_tty;
-	gd.ptr_array[index].global_sdio_received =
-		sdio_dld_info.global_bytes_read_fromio;
-}
-
-static void update_gd(int code)
-{
-	struct sdioc_reg_chunk *reg_str =
-					&sdio_dld->sdio_dloader_data.sdioc_reg;
-	struct sdio_data *outgoing = &sdio_dld->sdio_dloader_data.outgoing_data;
-	int index = curr_index%ARR_SIZE;
-
-	gd.curr_i = curr_index;
-	gd.duration_ms = 0;
-	gd.global_bytes_sent = 0;
-	gd.throughput_Mbs = 0;
-	gd.host_outgoing_buffer_size_KB = 0;
-	gd.client_up_buffer_size_KB = 0;
-	gd.client_dl_buffer_size_KB = 0;
-	gd.client_dl_buffer_address = 0;
-	gd.client_up_buffer_address = 0;
-	gd.global_bytes_received = 0;
-	gd.global_bytes_pushed = 0;
-	gd.reserve11 = 0;
-	gd.reserve12 = 0;
-	gd.reserve13 = 0;
-	gd.reserve14 = 0;
-	gd.reserve15 = 0;
-	gd.reserve16 = 0;
-	gd.reserve17 = 0;
-	gd.reserve18 = 0;
-	gd.reserve19 = 0;
-	gd.reserve20 = 0;
-	gd.reserve21 = 0;
-	gd.reserve22 = 0;
-	gd.reserve23 = 0;
-	gd.reserve24 = 0;
-	gd.reserve25 = 0;
-	gd.reserve26 = 0;
-	gd.reserve27 = 0;
-	gd.reserve28 = 0;
-	gd.reserve29 = 0;
-	gd.reserve30 = 0;
-	gd.reserve31 = 0;
-
-	gd.ptr_array[index].h_w_ptr = SDIO_DLD_DEBUGFS_INIT_VALUE;	/*0*/
-	gd.ptr_array[index].h_r_ptr = SDIO_DLD_DEBUGFS_INIT_VALUE;	/*1*/
-	gd.ptr_array[index].c_u_w_ptr =	SDIO_DLD_DEBUGFS_INIT_VALUE;	/*2*/
-	gd.ptr_array[index].c_u_r_ptr =	SDIO_DLD_DEBUGFS_INIT_VALUE;	/*3*/
-	gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_INIT_VALUE;		/*4*/
-	gd.ptr_array[index].h_has_to_send = SDIO_DLD_DEBUGFS_INIT_VALUE;/*5*/
-	gd.ptr_array[index].c_has_to_receive =
-		SDIO_DLD_DEBUGFS_INIT_VALUE;				/*6*/
-	gd.ptr_array[index].min_of = SDIO_DLD_DEBUGFS_INIT_VALUE;	/*7*/
-	gd.ptr_array[index].reserve2 = SDIO_DLD_DEBUGFS_INIT_VALUE;	/*8*/
-	gd.ptr_array[index].tty_count = SDIO_DLD_DEBUGFS_INIT_VALUE;	/*9*/
-	gd.ptr_array[index].write_tty = SDIO_DLD_DEBUGFS_INIT_VALUE;	/*A*/
-	gd.ptr_array[index].write_toio = SDIO_DLD_DEBUGFS_INIT_VALUE;	/*B*/
-	gd.ptr_array[index].loop_wait_wake =
-		SDIO_DLD_DEBUGFS_INIT_VALUE;				/*C*/
-	gd.ptr_array[index].cb_wait_wake = SDIO_DLD_DEBUGFS_INIT_VALUE;	/*D*/
-	gd.ptr_array[index].c_d_w_ptr =	SDIO_DLD_DEBUGFS_INIT_VALUE;	/*E*/
-	gd.ptr_array[index].c_d_r_ptr =	SDIO_DLD_DEBUGFS_INIT_VALUE;	/*F*/
-	gd.ptr_array[index].to_read =
-		SDIO_DLD_DEBUGFS_INIT_VALUE;			/*0x10*/
-	gd.ptr_array[index].push_to_tty =
-		SDIO_DLD_DEBUGFS_INIT_VALUE;			/*0x11*/
-	gd.ptr_array[index].global_tty_send =
-		SDIO_DLD_DEBUGFS_INIT_VALUE;			/*0x12*/
-	gd.ptr_array[index].global_sdio_send =
-		SDIO_DLD_DEBUGFS_INIT_VALUE;			/*0x13*/
-	gd.ptr_array[index].global_tty_received =
-		SDIO_DLD_DEBUGFS_INIT_VALUE;			/*0x14*/
-	gd.ptr_array[index].global_sdio_received =
-		SDIO_DLD_DEBUGFS_INIT_VALUE;			/*0x15*/
-	gd.ptr_array[index].reserve22 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-	gd.ptr_array[index].reserve23 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-	gd.ptr_array[index].reserve24 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-	gd.ptr_array[index].reserve25 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-	gd.ptr_array[index].reserve26 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-	gd.ptr_array[index].reserve27 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-	gd.ptr_array[index].reserve28 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-	gd.ptr_array[index].reserve29 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-	gd.ptr_array[index].reserve30 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-	gd.ptr_array[index].reserve31 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-
-	switch (code) {
-	case SDIO_DLD_DEBUGFS_CASE_1_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_1_CODE;
-		gd.ptr_array[index].h_w_ptr = outgoing->offset_write_p;
-		gd.ptr_array[index].h_r_ptr = outgoing->offset_read_p;
-		gd.ptr_array[index].c_u_w_ptr =	reg_str->up_wr_ptr.reg_val;
-		gd.ptr_array[index].c_u_r_ptr =	reg_str->up_rd_ptr.reg_val;
-		gd.ptr_array[index].c_d_w_ptr =	reg_str->dl_wr_ptr.reg_val;
-		gd.ptr_array[index].c_d_r_ptr =	reg_str->dl_rd_ptr.reg_val;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_2_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_2_CODE;
-		gd.ptr_array[index].c_u_r_ptr = reg_str->up_rd_ptr.reg_val;
-		gd.ptr_array[index].c_u_w_ptr = reg_str->up_wr_ptr.reg_val;
-		gd.ptr_array[index].h_has_to_send = debugfs_glob.global_8k_has;
-		gd.ptr_array[index].c_has_to_receive =
-			debugfs_glob.global_9k_has;
-		gd.ptr_array[index].min_of = debugfs_glob.global_min;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_3_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_3_CODE;
-		gd.ptr_array[index].h_w_ptr = outgoing->offset_write_p;
-		gd.ptr_array[index].h_r_ptr = outgoing->offset_read_p;
-		gd.ptr_array[index].write_tty = debugfs_glob.global_write_tty;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_4_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_4_CODE;
-		gd.ptr_array[index].h_w_ptr = outgoing->offset_write_p;
-		gd.ptr_array[index].h_r_ptr = outgoing->offset_read_p;
-		gd.ptr_array[index].c_u_r_ptr = reg_str->up_rd_ptr.reg_val;
-		gd.ptr_array[index].c_u_w_ptr = reg_str->up_wr_ptr.reg_val;
-		gd.ptr_array[index].write_toio =
-			debugfs_glob.global_write_toio;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_5_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_5_CODE;
-		gd.ptr_array[index].tty_count = debugfs_glob.global_count;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_6_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_6_CODE;
-		gd.ptr_array[index].loop_wait_wake = 7;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_7_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_7_CODE;
-		gd.ptr_array[index].loop_wait_wake = 8;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_8_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_8_CODE;
-		gd.ptr_array[index].cb_wait_wake = 3;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_9_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_9_CODE;
-		gd.ptr_array[index].cb_wait_wake = 4;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_10_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_10_CODE;
-		gd.ptr_array[index].cb_wait_wake =
-			debugfs_glob.global_bytes_cb_tty;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_11_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_11_CODE;
-		gd.ptr_array[index].to_read = debugfs_glob.global_to_read;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_12_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_12_CODE;
-		gd.ptr_array[index].push_to_tty =
-			debugfs_glob.global_push_to_tty;
-		break;
-
-	default:
-		break;
-	}
-	update_standard_fields(index);
-	curr_index++;
-}
-
-static int bootloader_debugfs_init(void)
-{
-	/* /sys/kernel/debug/bootloader there will be dld_arr file */
-	root = debugfs_create_dir("bootloader", NULL);
-	if (!root) {
-		pr_info(MODULE_NAME ": %s - creating root dir "
-			"failed\n", __func__);
-		return -ENODEV;
-	}
-
-	blob.data = &gd;
-	blob.size = sizeof(struct global_data);
-	dld = debugfs_create_blob("dld_arr", S_IRUGO, root, &blob);
-	if (!dld) {
-		debugfs_remove_recursive(root);
-		pr_err(MODULE_NAME ": %s, failed to create debugfs entry\n",
-		       __func__);
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-/*
-* for triggering the sdio_dld info use:
-* echo 1 > /sys/kernel/debug/sdio_al_dld/sdio_al_dloader_info
-*/
-static int sdio_dld_debug_init(void)
-{
-	sdio_dld_debug.sdio_dld_debug_root =
-				debugfs_create_dir("sdio_al_dld", NULL);
-	if (!sdio_dld_debug.sdio_dld_debug_root) {
-		pr_err(MODULE_NAME ": %s - Failed to create folder. "
-		       "sdio_dld_debug_root is NULL",
-		       __func__);
-		return -ENOENT;
-	}
-
-	sdio_dld_debug.sdio_al_dloader = debugfs_create_file(
-					"sdio_al_dloader_info",
-					S_IRUGO | S_IWUGO,
-					sdio_dld_debug.sdio_dld_debug_root,
-					NULL,
-					&sdio_dld_debug_info_ops);
-
-	if (!sdio_dld_debug.sdio_al_dloader) {
-		pr_err(MODULE_NAME ": %s - Failed to create a file. "
-		       "sdio_al_dloader is NULL",
-		       __func__);
-		debugfs_remove(sdio_dld_debug.sdio_dld_debug_root);
-		sdio_dld_debug.sdio_dld_debug_root = NULL;
-		return -ENOENT;
-	}
-
-	return 0;
-}
-
-static int sdio_dld_debug_info_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return 0;
-}
-
-static ssize_t sdio_dld_debug_info_write(struct file *file,
-		const char __user *buf, size_t count, loff_t *ppos)
-{
-	sdio_dld_print_info();
-	return count;
-}
-#endif /* CONFIG_DEBUG_FS */
-
-static void sdio_dld_print_info(void)
-{
-
-	sdio_dld_info.end_time = get_jiffies_64(); /* read the current time */
-	sdio_dld_info.delta_jiffies =
-		sdio_dld_info.end_time - sdio_dld_info.start_time;
-	sdio_dld_info.time_msec = jiffies_to_msecs(sdio_dld_info.delta_jiffies);
-
-	sdio_dld_info.throughput = sdio_dld_info.global_bytes_write_toio *
-		BITS_IN_BYTE / sdio_dld_info.time_msec;
-	sdio_dld_info.throughput /= MS_IN_SEC;
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - DURATION IN MSEC = %d\n",
-		__func__,
-		sdio_dld_info.time_msec);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - BYTES WRITTEN ON SDIO BUS "
-			    "= %d...BYTES SENT BY TTY = %d",
-		__func__,
-	       sdio_dld_info.global_bytes_write_toio,
-	       sdio_dld_info.global_bytes_write_tty);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - BYTES RECEIVED ON SDIO BUS "
-			    "= %d...BYTES SENT TO TTY = %d",
-		__func__,
-		sdio_dld_info.global_bytes_read_fromio,
-		sdio_dld_info.global_bytes_push_tty);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - THROUGHPUT=%d Mbit/Sec",
-		__func__, sdio_dld_info.throughput);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - CLIENT DL_BUFFER_SIZE=%d"
-		" KB..CLIENT UL_BUFFER=%d KB\n",
-		__func__,
-		sdio_dld_info.cl_dl_buffer_size/BYTES_IN_KB,
-		sdio_dld_info.cl_up_buffer_size/BYTES_IN_KB);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - HOST OUTGOING BUFFER_SIZE"
-			    "=%d KB",
-		__func__,
-		sdio_dld_info.host_outgoing_buffer_size/BYTES_IN_KB);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - CLIENT DL BUFFER "
-		 "ADDRESS = 0x%x", __func__,
-		sdio_dld_info.cl_dl_buffer_address);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - CLIENT UP BUFFER "
-		"ADDRESS = 0x%x",
-		__func__,
-		sdio_dld_info.cl_up_buffer_address);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - CLIENT - UPLINK BUFFER - "
-		"READ POINTER = %d", __func__,
-		sdio_dld_info.cl_up_rd_ptr);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - CLIENT - UPLINK BUFFER - "
-		"WRITE POINTER = %d", __func__,
-		sdio_dld_info.cl_up_wr_ptr);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - CLIENT - DOWNLINK BUFFER - "
-		"READ POINTER = %d", __func__,
-		sdio_dld_info.cl_dl_rd_ptr);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - CLIENT - DOWNLINK BUFFER - "
-		"WRITE POINTER = %d", __func__,
-		sdio_dld_info.cl_dl_wr_ptr);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - HOST - OUTGOING BUFFER - "
-		"READ POINTER = %d", __func__,
-		sdio_dld_info.host_read_ptr);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - HOST - OUTGOING BUFFER - "
-		"WRITE POINTER = %d", __func__,
-		sdio_dld_info.host_write_ptr);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - END DEBUG INFO", __func__);
-}
-
-/**
-  * sdio_dld_set_op_mode
-  * sets the op_mode and the name of the op_mode. Also, in case
-  * it's invalid mode sets op_mode to SDIO_DLD_NORMAL_MODE
-  *
-  * @op_mode: the operation mode to be set
-  * @return NONE
-  */
-static void sdio_dld_set_op_mode(enum sdio_dld_op_mode op_mode)
-{
-	sdio_dld->op_mode = op_mode;
-
-	switch (op_mode) {
-	case SDIO_DLD_NORMAL_MODE:
-		memcpy(sdio_dld->op_mode_name,
-		       SDIO_DLD_NORMAL_MODE_NAME, TEST_NAME_MAX_SIZE);
-		break;
-	case SDIO_DLD_BOOT_TEST_MODE:
-		memcpy(sdio_dld->op_mode_name,
-		       SDIO_DLD_BOOT_TEST_MODE_NAME, TEST_NAME_MAX_SIZE);
-		break;
-	case SDIO_DLD_AMSS_TEST_MODE:
-		memcpy(sdio_dld->op_mode_name,
-		       SDIO_DLD_AMSS_TEST_MODE_NAME, TEST_NAME_MAX_SIZE);
-		break;
-	default:
-		sdio_dld->op_mode = SDIO_DLD_NORMAL_MODE;
-		pr_err(MODULE_NAME ": %s - Invalid Op_Mode = %d. Settings "
-		       "Op_Mode to default - NORMAL_MODE\n",
-		       __func__, op_mode);
-		memcpy(sdio_dld->op_mode_name,
-		       SDIO_DLD_NORMAL_MODE_NAME, TEST_NAME_MAX_SIZE);
-		break;
-	}
-
-	if (sdio_dld->op_mode_name != NULL) {
-		pr_info(MODULE_NAME ": %s - FLASHLESS BOOT - Op_Mode is set to "
-			"%s\n", __func__, sdio_dld->op_mode_name);
-	} else {
-		pr_info(MODULE_NAME ": %s - FLASHLESS BOOT - op_mode_name is "
-			"NULL\n", __func__);
-	}
-}
-
-/**
-  * sdio_dld_allocate_local_buffers
-  * allocates local outgoing and incoming buffers and also sets
-  * threshold for outgoing data.
-  *
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_dld_allocate_local_buffers(void)
-{
-	struct sdioc_reg_chunk *reg_str = &sdio_dld->sdio_dloader_data.
-		sdioc_reg;
-	struct sdio_data *outgoing = &sdio_dld->sdio_dloader_data.outgoing_data;
-	struct sdio_data *incoming = &sdio_dld->sdio_dloader_data.incoming_data;
-
-	incoming->data =
-		kzalloc(reg_str->dl_buff_size.reg_val, GFP_KERNEL);
-
-	if (!incoming->data) {
-		pr_err(MODULE_NAME ": %s - param ""incoming->data"" is NULL. "
-		       "Couldn't allocate incoming_data local buffer\n",
-		       __func__);
-		return -ENOMEM;
-	}
-
-	incoming->buffer_size = reg_str->dl_buff_size.reg_val;
-
-	outgoing->data = outgoing_data_buffer;
-
-	outgoing->buffer_size = SDIO_DLD_OUTGOING_BUFFER_SIZE;
-
-	if (outgoing->buffer_size !=
-	    reg_str->ul_buff_size.reg_val*MULTIPLE_RATIO) {
-		pr_err(MODULE_NAME ": %s - HOST outgoing buffer size (%d bytes)"
-		       "must be a multiple of ClIENT uplink buffer size (%d "
-		       "bytes). HOST_SIZE == n*CLIENT_SIZE.(n=1,2,3...)\n",
-		       __func__,
-		       SDIO_DLD_OUTGOING_BUFFER_SIZE,
-		       reg_str->ul_buff_size.reg_val);
-		kfree(incoming->data);
-		return -EINVAL;
-	}
-
-	/* keep sdio_dld_info up to date */
-	sdio_dld_info.host_outgoing_buffer_size = outgoing->buffer_size;
-
-	return 0;
-}
-
-/**
-  * sdio_dld_dealloc_local_buffers frees incoming and outgoing
-  * buffers.
-  *
-  * @return None.
-  */
-static void sdio_dld_dealloc_local_buffers(void)
-{
-	kfree((void *)sdio_dld->sdio_dloader_data.incoming_data.data);
-}
-
-/**
-  * mailbox_to_seq_chunk_read_cfg
-  * reads 4 configuration registers of mailbox from str_func, as
-  * a sequentail chunk in memory, and updates global struct
-  * accordingly.
-  *
-  * @str_func: a pointer to func struct.
-  * @return 0 on success or negative value on error.
-  */
-static int mailbox_to_seq_chunk_read_cfg(struct sdio_func *str_func)
-{
-	struct sdioc_reg_sequential_chunk_cfg seq_chunk;
-	struct sdioc_reg_chunk *reg = &sdio_dld->sdio_dloader_data.sdioc_reg;
-	int status = 0;
-
-	if (!str_func) {
-		pr_err(MODULE_NAME ": %s - param ""str_func"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	sdio_claim_host(str_func);
-
-	/* reading SDIOC_MAILBOX_SIZE bytes from SDIOC_MAILBOX_ADDRESS */
-	status = sdio_memcpy_fromio(str_func,
-				    (void *)&seq_chunk,
-				    SDIOC_MAILBOX_ADDRESS,
-				    SDIOC_CFG_REGS_SIZE);
-	if (status) {
-		pr_err(MODULE_NAME ": %s - sdio_memcpy_fromio()"
-		       " READING CFG MAILBOX failed. status=%d.\n",
-		       __func__, status);
-	}
-
-	sdio_release_host(str_func);
-
-	reg->dl_buff_address.reg_val = seq_chunk.dl_buff_address;
-	reg->up_buff_address.reg_val = seq_chunk.up_buff_address;
-	reg->dl_buff_size.reg_val = seq_chunk.dl_buff_size;
-	reg->ul_buff_size.reg_val = seq_chunk.ul_buff_size;
-
-	/* keep sdio_dld_info up to date */
-	sdio_dld_info.cl_dl_buffer_size = seq_chunk.dl_buff_size;
-	sdio_dld_info.cl_up_buffer_size = seq_chunk.ul_buff_size;
-	sdio_dld_info.cl_dl_buffer_address = seq_chunk.dl_buff_address;
-	sdio_dld_info.cl_up_buffer_address = seq_chunk.up_buff_address;
-
-	return status;
-}
-
-/**
-  * mailbox_to_seq_chunk_read_ptrs
-  * reads 4 pointers registers of mailbox from str_func, as a
-  * sequentail chunk in memory, and updates global struct
-  * accordingly.
-  *
-  * @str_func: a pointer to func struct.
-  * @return 0 on success or negative value on error.
-  */
-static int mailbox_to_seq_chunk_read_ptrs(struct sdio_func *str_func)
-{
-	struct sdioc_reg_sequential_chunk_ptrs seq_chunk;
-	struct sdioc_reg_chunk *reg = &sdio_dld->sdio_dloader_data.sdioc_reg;
-	int status = 0;
-
-	struct sdio_data *outgoing = &sdio_dld->sdio_dloader_data.outgoing_data;
-	static int counter = 1;
-	static int offset_write_p;
-	static int offset_read_p;
-	static int up_wr_ptr;
-	static int up_rd_ptr;
-	static int dl_wr_ptr;
-	static int dl_rd_ptr;
-
-	if (!str_func) {
-		pr_err(MODULE_NAME ": %s - param ""str_func"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	sdio_claim_host(str_func);
-
-	/* reading SDIOC_MAILBOX_SIZE bytes from SDIOC_MAILBOX_ADDRESS */
-	status = sdio_memcpy_fromio(str_func,
-				    (void *)&seq_chunk,
-				    SDIOC_PTRS_OFFSET,
-				    SDIOC_PTR_REGS_SIZE);
-	if (status) {
-		pr_err(MODULE_NAME ": %s - sdio_memcpy_fromio()"
-		       " READING PTRS MAILBOX failed. status=%d.\n",
-		       __func__, status);
-	}
-
-	sdio_release_host(str_func);
-
-	reg->dl_rd_ptr.reg_val = seq_chunk.dl_rd_ptr;
-	reg->dl_wr_ptr.reg_val = seq_chunk.dl_wr_ptr;
-	reg->up_rd_ptr.reg_val = seq_chunk.up_rd_ptr;
-	reg->up_wr_ptr.reg_val = seq_chunk.up_wr_ptr;
-
-	/* keeping sdio_dld_info up to date */
-	sdio_dld_info.cl_dl_rd_ptr = seq_chunk.dl_rd_ptr;
-	sdio_dld_info.cl_dl_wr_ptr = seq_chunk.dl_wr_ptr;
-	sdio_dld_info.cl_up_rd_ptr = seq_chunk.up_rd_ptr;
-	sdio_dld_info.cl_up_wr_ptr = seq_chunk.up_wr_ptr;
-
-
-	/* DEBUG - if there was a change in value */
-	if ((offset_write_p != outgoing->offset_write_p) ||
-	    (offset_read_p != outgoing->offset_read_p) ||
-	    (up_wr_ptr != reg->up_wr_ptr.reg_val) ||
-	    (up_rd_ptr != reg->up_rd_ptr.reg_val) ||
-	    (dl_wr_ptr != reg->dl_wr_ptr.reg_val) ||
-	    (dl_rd_ptr != reg->dl_rd_ptr.reg_val) ||
-	    (counter % PRINTING_GAP == 0)) {
-		counter = 1;
-		pr_debug(MODULE_NAME ": %s MailBox pointers: BLOCK_SIZE=%d, "
-			 "hw=%d, hr=%d, cuw=%d, cur=%d, cdw=%d, cdr=%d\n",
-			 __func__,
-			 SDIO_DL_BLOCK_SIZE,
-			 outgoing->offset_write_p,
-			 outgoing->offset_read_p,
-			 reg->up_wr_ptr.reg_val,
-			 reg->up_rd_ptr.reg_val,
-			 reg->dl_wr_ptr.reg_val,
-			 reg->dl_rd_ptr.reg_val);
-
-#ifdef CONFIG_DEBUG_FS
-		update_gd(SDIO_DLD_DEBUGFS_CASE_1_CODE);
-#endif
-		/* update static variables */
-		offset_write_p = outgoing->offset_write_p;
-		offset_read_p =	outgoing->offset_read_p;
-		up_wr_ptr = reg->up_wr_ptr.reg_val;
-		up_rd_ptr = reg->up_rd_ptr.reg_val;
-		dl_wr_ptr = reg->dl_wr_ptr.reg_val;
-		dl_rd_ptr = reg->dl_rd_ptr.reg_val;
-	} else {
-		counter++;
-	}
-	return status;
-}
-
-/**
-  * sdio_dld_init_func
-  * enables the sdio func, and sets the func block size.
-  *
-  * @str_func: a pointer to func struct.
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_dld_init_func(struct sdio_func *str_func)
-{
-	int status1 = 0;
-	int status2 = 0;
-
-	if (!str_func) {
-		pr_err(MODULE_NAME ": %s - param ""str_func"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	sdio_claim_host(str_func);
-
-	status1 = sdio_enable_func(str_func);
-	if (status1) {
-		sdio_release_host(str_func);
-		pr_err(MODULE_NAME ": %s - sdio_enable_func() failed. "
-		       "status=%d\n", __func__, status1);
-		return status1;
-	}
-
-	status2 = sdio_set_block_size(str_func, SDIO_DL_BLOCK_SIZE);
-	if (status2) {
-		pr_err(MODULE_NAME ": %s - sdio_set_block_size() failed. "
-		       "status=%d\n", __func__, status2);
-		status1 = sdio_disable_func(str_func);
-		if (status1) {
-			pr_err(MODULE_NAME ": %s - sdio_disable_func() "
-		       "failed. status=%d\n", __func__, status1);
-		}
-		sdio_release_host(str_func);
-		return status2;
-	}
-
-	sdio_release_host(str_func);
-	str_func->max_blksize = SDIO_DL_BLOCK_SIZE;
-	return 0;
-}
-
-/**
-  * sdio_dld_allocate_buffers
-  * initializes the sdio func, and then reads the mailbox, in
-  * order to allocate incoming and outgoing buffers according to
-  * the size that was read from the mailbox.
-  *
-  * @str_func: a pointer to func struct.
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_dld_allocate_buffers(struct sdio_func *str_func)
-{
-	int status = 0;
-
-	if (!str_func) {
-		pr_err(MODULE_NAME ": %s - param ""str_func"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	status = mailbox_to_seq_chunk_read_cfg(str_func);
-	if (status) {
-		pr_err(MODULE_NAME ": %s - Failure in Function "
-		       "mailbox_to_seq_chunk_read_cfg(). status=%d\n",
-		       __func__, status);
-		return status;
-	}
-
-	status = sdio_dld_allocate_local_buffers();
-	if (status) {
-		pr_err(MODULE_NAME ": %s - Failure in Function "
-		       "sdio_dld_allocate_local_buffers(). status=%d\n",
-		       __func__, status);
-		return status;
-	}
-	return 0;
-}
-
-/**
-  * sdio_dld_create_thread
-  * creates thread and wakes it up.
-  *
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_dld_create_thread(void)
-{
-	sdio_dld->dld_main_thread.task_name = SDIO_DL_MAIN_THREAD_NAME;
-
-	sdio_dld->dld_main_thread.dld_task =
-		kthread_create(sdio_dld_main_task,
-			       (void *)(sdio_dld->card),
-			       sdio_dld->dld_main_thread.task_name);
-
-	if (IS_ERR(sdio_dld->dld_main_thread.dld_task)) {
-		pr_err(MODULE_NAME ": %s - kthread_create() failed\n",
-			__func__);
-		return -ENOMEM;
-	}
-	wake_up_process(sdio_dld->dld_main_thread.dld_task);
-	return 0;
-}
-
-/**
-  * start_timer
-  * sets the timer and starts.
-  *
-  * @timer: the timer to configure and add
-  * @ms: the ms until it expires
-  * @return None.
-  */
-static void start_timer(struct timer_list *timer, unsigned int ms)
-{
-	if ((ms == 0) || (timer == NULL)) {
-		pr_err(MODULE_NAME ": %s - invalid parameter", __func__);
-	} else {
-		timer->expires = jiffies +
-			msecs_to_jiffies(ms);
-		add_timer(timer);
-	}
-}
-
-/**
-  * sdio_dld_timer_handler
-  * this is the timer handler. whenever it is invoked, it wakes
-  * up the main loop task, and the write callback, and starts
-  * the timer again.
-  *
-  * @data: a pointer to the tty device driver structure.
-  * @return None.
-  */
-
-static void sdio_dld_timer_handler(unsigned long data)
-{
-	pr_debug(MODULE_NAME " Timer Expired\n");
-	spin_lock_irqsave(&lock2, lock_flags2);
-	if (sdio_dld->main_loop_event.wake_up_signal == 0) {
-		sdio_dld->main_loop_event.wake_up_signal = 1;
-		wake_up(&sdio_dld->main_loop_event.wait_event);
-	}
-	spin_unlock_irqrestore(&lock2, lock_flags2);
-
-	sdio_dld->write_callback_event.wake_up_signal = 1;
-	wake_up(&sdio_dld->write_callback_event.wait_event);
-
-	start_timer(&sdio_dld->timer, sdio_dld->poll_ms);
-}
-
-/**
-  * sdio_dld_push_timer_handler
-  * this is a timer handler of the push_timer.
-  *
-  * @data: a pointer to the tty device driver structure.
-  * @return None.
-  */
-static void sdio_dld_push_timer_handler(unsigned long data)
-{
-	pr_err(MODULE_NAME " %s - Push Timer Expired... Trying to "
-		"push data to TTY Core for over then %d ms.\n",
-		__func__, sdio_dld->push_timer_ms);
-}
-
-/**
-  * sdio_dld_open
-  * this is the open callback of the tty driver.
-  * it initializes the sdio func, allocates the buffers, and
-  * creates the main thread.
-  *
-  * @tty: a pointer to the tty struct.
-  * @file: file descriptor.
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_dld_open(struct tty_struct *tty, struct file *file)
-{
-	int status = 0;
-	int func_in_array =
-		REAL_FUNC_TO_FUNC_IN_ARRAY(sdio_dld->sdioc_boot_func);
-	struct sdio_func *str_func = sdio_dld->card->sdio_func[func_in_array];
-
-	if (atomic_read(&sdio_dld_in_use) == 1)
-		return -EBUSY;
-
-	atomic_set(&sdio_dld_in_use, 1);
-	sdio_dld->tty_str = tty;
-	sdio_dld->tty_str->low_latency = 1;
-	sdio_dld->tty_str->icanon = 0;
-	set_bit(TTY_NO_WRITE_SPLIT, &sdio_dld->tty_str->flags);
-
-	pr_info(MODULE_NAME ": %s, TTY DEVICE FOR FLASHLESS BOOT OPENED\n",
-	       __func__);
-	sdio_dld_info.start_time = get_jiffies_64(); /* read the current time */
-
-	if (!tty) {
-		pr_err(MODULE_NAME ": %s - param ""tty"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!str_func) {
-		pr_err(MODULE_NAME ": %s - param ""str_func"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	atomic_set(&sdio_dld->dld_main_thread.please_close, 0);
-	sdio_dld->dld_main_thread.exit_wait.wake_up_signal = 0;
-
-	status = sdio_dld_allocate_buffers(str_func);
-	if (status) {
-		pr_err(MODULE_NAME ": %s, failed in "
-		       "sdio_dld_allocate_buffers(). status=%d\n",
-		       __func__, status);
-		return status;
-	}
-
-	/* init waiting event of the write callback */
-	init_waitqueue_head(&sdio_dld->write_callback_event.wait_event);
-
-	/* init waiting event of the main loop */
-	init_waitqueue_head(&sdio_dld->main_loop_event.wait_event);
-
-	/* configure and init the timer */
-	sdio_dld->poll_ms = TIMER_DURATION;
-	init_timer(&sdio_dld->timer);
-	sdio_dld->timer.data = (unsigned long) sdio_dld;
-	sdio_dld->timer.function = sdio_dld_timer_handler;
-	sdio_dld->timer.expires = jiffies +
-		msecs_to_jiffies(sdio_dld->poll_ms);
-	add_timer(&sdio_dld->timer);
-
-	sdio_dld->push_timer_ms = PUSH_TIMER_DURATION;
-	init_timer(&sdio_dld->push_timer);
-	sdio_dld->push_timer.data = (unsigned long) sdio_dld;
-	sdio_dld->push_timer.function = sdio_dld_push_timer_handler;
-
-	status = sdio_dld_create_thread();
-	if (status) {
-		del_timer_sync(&sdio_dld->timer);
-		del_timer_sync(&sdio_dld->push_timer);
-		sdio_dld_dealloc_local_buffers();
-		pr_err(MODULE_NAME ": %s, failed in sdio_dld_create_thread()."
-				   "status=%d\n", __func__, status);
-		return status;
-	}
-	return 0;
-}
-
-/**
-  * sdio_dld_close
-  * this is the close callback of the tty driver. it requests
-  * the main thread to exit, and waits for notification of it.
-  * it also de-allocates the buffers, and unregisters the tty
-  * driver and device.
-  *
-  * @tty: a pointer to the tty struct.
-  * @file: file descriptor.
-  * @return None.
-  */
-static void sdio_dld_close(struct tty_struct *tty, struct file *file)
-{
-	struct sdioc_reg_chunk *reg = &sdio_dld->sdio_dloader_data.sdioc_reg;
-
-	/* informing the SDIOC that it can exit boot phase */
-	sdio_dld->sdio_dloader_data.sdioc_reg.good_to_exit_ptr.reg_val =
-		SDIOC_EXIT_CODE;
-
-	atomic_set(&sdio_dld->dld_main_thread.please_close, 1);
-
-	pr_debug(MODULE_NAME ": %s - CLOSING - WAITING...", __func__);
-
-	wait_event(sdio_dld->dld_main_thread.exit_wait.wait_event,
-		   sdio_dld->dld_main_thread.exit_wait.wake_up_signal);
-	pr_debug(MODULE_NAME ": %s - CLOSING - WOKE UP...", __func__);
-
-#ifdef CONFIG_DEBUG_FS
-	gd.curr_i = curr_index;
-	gd.duration_ms = sdio_dld_info.time_msec;
-	gd.global_bytes_sent = sdio_dld_info.global_bytes_write_toio;
-	gd.global_bytes_received = 0;
-	gd.throughput_Mbs = sdio_dld_info.throughput;
-	gd.host_outgoing_buffer_size_KB = sdio_dld->sdio_dloader_data.
-		outgoing_data.buffer_size/BYTES_IN_KB;
-	gd.client_up_buffer_size_KB = reg->ul_buff_size.reg_val/BYTES_IN_KB;
-	gd.client_dl_buffer_size_KB = reg->dl_buff_size.reg_val/BYTES_IN_KB;
-	gd.client_dl_buffer_address = reg->dl_buff_address.reg_val;
-	gd.client_up_buffer_address = reg->up_buff_address.reg_val;
-	gd.global_bytes_received = sdio_dld_info.global_bytes_read_fromio;
-	gd.global_bytes_pushed = sdio_dld_info.global_bytes_push_tty;
-#endif
-
-	/* saving register values before deallocating sdio_dld
-	   in order to use it in sdio_dld_print_info() through shell command */
-	sdio_dld_info.cl_dl_rd_ptr = reg->dl_rd_ptr.reg_val;
-	sdio_dld_info.cl_dl_wr_ptr = reg->dl_wr_ptr.reg_val;
-	sdio_dld_info.cl_up_rd_ptr = reg->up_rd_ptr.reg_val;
-	sdio_dld_info.cl_up_wr_ptr = reg->up_wr_ptr.reg_val;
-
-	sdio_dld_info.host_read_ptr =
-		sdio_dld->sdio_dloader_data.outgoing_data.offset_read_p;
-
-	sdio_dld_info.host_write_ptr =
-		sdio_dld->sdio_dloader_data.outgoing_data.offset_write_p;
-
-	sdio_dld_info.cl_dl_buffer_size =
-		sdio_dld->sdio_dloader_data.sdioc_reg.dl_buff_size.reg_val;
-
-	sdio_dld_info.cl_up_buffer_size =
-		sdio_dld->sdio_dloader_data.sdioc_reg.ul_buff_size.reg_val;
-
-	sdio_dld_info.host_outgoing_buffer_size =
-		sdio_dld->sdio_dloader_data.outgoing_data.buffer_size;
-
-	sdio_dld_info.cl_dl_buffer_address =
-		sdio_dld->sdio_dloader_data.sdioc_reg.dl_buff_address.reg_val;
-
-	sdio_dld_info.cl_up_buffer_address =
-		sdio_dld->sdio_dloader_data.sdioc_reg.up_buff_address.reg_val;
-
-	sdio_dld_print_info();
-
-	if (sdio_dld->done_callback)
-		sdio_dld->done_callback();
-
-	schedule_work(&cleanup);
-	pr_info(MODULE_NAME ": %s - Bootloader done, returning...", __func__);
-}
-
-/**
-  * writing_size_to_buf
-  * writes from src buffer into dest buffer. if dest buffer
-  * reaches its end, rollover happens.
-  *
-  * @dest: destination buffer.
-  * @src: source buffer.
-  * @dest_wr_ptr: writing pointer in destination buffer.
-  * @dest_size: destination buffer size.
-  * @dest_rd_ptr: reading pointer in destination buffer.
-  * @size_to_write: size of bytes to write.
-  * @return -how many bytes actually written to destination
-  * buffer.
-  *
-  * ONLY destination buffer is treated as cyclic buffer.
-  */
-static int writing_size_to_buf(char *dest,
-			       const unsigned char *src,
-			       int *dest_wr_ptr,
-			       int dest_size,
-			       int dest_rd_ptr,
-			       int size_to_write)
-{
-	int actually_written = 0;
-	int size_to_add = *dest_wr_ptr;
-
-	if (!dest) {
-		pr_err(MODULE_NAME ": %s - param ""dest"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!src) {
-		pr_err(MODULE_NAME ": %s - param ""src"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!dest_wr_ptr) {
-		pr_err(MODULE_NAME ": %s - param ""dest_wr_ptr"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	for (actually_written = 0 ;
-	      actually_written < size_to_write ; ++actually_written) {
-		/* checking if buffer is full */
-		if (((size_to_add + 1) % dest_size) == dest_rd_ptr) {
-			*dest_wr_ptr = size_to_add;
-			return actually_written;
-		}
-
-		dest[size_to_add] = src[actually_written];
-		size_to_add = (size_to_add+1)%dest_size;
-	}
-
-	*dest_wr_ptr = size_to_add;
-
-	return actually_written;
-}
-
-/**
-  * sdioc_bytes_till_end_of_buffer - this routine calculates how many bytes are
-  * empty/in use. if calculation requires rap around - it will ignore the rap
-  * around and will do the calculation untill the end of the buffer
-  *
-  * @write_ptr: writing pointer.
-  * @read_ptr: reading pointer.
-  * @total_size: buffer size.
-  * @free_bytes: return value-how many free bytes.
-  * @bytes_in_use: return value-how many bytes in use.
-  * @return 0 on success or negative value on error.
-  *
-  * buffer is treated as a cyclic buffer.
-  */
-static int sdioc_bytes_till_end_of_buffer(int write_ptr,
-					  int read_ptr,
-					  int total_size,
-					  int *free_bytes,
-					  int *bytes_in_use)
-{
-	if (!free_bytes) {
-		pr_err(MODULE_NAME ": %s - param ""free_bytes"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!bytes_in_use) {
-		pr_err(MODULE_NAME ": %s - param ""bytes_in_use"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (write_ptr >= read_ptr) {
-		if (read_ptr == 0)
-			*free_bytes = total_size - write_ptr - 1;
-		else
-			*free_bytes = total_size - write_ptr;
-		*bytes_in_use = write_ptr - read_ptr;
-	} else {
-		*bytes_in_use = total_size - read_ptr;
-		*free_bytes = read_ptr - write_ptr - 1;
-	}
-
-	return  0;
-}
-
-/**
-  * sdioc_bytes_free_in_buffer
-  * this routine calculates how many bytes are free in a buffer
-  * and how many are in use, according to its reading and
-  * writing pointer offsets.
-  *
-  * @write_ptr: writing pointer.
-  * @read_ptr: reading pointer.
-  * @total_size: buffer size.
-  * @free_bytes: return value-how many free bytes in buffer.
-  * @bytes_in_use: return value-how many bytes in use in buffer.
-  * @return 0 on success or negative value on error.
-  *
-  * buffer is treated as a cyclic buffer.
-  */
-static int sdioc_bytes_free_in_buffer(int write_ptr,
-				      int read_ptr,
-				      int total_size,
-				      int *free_bytes,
-				      int *bytes_in_use)
-{
-	if (!free_bytes) {
-		pr_err(MODULE_NAME ": %s - param ""free_bytes"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!bytes_in_use) {
-		pr_err(MODULE_NAME ": %s - param ""bytes_in_use"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	/* if pointers equel - buffers are empty. nothing to read/write */
-
-	if (write_ptr >= read_ptr)
-		*bytes_in_use = write_ptr - read_ptr;
-	else
-		*bytes_in_use = total_size - (read_ptr - write_ptr);
-
-	*free_bytes = total_size - *bytes_in_use - 1;
-
-	return 0;
-}
-
-/*
-* sdio_dld_write_room
-*
-* This is the write_room function of the tty driver.
-*
-* @tty: pointer to tty struct.
-* @return free bytes for write.
-*
-*/
-static int sdio_dld_write_room(struct tty_struct *tty)
-{
-	return sdio_dld->sdio_dloader_data.outgoing_data.buffer_size;
-}
-
-/**
-  * sdio_dld_write_callback
-  * this is the write callback of the tty driver.
-  *
-  * @tty: pointer to tty struct.
-  * @buf: buffer to write from.
-  * @count: number of bytes to write.
-  * @return bytes written or negative value on error.
-  *
-  * if destination buffer has not enough room for the incoming
-  * data, returns an error.
-  */
-static int sdio_dld_write_callback(struct tty_struct *tty,
-				   const unsigned char *buf, int count)
-{
-	struct sdio_data *outgoing = &sdio_dld->sdio_dloader_data.outgoing_data;
-	int dst_free_bytes = 0;
-	int dummy = 0;
-	int status = 0;
-	int bytes_written = 0;
-	int total_written = 0;
-	static int write_retry;
-	int pending_to_write = count;
-
-#ifdef CONFIG_DEBUG_FS
-	debugfs_glob.global_count = count;
-	update_gd(SDIO_DLD_DEBUGFS_CASE_5_CODE);
-#endif
-
-	pr_debug(MODULE_NAME ": %s - WRITING CALLBACK CALLED WITH %d bytes\n",
-		 __func__, count);
-
-	if (!outgoing->data) {
-		pr_err(MODULE_NAME ": %s - param ""outgoing->data"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	pr_debug(MODULE_NAME ": %s - WRITE CALLBACK size to write to outgoing"
-		 " buffer %d\n", __func__, count);
-
-	/* as long as there is something to write to outgoing buffer */
-	do {
-		int bytes_to_write = 0;
-		status = sdioc_bytes_free_in_buffer(
-			outgoing->offset_write_p,
-			outgoing->offset_read_p,
-			outgoing->buffer_size,
-			&dst_free_bytes,
-			&dummy);
-
-		if (status) {
-			pr_err(MODULE_NAME ": %s - Failure in Function "
-			       "sdioc_bytes_free_in_buffer(). status=%d\n",
-			       __func__, status);
-			return status;
-		}
-
-		/*
-		 * if there is free room in outgoing buffer
-		 * lock mutex and request trigger notification from the main
-		 * task. unlock mutex, and wait for sinal
-		 */
-		if (dst_free_bytes > 0) {
-			write_retry = 0;
-			/*
-			 * if there is more data to write to outgoing buffer
-			 * than it can receive, wait for signal from main task
-			 */
-			if (pending_to_write > dst_free_bytes) {
-
-				/* sampling updated dst_free_bytes */
-				status = sdioc_bytes_free_in_buffer(
-				outgoing->offset_write_p,
-				outgoing->offset_read_p,
-				outgoing->buffer_size,
-				&dst_free_bytes,
-				&dummy);
-
-				if (status) {
-					pr_err(MODULE_NAME ": %s - Failure in "
-							   "Function "
-					       "sdioc_bytes_free_in_buffer(). "
-					       "status=%d\n", __func__, status);
-					return status;
-				}
-			}
-
-			bytes_to_write = min(pending_to_write, dst_free_bytes);
-			bytes_written =
-				writing_size_to_buf(outgoing->data,
-						    buf+total_written,
-						    &outgoing->offset_write_p,
-						    outgoing->buffer_size,
-						    outgoing->offset_read_p,
-						    bytes_to_write);
-
-			/* keeping sdio_dld_info up to date */
-			sdio_dld_info.host_write_ptr =
-				sdio_dld->sdio_dloader_data.
-					    outgoing_data.offset_write_p;
-
-#ifdef CONFIG_DEBUG_FS
-			debugfs_glob.global_write_tty = bytes_written;
-			update_gd(SDIO_DLD_DEBUGFS_CASE_3_CODE);
-#endif
-			sdio_dld_info.global_bytes_write_tty += bytes_written;
-
-			spin_lock_irqsave(&lock2, lock_flags2);
-			if (sdio_dld->main_loop_event.wake_up_signal == 0) {
-				sdio_dld->main_loop_event.wake_up_signal = 1;
-				wake_up(&sdio_dld->main_loop_event.wait_event);
-			}
-			spin_unlock_irqrestore(&lock2, lock_flags2);
-
-			/*
-			 * although outgoing buffer has enough room, writing
-			 * failed
-			 */
-			if (bytes_written != bytes_to_write) {
-				pr_err(MODULE_NAME ": %s - couldn't write "
-				       "%d bytes to " "outgoing buffer."
-				       "bytes_written=%d\n",
-				       __func__, bytes_to_write,
-				       bytes_written);
-			       return -EIO;
-			}
-
-			total_written += bytes_written;
-			pending_to_write -= bytes_written;
-			outgoing->num_of_bytes_in_use += bytes_written;
-
-			pr_debug(MODULE_NAME ": %s - WRITE CHUNK to outgoing "
-					   "buffer. pending_to_write=%d, "
-					   "outgoing_free_bytes=%d, "
-					   "bytes_written=%d\n",
-				 __func__,
-				 pending_to_write,
-				 dst_free_bytes,
-				 bytes_written);
-
-		} else {
-			write_retry++;
-
-			pr_debug(MODULE_NAME ": %s - WRITE CALLBACK - NO ROOM."
-			       " pending_to_write=%d, write_retry=%d\n",
-				 __func__,
-				 pending_to_write,
-				 write_retry);
-
-			spin_lock_irqsave(&lock1, lock_flags1);
-			sdio_dld->write_callback_event.wake_up_signal = 0;
-			spin_unlock_irqrestore(&lock1, lock_flags1);
-
-			pr_debug(MODULE_NAME ": %s - WRITE CALLBACK - "
-					     "WAITING...", __func__);
-#ifdef CONFIG_DEBUG_FS
-			update_gd(SDIO_DLD_DEBUGFS_CASE_8_CODE);
-#endif
-			wait_event(sdio_dld->write_callback_event.wait_event,
-				   sdio_dld->write_callback_event.
-				   wake_up_signal);
-#ifdef CONFIG_DEBUG_FS
-			update_gd(SDIO_DLD_DEBUGFS_CASE_9_CODE);
-#endif
-			pr_debug(MODULE_NAME ": %s - WRITE CALLBACK - "
-					     "WOKE UP...", __func__);
-		}
-	} while (pending_to_write > 0 && write_retry < WRITE_RETRIES);
-
-	if (pending_to_write > 0) {
-
-		pr_err(MODULE_NAME ": %s - WRITE CALLBACK - pending data is "
-				   "%d out of %d > 0. total written in this "
-				   "callback = %d\n",
-		       __func__, pending_to_write, count, total_written);
-	}
-
-	if (write_retry == WRITE_RETRIES) {
-		pr_err(MODULE_NAME ": %s, write_retry=%d= max\n",
-		       __func__, write_retry);
-	}
-
-#ifdef CONFIG_DEBUG_FS
-	debugfs_glob.global_bytes_cb_tty = total_written;
-	update_gd(SDIO_DLD_DEBUGFS_CASE_10_CODE);
-#endif
-
-	return total_written;
-}
-
-/**
-  * sdio_memcpy_fromio_wrapper -
-  * reads from sdioc, and updats the sdioc registers according
-  * to how many bytes were actually read.
-  *
-  * @str_func: a pointer to func struct.
-  * @client_rd_ptr: sdioc value of downlink read ptr.
-  * @client_wr_ptr: sdioc value of downlink write ptr.
-  * @buffer_to_store: buffer to store incoming data.
-  * @address_to_read: address to start reading from in sdioc.
-  * @size_to_read: size of bytes to read.
-  * @client_buffer_size: sdioc downlink buffer size.
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_memcpy_fromio_wrapper(struct sdio_func *str_func,
-				      unsigned int client_rd_ptr,
-				      unsigned int client_wr_ptr,
-				      void *buffer_to_store,
-				      unsigned int address_to_read_from,
-				      int size_to_read,
-				      int client_buffer_size)
-{
-	int status = 0;
-	struct sdioc_reg_chunk *reg_str =
-		&sdio_dld->sdio_dloader_data.sdioc_reg;
-
-	if (!str_func) {
-		pr_err(MODULE_NAME ": %s - param ""str_func"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!buffer_to_store) {
-		pr_err(MODULE_NAME ": %s - param ""buffer_to_store"" is "
-				   "NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (size_to_read < 0) {
-		pr_err(MODULE_NAME ": %s - invalid size to read=%d\n",
-			__func__, size_to_read);
-		return -EINVAL;
-	}
-
-	sdio_claim_host(str_func);
-
-	pr_debug(MODULE_NAME ": %s, READING DATA - from add %d, "
-			   "size_to_read=%d\n",
-	       __func__, address_to_read_from, size_to_read);
-
-	status = sdio_memcpy_fromio(str_func,
-				    (void *)buffer_to_store,
-				    address_to_read_from,
-				    size_to_read);
-	if (status) {
-		pr_err(MODULE_NAME ": %s - sdio_memcpy_fromio()"
-		       " DATA failed. status=%d.\n",
-		       __func__, status);
-		sdio_release_host(str_func);
-		return status;
-	}
-
-	/* updating an offset according to cyclic buffer size */
-	reg_str->dl_rd_ptr.reg_val =
-		(reg_str->dl_rd_ptr.reg_val + size_to_read) %
-		client_buffer_size;
-	/* keeping sdio_dld_info up to date */
-	sdio_dld_info.cl_dl_rd_ptr = reg_str->dl_rd_ptr.reg_val;
-
-	status = sdio_memcpy_toio(str_func,
-				  reg_str->dl_rd_ptr.reg_offset,
-				  (void *)&reg_str->dl_rd_ptr.reg_val,
-				  sizeof(reg_str->dl_rd_ptr.reg_val));
-
-	if (status) {
-		pr_err(MODULE_NAME ": %s - sdio_memcpy_toio() "
-		       "UPDATE PTR failed. status=%d.\n",
-		       __func__, status);
-	}
-
-	sdio_release_host(str_func);
-	return status;
-}
-
-/**
-  * sdio_memcpy_toio_wrapper
-  * writes to sdioc, and updats the sdioc registers according
-  * to how many bytes were actually read.
-  *
-  * @str_func: a pointer to func struct.
-  * @client_wr_ptr: sdioc downlink write ptr.
-  * @h_read_ptr: host incoming read ptrs
-  * @buf_write_from: buffer to write from.
-  * @bytes_to_write: number of bytes to write.
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_memcpy_toio_wrapper(struct sdio_func *str_func,
-				    unsigned int client_wr_ptr,
-				    unsigned int h_read_ptr,
-				    void *buf_write_from,
-				    int bytes_to_write)
-{
-	int status = 0;
-	struct sdioc_reg_chunk *reg_str =
-		&sdio_dld->sdio_dloader_data.sdioc_reg;
-	struct sdio_data *outgoing = &sdio_dld->sdio_dloader_data.outgoing_data;
-
-	if (!str_func) {
-		pr_err(MODULE_NAME ": %s - param ""str_func"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!buf_write_from) {
-		pr_err(MODULE_NAME ": %s - param ""buf_write_from"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	sdio_claim_host(str_func);
-
-	pr_debug(MODULE_NAME ": %s, WRITING DATA TOIO to address 0x%x, "
-		 "bytes_to_write=%d\n",
-		 __func__,
-		reg_str->up_buff_address.reg_val + reg_str->up_wr_ptr.reg_val,
-		 bytes_to_write);
-
-	status = sdio_memcpy_toio(str_func,
-				  reg_str->up_buff_address.reg_val +
-				  reg_str->up_wr_ptr.reg_val,
-				  (void *) (outgoing->data + h_read_ptr),
-				  bytes_to_write);
-
-	if (status) {
-		pr_err(MODULE_NAME ": %s - sdio_memcpy_toio() "
-		       "DATA failed. status=%d.\n", __func__, status);
-		sdio_release_host(str_func);
-		return status;
-	}
-
-	sdio_dld_info.global_bytes_write_toio += bytes_to_write;
-	outgoing->num_of_bytes_in_use -= bytes_to_write;
-
-	/*
-	 * if writing to client succeeded, then
-	 * 1. update the client up_wr_ptr
-	 * 2. update the host outgoing rd ptr
-	 **/
-	reg_str->up_wr_ptr.reg_val =
-		((reg_str->up_wr_ptr.reg_val + bytes_to_write) %
-		 reg_str->ul_buff_size.reg_val);
-
-	/* keeping sdio_dld_info up to date */
-	sdio_dld_info.cl_up_wr_ptr = reg_str->up_wr_ptr.reg_val;
-
-	outgoing->offset_read_p =
-		((outgoing->offset_read_p + bytes_to_write) %
-		  outgoing->buffer_size);
-
-	/* keeping sdio_dld_info up to date*/
-	sdio_dld_info.host_read_ptr = outgoing->offset_read_p;
-
-#ifdef CONFIG_DEBUG_FS
-	debugfs_glob.global_write_toio = bytes_to_write;
-	update_gd(SDIO_DLD_DEBUGFS_CASE_4_CODE);
-#endif
-
-	/* updating uplink write pointer according to size that was written */
-	status = sdio_memcpy_toio(str_func,
-				  reg_str->up_wr_ptr.reg_offset,
-				  (void *)(&reg_str->up_wr_ptr.reg_val),
-				  sizeof(reg_str->up_wr_ptr.reg_val));
-	if (status) {
-		pr_err(MODULE_NAME ": %s - sdio_memcpy_toio() "
-				       "UPDATE PTR failed. status=%d.\n",
-		       __func__, status);
-	}
-
-	sdio_release_host(str_func);
-	return status;
-}
-
-/**
-  * sdio_dld_read
-  * reads from sdioc
-  *
-  * @client_rd_ptr: sdioc downlink read ptr.
-  * @client_wr_ptr: sdioc downlink write ptr.
-  * @reg_str: sdioc register shadowing struct.
-  * @str_func: a pointer to func struct.
-  * @bytes_read:how many bytes read.
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_dld_read(unsigned int client_rd_ptr,
-			 unsigned int client_wr_ptr,
-			 struct sdioc_reg_chunk *reg_str,
-			 struct sdio_func *str_func,
-			 int *bytes_read)
-{
-	int status = 0;
-	struct sdio_data *incoming = &sdio_dld->sdio_dloader_data.incoming_data;
-
-	if (!reg_str) {
-		pr_err(MODULE_NAME ": %s - param ""reg_str"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!str_func) {
-		pr_err(MODULE_NAME ": %s - param ""str_func"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!bytes_read) {
-		pr_err(MODULE_NAME ": %s - param ""bytes_read"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	/* there is data to read in ONE chunk */
-	if (client_wr_ptr > client_rd_ptr) {
-		status = sdio_memcpy_fromio_wrapper(
-			str_func,
-			client_rd_ptr,
-			client_wr_ptr,
-			(void *)incoming->data,
-			reg_str->dl_buff_address.reg_val + client_rd_ptr,
-			client_wr_ptr - client_rd_ptr,
-			reg_str->dl_buff_size.reg_val);
-
-		if (status) {
-			pr_err(MODULE_NAME ": %s - Failure in Function "
-			       "sdio_memcpy_fromio_wrapper(). "
-			       "SINGLE CHUNK READ. status=%d\n",
-			       __func__, status);
-			return status;
-		}
-
-		incoming->num_of_bytes_in_use += client_wr_ptr - client_rd_ptr;
-		*bytes_read = client_wr_ptr - client_rd_ptr;
-
-#ifdef CONFIG_DEBUG_FS
-			debugfs_glob.global_to_read =
-				client_wr_ptr - client_rd_ptr;
-			update_gd(SDIO_DLD_DEBUGFS_CASE_11_CODE);
-#endif
-	}
-
-	/* there is data to read in TWO chunks */
-	else {
-		int dl_buf_size = reg_str->dl_buff_size.reg_val;
-		int tail_size = dl_buf_size - client_rd_ptr;
-
-		/* reading chunk#1: from rd_ptr to the end of the buffer */
-		status = sdio_memcpy_fromio_wrapper(
-			str_func,
-			client_rd_ptr,
-			dl_buf_size,
-			(void *)incoming->data,
-			reg_str->dl_buff_address.reg_val + client_rd_ptr,
-			tail_size,
-			dl_buf_size);
-
-		if (status) {
-			pr_err(MODULE_NAME ": %s - Failure in Function "
-			       "sdio_memcpy_fromio_wrapper(). "
-			       "1 of 2 CHUNKS READ. status=%d\n",
-			       __func__, status);
-			return status;
-		}
-
-		incoming->num_of_bytes_in_use += tail_size;
-		*bytes_read = tail_size;
-
-#ifdef CONFIG_DEBUG_FS
-			debugfs_glob.global_to_read = tail_size;
-			update_gd(SDIO_DLD_DEBUGFS_CASE_11_CODE);
-#endif
-
-		/* reading chunk#2: reading from beginning buffer */
-		status = sdio_memcpy_fromio_wrapper(
-			str_func,
-			client_rd_ptr,
-			client_wr_ptr,
-			(void *)(incoming->data + tail_size),
-			reg_str->dl_buff_address.reg_val,
-			client_wr_ptr,
-			reg_str->dl_buff_size.reg_val);
-
-		if (status) {
-			pr_err(MODULE_NAME ": %s - Failure in Function "
-			       "sdio_memcpy_fromio_wrapper(). "
-			       "2 of 2 CHUNKS READ. status=%d\n",
-			       __func__, status);
-			return status;
-		}
-
-		incoming->num_of_bytes_in_use += client_wr_ptr;
-		*bytes_read += client_wr_ptr;
-
-#ifdef CONFIG_DEBUG_FS
-			debugfs_glob.global_to_read = client_wr_ptr;
-			update_gd(SDIO_DLD_DEBUGFS_CASE_11_CODE);
-#endif
-	}
-	return 0;
-}
-
-/**
-  * sdio_dld_main_task
-  * sdio downloader main task. reads mailboxf checks if there is
-  * anything to read, checks if host has anything to
-  * write.
-  *
-  * @card: a pointer to mmc_card.
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_dld_main_task(void *card)
-{
-	int status = 0;
-	struct tty_struct *tty = sdio_dld->tty_str;
-	struct sdioc_reg_chunk *reg_str =
-		&sdio_dld->sdio_dloader_data.sdioc_reg;
-	int func = sdio_dld->sdioc_boot_func;
-	struct sdio_func *str_func = NULL;
-	struct sdio_data *outgoing = &sdio_dld->sdio_dloader_data.outgoing_data;
-	struct sdio_data *incoming = &sdio_dld->sdio_dloader_data.incoming_data;
-	struct sdio_dld_task *task = &sdio_dld->dld_main_thread;
-	int retries = 0;
-#ifdef PUSH_STRING
-	int bytes_pushed = 0;
-#endif
-
-	msleep(SLEEP_MS);
-
-	if (!card) {
-		pr_err(MODULE_NAME ": %s - param ""card"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!tty) {
-		pr_err(MODULE_NAME ": %s - param ""tty"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	str_func = ((struct mmc_card *)card)->
-		sdio_func[REAL_FUNC_TO_FUNC_IN_ARRAY(func)];
-
-	if (!str_func) {
-		pr_err(MODULE_NAME ": %s - param ""str_func"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	while (true) {
-		/* client pointers for both buffers */
-		int client_ul_wr_ptr = 0;
-		int client_ul_rd_ptr = 0;
-		int client_dl_wr_ptr = 0;
-		int client_dl_rd_ptr = 0;
-
-		/* host pointer for outgoing buffer */
-		int h_out_wr_ptr = 0;
-		int h_out_rd_ptr = 0;
-
-		int h_bytes_rdy_wr = 0;
-		int c_bytes_rdy_rcve = 0;
-
-		int need_to_write = 0;
-		int need_to_read = 0;
-
-		/*
-		 * forever, checking for signal to die, then read MailBox.
-		 * if nothing to read or nothing to write to client, sleep,
-		 * and again read MailBox
-		 */
-		do {
-			int dummy = 0;
-
-			/*  checking if a signal to die was sent */
-			if (atomic_read(&task->please_close) == 1) {
-
-				pr_debug(MODULE_NAME ": %s - 0x%x was written "
-					 "to 9K\n", __func__, SDIOC_EXIT_CODE);
-
-				sdio_claim_host(str_func);
-
-				/* returned value is not checked on purpose */
-				sdio_memcpy_toio(
-					str_func,
-					reg_str->good_to_exit_ptr.reg_offset,
-					(void *)&reg_str->good_to_exit_ptr.
-					reg_val,
-					sizeof(reg_str->good_to_exit_ptr.
-					       reg_val));
-
-				sdio_release_host(str_func);
-
-				task->exit_wait.wake_up_signal = 1;
-				wake_up(&task->exit_wait.wait_event);
-				return 0;
-			}
-
-			status = mailbox_to_seq_chunk_read_ptrs(str_func);
-			if (status) {
-				pr_err(MODULE_NAME ": %s - Failure in Function "
-				       "mailbox_to_seq_chunk_read_ptrs(). "
-				       "status=%d\n", __func__, status);
-				return status;
-			}
-
-			/* calculate how many bytes the host has send */
-			h_out_wr_ptr = outgoing->offset_write_p;
-			h_out_rd_ptr = outgoing->offset_read_p;
-
-			status = sdioc_bytes_till_end_of_buffer(
-				h_out_wr_ptr,
-				h_out_rd_ptr,
-				outgoing->buffer_size,
-				&dummy,
-				&h_bytes_rdy_wr);
-
-			if (status) {
-				pr_err(MODULE_NAME ": %s - Failure in Function "
-				       "sdioc_bytes_till_end_of_buffer(). "
-				       "status=%d\n", __func__, status);
-				return status;
-			}
-
-			/* is there something to read from client */
-			client_dl_wr_ptr = reg_str->dl_wr_ptr.reg_val;
-			client_dl_rd_ptr = reg_str->dl_rd_ptr.reg_val;
-
-			if (client_dl_rd_ptr != client_dl_wr_ptr)
-				need_to_read = 1;
-
-			/*
-			 *  calculate how many bytes the client can receive
-			 *  from host
-			 */
-			client_ul_wr_ptr = reg_str->up_wr_ptr.reg_val;
-			client_ul_rd_ptr = reg_str->up_rd_ptr.reg_val;
-
-			status = sdioc_bytes_till_end_of_buffer(
-				client_ul_wr_ptr,
-				client_ul_rd_ptr,
-				reg_str->ul_buff_size.reg_val,
-				&c_bytes_rdy_rcve,
-				&dummy);
-
-			if (status) {
-				pr_err(MODULE_NAME ": %s - Failure in Function "
-				       "sdioc_bytes_till_end_of_buffer(). "
-				       "status=%d\n", __func__, status);
-				return status;
-			}
-
-			/* if host has anything to write */
-			if (h_bytes_rdy_wr > 0)
-				need_to_write = 1;
-
-			if (need_to_write || need_to_read)
-				break;
-
-			spin_lock_irqsave(&lock2, lock_flags2);
-			sdio_dld->main_loop_event.wake_up_signal = 0;
-			spin_unlock_irqrestore(&lock2, lock_flags2);
-
-			pr_debug(MODULE_NAME ": %s - MAIN LOOP - WAITING...\n",
-				 __func__);
-#ifdef CONFIG_DEBUG_FS
-			update_gd(SDIO_DLD_DEBUGFS_CASE_6_CODE);
-#endif
-			wait_event(sdio_dld->main_loop_event.wait_event,
-				   sdio_dld->main_loop_event.wake_up_signal);
-#ifdef CONFIG_DEBUG_FS
-			update_gd(SDIO_DLD_DEBUGFS_CASE_7_CODE);
-#endif
-
-			pr_debug(MODULE_NAME ": %s - MAIN LOOP - WOKE UP...\n",
-				 __func__);
-
-		} while (1);
-
-		/* CHECK IF THERE IS ANYTHING TO READ IN CLIENT */
-		if (need_to_read) {
-#ifdef PUSH_STRING
-			int num_push = 0;
-			int left = 0;
-			int bytes_read;
-#else
-			int i;
-#endif
-			need_to_read = 0;
-
-			status = sdio_dld_read(client_dl_rd_ptr,
-					       client_dl_wr_ptr,
-					       reg_str,
-					       str_func,
-					       &bytes_read);
-
-			if (status) {
-				pr_err(MODULE_NAME ": %s - Failure in Function "
-				       "sdio_dld_read(). status=%d\n",
-				       __func__, status);
-				return status;
-			}
-
-			sdio_dld_info.global_bytes_read_fromio +=
-				bytes_read;
-
-			bytes_pushed = 0;
-#ifdef PUSH_STRING
-			left = incoming->num_of_bytes_in_use;
-			start_timer(&sdio_dld->push_timer,
-				    sdio_dld->push_timer_ms);
-			do {
-				num_push = tty_insert_flip_string(
-					tty,
-					incoming->data+bytes_pushed,
-					left);
-
-				bytes_pushed += num_push;
-				left -= num_push;
-				tty_flip_buffer_push(tty);
-			} while (left != 0);
-
-			del_timer(&sdio_dld->push_timer);
-
-			if (bytes_pushed != incoming->num_of_bytes_in_use) {
-				pr_err(MODULE_NAME ": %s - failed\n",
-				       __func__);
-			}
-#else
-			pr_debug(MODULE_NAME ": %s - NEED TO READ %d\n",
-			       __func__, incoming->num_of_bytes_in_use);
-
-			for (i = 0 ; i < incoming->num_of_bytes_in_use ; ++i) {
-				int err = 0;
-				err = tty_insert_flip_char(tty,
-							   incoming->data[i],
-							   TTY_NORMAL);
-				tty_flip_buffer_push(tty);
-			}
-
-			pr_debug(MODULE_NAME ": %s - JUST READ\n", __func__);
-#endif /*PUSH_STRING*/
-			sdio_dld_info.global_bytes_push_tty +=
-				incoming->num_of_bytes_in_use;
-#ifdef CONFIG_DEBUG_FS
-			debugfs_glob.global_push_to_tty = bytes_read;
-			update_gd(SDIO_DLD_DEBUGFS_CASE_12_CODE);
-#endif
-			incoming->num_of_bytes_in_use = 0;
-			tty_flip_buffer_push(tty);
-		}
-
-		/* CHECK IF THERE IS ANYTHING TO WRITE IN HOST AND HOW MUCH */
-		if (need_to_write) {
-			int dummy = 0;
-
-			do {
-				int bytes_to_write = min(c_bytes_rdy_rcve,
-							 h_bytes_rdy_wr);
-
-				/*
-				 * in case nothing to send or no room to
-				 * receive
-				 */
-				if (bytes_to_write == 0)
-					break;
-
-				if (client_ul_rd_ptr == 0 &&
-				    (client_ul_rd_ptr != client_ul_wr_ptr))
-					break;
-
-				/*
-				 * if client_rd_ptr points to start, but there
-				 * is data to read wait until WRITE_TILL_END
-				 * before writing a chunk of data, to avoid
-				 * writing until (BUF_SIZE - 1), because it will
-				 * yield an extra write of "1" bytes
-				 */
-				if (client_ul_rd_ptr == 0 &&
-				    (client_ul_rd_ptr != client_ul_wr_ptr) &&
-				    retries < WRITE_TILL_END_RETRIES) {
-					retries++;
-					break;
-				}
-				retries = 0;
-
-#ifdef CONFIG_DEBUG_FS
-				debugfs_glob.global_8k_has = h_bytes_rdy_wr;
-				debugfs_glob.global_9k_has = c_bytes_rdy_rcve;
-				debugfs_glob.global_min = bytes_to_write;
-				update_gd(SDIO_DLD_DEBUGFS_CASE_2_CODE);
-#endif
-				need_to_write = 0;
-
-				pr_debug(MODULE_NAME ": %s - NEED TO WRITE "
-					 "TOIO %d\n",
-					 __func__, bytes_to_write);
-
-				status = sdio_memcpy_toio_wrapper(
-					str_func,
-					reg_str->up_wr_ptr.reg_val,
-					outgoing->offset_read_p,
-					(void *)((char *)outgoing->data +
-						 outgoing->offset_read_p),
-					bytes_to_write);
-
-				if (status) {
-					pr_err(MODULE_NAME ": %s - Failure in "
-					       "Function "
-					       "sdio_memcpy_toio_wrapper(). "
-					       "SINGLE CHUNK WRITE. "
-					       "status=%d\n",
-					       __func__, status);
-					return status;
-				}
-
-				sdio_claim_host(str_func);
-
-				status = sdio_memcpy_fromio(
-					str_func,
-					(void *)&reg_str->up_rd_ptr.reg_val,
-					SDIOC_UL_RD_PTR,
-					sizeof(reg_str->up_rd_ptr.reg_val));
-
-				if (status) {
-					pr_err(MODULE_NAME ": %s - "
-					       "sdio_memcpy_fromio() "
-					       "failed. status=%d\n",
-					       __func__, status);
-					sdio_release_host(str_func);
-
-					return status;
-				}
-
-				sdio_release_host(str_func);
-
-				spin_lock_irqsave(&lock1, lock_flags1);
-				if (sdio_dld->write_callback_event.
-				    wake_up_signal == 0) {
-					sdio_dld->write_callback_event.
-						wake_up_signal = 1;
-					wake_up(&sdio_dld->
-						write_callback_event.
-						wait_event);
-				}
-
-				spin_unlock_irqrestore(&lock1, lock_flags1);
-				client_ul_wr_ptr = reg_str->up_wr_ptr.reg_val;
-				client_ul_rd_ptr = reg_str->up_rd_ptr.reg_val;
-
-				status = sdioc_bytes_till_end_of_buffer(
-					client_ul_wr_ptr,
-					client_ul_rd_ptr,
-					reg_str->ul_buff_size.reg_val,
-					&c_bytes_rdy_rcve,
-					&dummy);
-
-				/* calculate how many bytes host has to send */
-				h_out_wr_ptr = outgoing->offset_write_p;
-				h_out_rd_ptr = outgoing->offset_read_p;
-
-				status = sdioc_bytes_till_end_of_buffer(
-					h_out_wr_ptr,
-					h_out_rd_ptr,
-					outgoing->buffer_size,
-					&dummy,
-					&h_bytes_rdy_wr);
-
-			} while (h_out_wr_ptr != h_out_rd_ptr);
-		}
-	}
-	return 0;
-}
-
-/**
-  * sdio_dld_init_global
-  * initialization of sdio_dld global struct
-  *
-  * @card: a pointer to mmc_card.
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_dld_init_global(struct mmc_card *card,
-				int(*done)(void))
-{
-	if (!card) {
-		pr_err(MODULE_NAME ": %s - param ""card"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!done) {
-		pr_err(MODULE_NAME ": %s - param ""done"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	sdio_dld->done_callback = done;
-	sdio_dld->card = card;
-	init_waitqueue_head(&sdio_dld->dld_main_thread.exit_wait.wait_event);
-	sdio_dld->write_callback_event.wake_up_signal = 1;
-	sdio_dld->main_loop_event.wake_up_signal = 1;
-
-	sdio_dld->sdio_dloader_data.sdioc_reg.dl_buff_size.reg_offset =
-		SDIOC_DL_BUFF_SIZE_OFFSET;
-
-	sdio_dld->sdio_dloader_data.sdioc_reg.dl_rd_ptr.reg_offset =
-		SDIOC_DL_RD_PTR;
-
-	sdio_dld->sdio_dloader_data.sdioc_reg.dl_wr_ptr.reg_offset =
-		SDIOC_DL_WR_PTR;
-
-	sdio_dld->sdio_dloader_data.sdioc_reg.ul_buff_size.reg_offset =
-		SDIOC_UP_BUFF_SIZE_OFFSET;
-
-	sdio_dld->sdio_dloader_data.sdioc_reg.up_rd_ptr.reg_offset =
-		SDIOC_UL_RD_PTR;
-
-	sdio_dld->sdio_dloader_data.sdioc_reg.up_wr_ptr.reg_offset =
-		SDIOC_UL_WR_PTR;
-
-	sdio_dld->sdio_dloader_data.sdioc_reg.good_to_exit_ptr.reg_offset =
-		SDIOC_EXIT_PTR;
-
-	sdio_dld->sdio_dloader_data.sdioc_reg.dl_buff_address.reg_offset =
-		SDIOC_DL_BUFF_ADDRESS;
-
-	sdio_dld->sdio_dloader_data.sdioc_reg.up_buff_address.reg_offset =
-		SDIOC_UP_BUFF_ADDRESS;
-
-	sdio_dld_set_op_mode(SDIO_DLD_NORMAL_MODE);
-
-	return 0;
-}
-
-/**
- * sdio_downloader_setup
- * initializes the TTY driver
- *
- * @card: a pointer to mmc_card.
- * @num_of_devices: number of devices.
- * @channel_number: channel number.
- * @return 0 on success or negative value on error.
- *
- * The TTY stack needs to know in advance how many devices it should
- * plan to manage. Use this call to set up the ports that will
- * be exported through SDIO.
- */
-int sdio_downloader_setup(struct mmc_card *card,
-			  unsigned int num_of_devices,
-			  int channel_number,
-			  int(*done)(void))
-{
-	int status = 0;
-	int result = 0;
-	int func_in_array = 0;
-	struct sdio_func *str_func = NULL;
-	struct device *tty_dev;
-
-	if (atomic_read(&sdio_dld_in_use) == 1)
-		return -EBUSY;
-
-	/*
-	 * If the setup is already complete tear down the existing
-	 * one and reinitialize. This might happen during modem restarts
-	 * in boot phase.
-	 */
-	if (atomic_read(&sdio_dld_setup_done) == 1)
-		sdio_dld_tear_down(NULL);
-
-	if (num_of_devices == 0 || num_of_devices > MAX_NUM_DEVICES) {
-		pr_err(MODULE_NAME ": %s - invalid number of devices\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!card) {
-		pr_err(MODULE_NAME ": %s - param ""card"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!done) {
-		pr_err(MODULE_NAME ": %s - param ""done"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	sdio_dld = kzalloc(sizeof(struct sdio_downloader), GFP_KERNEL);
-	if (!sdio_dld) {
-		pr_err(MODULE_NAME ": %s - couldn't allocate sdio_dld data "
-		       "structure.", __func__);
-		return -ENOMEM;
-	}
-
-#ifdef CONFIG_DEBUG_FS
-	bootloader_debugfs_init();
-#endif /* CONFIG_DEBUG_FS */
-
-	status = sdio_dld_init_global(card, done);
-
-	if (status) {
-		pr_err(MODULE_NAME ": %s - Failure in Function "
-		       "sdio_dld_init_global(). status=%d\n",
-		       __func__, status);
-		kfree(sdio_dld);
-		return status;
-	}
-
-	sdio_dld->tty_drv = alloc_tty_driver(num_of_devices);
-
-	if (!sdio_dld->tty_drv) {
-		pr_err(MODULE_NAME ": %s - param ""sdio_dld->tty_drv"" is "
-				   "NULL.\n", __func__);
-		kfree(sdio_dld);
-		return -EINVAL;
-	}
-
-	sdio_dld_set_op_mode((enum sdio_dld_op_mode)sdio_op_mode);
-
-	/* according to op_mode, a different tty device is created */
-	if (sdio_dld->op_mode == SDIO_DLD_BOOT_TEST_MODE)
-		sdio_dld->tty_drv->name = TTY_SDIO_DEV_TEST;
-	else
-	    sdio_dld->tty_drv->name = TTY_SDIO_DEV;
-
-	sdio_dld->tty_drv->owner = THIS_MODULE;
-	sdio_dld->tty_drv->driver_name = "SDIO_Dloader";
-
-	/* uses dynamically assigned dev_t values */
-	sdio_dld->tty_drv->type = TTY_DRIVER_TYPE_SERIAL;
-	sdio_dld->tty_drv->subtype = SERIAL_TYPE_NORMAL;
-	sdio_dld->tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV
-				| TTY_DRIVER_RESET_TERMIOS;
-
-	/* initializing the tty driver */
-	sdio_dld->tty_drv->init_termios = tty_std_termios;
-	sdio_dld->tty_drv->init_termios.c_cflag =
-		B4800 | CS8 | CREAD | HUPCL | CLOCAL;
-	sdio_dld->tty_drv->init_termios.c_ispeed = INPUT_SPEED;
-	sdio_dld->tty_drv->init_termios.c_ospeed = OUTPUT_SPEED;
-
-	tty_set_operations(sdio_dld->tty_drv, &sdio_dloader_tty_ops);
-
-	status = tty_register_driver(sdio_dld->tty_drv);
-	if (status) {
-		put_tty_driver(sdio_dld->tty_drv);
-		pr_err(MODULE_NAME ": %s - tty_register_driver() failed\n",
-			__func__);
-
-		sdio_dld->tty_drv = NULL;
-		kfree(sdio_dld);
-		return status;
-	}
-
-	tty_dev = tty_register_device(sdio_dld->tty_drv, 0, NULL);
-	if (IS_ERR(tty_dev)) {
-		pr_err(MODULE_NAME ": %s - tty_register_device() "
-			"failed\n", __func__);
-		tty_unregister_driver(sdio_dld->tty_drv);
-		put_tty_driver(sdio_dld->tty_drv);
-		kfree(sdio_dld);
-		return PTR_ERR(tty_dev);
-	}
-
-	sdio_dld->sdioc_boot_func = SDIOC_CHAN_TO_FUNC_NUM(channel_number);
-	func_in_array = REAL_FUNC_TO_FUNC_IN_ARRAY(sdio_dld->sdioc_boot_func);
-	str_func = sdio_dld->card->sdio_func[func_in_array];
-	status = sdio_dld_init_func(str_func);
-	if (status) {
-		pr_err(MODULE_NAME ": %s - Failure in Function "
-		       "sdio_dld_init_func(). status=%d\n",
-		       __func__, status);
-		goto exit_err;
-	}
-
-#ifdef CONFIG_DEBUG_FS
-	sdio_dld_debug_init();
-#endif
-
-	sdio_claim_host(str_func);
-
-	/*
-	 * notifing the client by writing what mode we are by writing
-	 * to a special register
-	 */
-	status = sdio_memcpy_toio(str_func,
-				  SDIOC_OP_MODE_PTR,
-				  (void *)&sdio_dld->op_mode,
-				  sizeof(sdio_dld->op_mode));
-
-	sdio_release_host(str_func);
-
-	if (status) {
-		pr_err(MODULE_NAME ": %s - sdio_memcpy_toio() "
-		       "writing to OP_MODE_REGISTER failed. "
-		       "status=%d.\n",
-		       __func__, status);
-		goto exit_err;
-	}
-
-	atomic_set(&sdio_dld_setup_done, 1);
-	return 0;
-
-exit_err:
-	tty_unregister_device(sdio_dld->tty_drv, 0);
-	result = tty_unregister_driver(sdio_dld->tty_drv);
-	if (result)
-		pr_err(MODULE_NAME ": %s - tty_unregister_driver() "
-		       "failed. result=%d\n", __func__, -result);
-	put_tty_driver(sdio_dld->tty_drv);
-	kfree(sdio_dld);
-	atomic_set(&sdio_dld_setup_done, 0);
-	return status;
-}
-
-static void sdio_dld_tear_down(struct work_struct *work)
-{
-	int status = 0;
-
-	if (atomic_read(&sdio_dld_in_use) == 1) {
-		del_timer_sync(&sdio_dld->timer);
-		del_timer_sync(&sdio_dld->push_timer);
-		sdio_dld_dealloc_local_buffers();
-	}
-
-	tty_unregister_device(sdio_dld->tty_drv, 0);
-
-	status = tty_unregister_driver(sdio_dld->tty_drv);
-	if (status) {
-		pr_err(MODULE_NAME ": %s - tty_unregister_driver() failed\n",
-		       __func__);
-	}
-
-	put_tty_driver(sdio_dld->tty_drv);
-	kfree(sdio_dld);
-	atomic_set(&sdio_dld_in_use, 0);
-	atomic_set(&sdio_dld_setup_done, 0);
-}
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("SDIO Downloader");
-MODULE_AUTHOR("Yaniv Gardi <ygardi@codeaurora.org>");
-MODULE_VERSION(DRV_VERSION);
-
diff --git a/arch/arm/mach-msm/sdio_al_private.h b/arch/arm/mach-msm/sdio_al_private.h
deleted file mode 100644
index 3a5ab79..0000000
--- a/arch/arm/mach-msm/sdio_al_private.h
+++ /dev/null
@@ -1,267 +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.
- */
-
-/*
- * SDIO-Abstraction-Layer internal interface.
- */
-
-#ifndef __SDIO_AL_PRIVATE__
-#define __SDIO_AL_PRIVATE__
-
-#include <linux/mmc/card.h>
-#include <linux/platform_device.h>
-#include <mach/sdio_al.h>
-
-#define DRV_VERSION "1.30"
-#define MODULE_NAME "sdio_al"
-#define SDIOC_CHAN_TO_FUNC_NUM(x)	((x)+2)
-#define REAL_FUNC_TO_FUNC_IN_ARRAY(x)	((x)-1)
-#define SDIO_PREFIX "SDIO_"
-#define PEER_CHANNEL_NAME_SIZE		4
-#define CHANNEL_NAME_SIZE (sizeof(SDIO_PREFIX) + PEER_CHANNEL_NAME_SIZE)
-#define SDIO_TEST_POSTFIX_SIZE 5
-#define MAX_NUM_OF_SDIO_DEVICES	2
-#define TEST_CH_NAME_SIZE (CHANNEL_NAME_SIZE + SDIO_TEST_POSTFIX_SIZE)
-
-struct sdio_al_device; /* Forward Declaration */
-
-enum sdio_channel_state {
-	SDIO_CHANNEL_STATE_INVALID,	 /* before reading software header */
-	SDIO_CHANNEL_STATE_IDLE,         /* channel valid, not opened    */
-	SDIO_CHANNEL_STATE_CLOSED,       /* was closed */
-	SDIO_CHANNEL_STATE_OPEN,	 /* opened */
-	SDIO_CHANNEL_STATE_CLOSING,      /* during flush, when closing */
-};
-/**
- * Peer SDIO-Client channel configuration.
- *
- *  @is_ready - channel is ready and the data is valid.
- *
- *  @max_rx_threshold - maximum rx threshold, according to the
- *		total buffers size on the peer pipe.
- *  @max_tx_threshold - maximum tx threshold, according to the
- *		total buffers size on the peer pipe.
- *  @tx_buf_size - size of a single buffer on the peer pipe; a
- *		transfer smaller than the buffer size still
- *		make the buffer unusable for the next transfer.
- * @max_packet_size
- * @is_host_ok_to_sleep - Host marks this bit when it's okay to
- *		sleep (no pending transactions)
- */
-struct peer_sdioc_channel_config {
-	u32 is_ready;
-	u32 max_rx_threshold; /* Downlink */
-	u32 max_tx_threshold; /* Uplink */
-	u32 tx_buf_size;
-	u32 max_packet_size;
-	u32 is_host_ok_to_sleep;
-	u32 is_packet_mode;
-	u32 peer_operation;
-	u32 is_low_latency_ch;
-	u32 reserved[23];
-};
-
-
-/**
- * Peer SDIO-Client channel statsitics.
- *
- * @last_any_read_avail - the last read avail in all the
- *		 channels including this channel.
- * @last_read_avail - the last read_avail that was read from HW
- *	    mailbox.
- * @last_old_read_avail - the last read_avail channel shadow.
- * @total_notifs - the total number of read notifications sent
- *	 to this channel client
- * @total_read_times - the total number of successful sdio_read
- *	     calls for this channel
- */
-struct sdio_channel_statistics {
-	int last_any_read_avail;
-	int last_read_avail;
-	int last_old_read_avail;
-	int total_notifs;
-	int total_read_times;
-};
-
-/**
- *  SDIO Channel context.
- *
- *  @name - channel name. Used by the caller to open the
- *	  channel.
- *
- *  @read_threshold - Threshold on SDIO-Client mailbox for Rx
- *				Data available bytes. When the limit exceed
- *				the SDIO-Client generates an interrupt to the
- *				host.
- *
- *  @write_threshold - Threshold on SDIO-Client mailbox for Tx
- *				Data available bytes. When the limit exceed
- *				the SDIO-Client generates an interrupt to the
- *				host.
- *
- *  @def_read_threshold - Default theshold on SDIO-Client for Rx
- *
- *  @min_write_avail - Threshold of minimal available bytes
- *					 to write. Below that threshold the host
- *					 will initiate reading the mailbox.
- *
- *  @poll_delay_msec - Delay between polling the mailbox. When
- *				 the SDIO-Client doesn't generates EOT
- *				 interrupt for Rx Available bytes, the host
- *				 should poll the SDIO-Client mailbox.
- *
- *  @is_packet_mode - The host get interrupt when a packet is
- *				available at the SDIO-client (pipe EOT
- *				indication).
- *
- *  @num - channel number.
- *
- *  @notify - Client's callback. Should not call sdio read/write.
- *
- *  @priv - Client's private context, provided to callback.
- *
- *  @is_valid - Channel is used (we have a list of
- *		SDIO_AL_MAX_CHANNELS and not all of them are in
- *		use).
- *
- *  @is_open - Channel is open.
- *
- *  @func - SDIO Function handle.
- *
- *  @rx_pipe_index - SDIO-Client Pipe Index for Rx Data.
- *
- *  @tx_pipe_index - SDIO-Client Pipe Index for Tx Data.
- *
- *  @ch_lock - Channel lock to protect channel specific Data
- *
- *  @rx_pending_bytes - Total number of Rx pending bytes, at Rx
- *				  packet list. Maximum of 16KB-1 limited by
- *				  SDIO-Client specification.
- *
- *  @read_avail - Available bytes to read.
- *
- *  @write_avail - Available bytes to write.
- *
- *  @rx_size_list_head - The head of Rx Pending Packets List.
- *
- *  @pdev - platform device - clients to probe for the sdio-al.
- *
- *  @signature - Context Validity check.
- *
- *  @sdio_al_dev - a pointer to the sdio_al_device instance of
- *   this channel
- *
- *   @statistics - channel statistics
- *
- */
-struct sdio_channel {
-	/* Channel Configuration Parameters*/
-	char name[CHANNEL_NAME_SIZE];
-	char ch_test_name[TEST_CH_NAME_SIZE];
-	int read_threshold;
-	int write_threshold;
-	int def_read_threshold;
-	int threshold_change_cnt;
-	int min_write_avail;
-	int poll_delay_msec;
-	int is_packet_mode;
-	int is_low_latency_ch;
-
-	struct peer_sdioc_channel_config ch_config;
-
-	/* Channel Info */
-	int num;
-
-	void (*notify)(void *priv, unsigned channel_event);
-	void *priv;
-
-	int state;
-
-	struct sdio_func *func;
-
-	int rx_pipe_index;
-	int tx_pipe_index;
-
-	struct mutex ch_lock;
-
-	u32 read_avail;
-	u32 write_avail;
-
-	u32 peer_tx_buf_size;
-
-	u16 rx_pending_bytes;
-
-	struct list_head rx_size_list_head;
-
-	struct platform_device *pdev;
-
-	u32 total_rx_bytes;
-	u32 total_tx_bytes;
-
-	u32 signature;
-
-	struct sdio_al_device *sdio_al_dev;
-
-	struct sdio_channel_statistics statistics;
-};
-
-/**
- * sdio_downloader_setup
- * initializes the TTY driver
- *
- * @card: a pointer to mmc_card.
- * @num_of_devices: number of devices.
- * @channel_number: channel number.
- * @return 0 on success or negative value on error.
- *
- * The TTY stack needs to know in advance how many devices it should
- * plan to manage. Use this call to set up the ports that will
- * be exported through SDIO.
- */
-int sdio_downloader_setup(struct mmc_card *card,
-			  unsigned int num_of_devices,
-			  int func_number,
-			  int(*func)(void));
-
-/**
- * test_channel_init
- * initializes a test channel
- *
- * @name: the channel name.
- * @return 0 on success or negative value on error.
- *
- */
-int test_channel_init(char *name);
-
-/**
- * sdio_al_register_lpm_cb
- * Allow the sdio_al test to register for lpm voting
- * notifications
- *
- * @device_handle: the device handle.
- * @wakeup_callback: callback function to be called when voting.
- *
- */
-void sdio_al_register_lpm_cb(void *device_handle,
-				       int(*lpm_callback)(void *, int));
-
-/**
- * sdio_al_unregister_lpm_cb
- * Allow the sdio_al test to unregister for lpm voting
- * notifications
- *
- * @device_handle: the device handle.
- *
- */
-void sdio_al_unregister_lpm_cb(void *device_handle);
-
-#endif /* __SDIO_AL_PRIVATE__ */
diff --git a/arch/arm/mach-msm/sdio_al_test.c b/arch/arm/mach-msm/sdio_al_test.c
deleted file mode 100644
index 2c9f675..0000000
--- a/arch/arm/mach-msm/sdio_al_test.c
+++ /dev/null
@@ -1,6500 +0,0 @@
-/* Copyright (c) 2010-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.
- */
-
-/*
- * SDIO-Abstraction-Layer Test Module.
- *
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/workqueue.h>
-#include <linux/fs.h>
-#include <linux/cdev.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/platform_device.h>
-#include <mach/sdio_smem.h>
-#include <linux/wakelock.h>
-#include <linux/uaccess.h>
-
-#include "sdio_al_private.h"
-#include <linux/debugfs.h>
-
-#include <linux/kthread.h>
-enum lpm_test_msg_type {
-	LPM_NO_MSG,	/* 0 */
-	LPM_MSG_SEND,	/* 1 */
-	LPM_MSG_REC,	/* 2 */
-	LPM_SLEEP,	/* 3 */
-	LPM_WAKEUP,	/* 4 */
-	LPM_NOTIFY	/* 5 */
-};
-
-#define LPM_NO_MSG_NAME "LPM No Event"
-#define LPM_MSG_SEND_NAME "LPM Send Msg Event"
-#define LPM_MSG_REC_NAME "LPM Receive Msg Event"
-#define LPM_SLEEP_NAME "LPM Sleep Event"
-#define LPM_WAKEUP_NAME "LPM Wakeup Event"
-
-/** Module name string */
-#define TEST_MODULE_NAME "sdio_al_test"
-
-#define TEST_SIGNATURE 0x12345678
-#define TEST_CONFIG_SIGNATURE 0xBEEFCAFE
-
-#define MAX_XFER_SIZE (16*1024)
-#define SMEM_MAX_XFER_SIZE 0xBC000
-#define A2_MIN_PACKET_SIZE 5
-#define RMNT_PACKET_SIZE (4*1024)
-#define DUN_PACKET_SIZE (2*1024)
-#define CSVT_PACKET_SIZE 1700
-
-#define TEST_DBG(x...) if (test_ctx->runtime_debug) pr_info(x)
-
-#define LPM_TEST_NUM_OF_PACKETS 100
-#define LPM_MAX_OPEN_CHAN_PER_DEV 4
-#define LPM_ARRAY_SIZE	(7*LPM_TEST_NUM_OF_PACKETS*LPM_MAX_OPEN_CHAN_PER_DEV)
-#define SDIO_LPM_TEST "sdio_lpm_test_reading_task"
-#define LPM_TEST_CONFIG_SIGNATURE 0xDEADBABE
-#define LPM_MSG_NAME_SIZE 20
-#define MAX_STR_SIZE	10
-#define MAX_AVG_RTT_TIME_USEC	2500
-#define SDIO_RMNT_RTT_PACKET_SIZE	32
-#define SDIO_CSVT_RTT_PACKET_SIZE	1900
-
-#define A2_HEADER_OVERHEAD 8
-
-enum rx_process_state {
-	RX_PROCESS_PACKET_INIT,
-	RX_PROCESS_A2_HEADER,
-	RX_PROCESS_PACKET_DATA,
-};
-
-enum sdio_test_case_type {
-	SDIO_TEST_LOOPBACK_HOST,
-	SDIO_TEST_LOOPBACK_CLIENT,
-	SDIO_TEST_LPM_HOST_WAKER,
-	SDIO_TEST_LPM_CLIENT_WAKER,
-	SDIO_TEST_LPM_RANDOM,
-	SDIO_TEST_HOST_SENDER_NO_LP,
-	SDIO_TEST_CLOSE_CHANNEL,
-	SDIO_TEST_A2_VALIDATION,
-	/* The following tests are not part of the 9k tests and should be
-	 * kept last in case new tests are added
-	 */
-	SDIO_TEST_PERF,
-	SDIO_TEST_RTT,
-	SDIO_TEST_MODEM_RESET,
-};
-
-struct lpm_task {
-	struct task_struct *lpm_task;
-	const char *task_name;
-};
-
-struct lpm_entry_type {
-	enum lpm_test_msg_type msg_type;
-	char msg_name[LPM_MSG_NAME_SIZE];
-	u32 counter;
-	u32 current_ms;
-	u32 read_avail_mask;
-	char chan_name[CHANNEL_NAME_SIZE];
-};
-
-struct lpm_msg {
-	u32 signature;
-	u32 counter;
-	u32 reserve1;
-	u32 reserve2;
-};
-
-struct test_config_msg {
-	u32 signature;
-	u32 test_case;
-	u32 test_param;
-	u32 num_packets;
-	u32 num_iterations;
-};
-
-struct test_result_msg {
-	u32 signature;
-	u32 is_successful;
-};
-
-struct test_work {
-	struct work_struct work;
-	struct test_channel *test_ch;
-};
-
-enum sdio_channels_ids {
-	SDIO_RPC,
-	SDIO_QMI,
-	SDIO_RMNT,
-	SDIO_DIAG,
-	SDIO_DUN,
-	SDIO_SMEM,
-	SDIO_CSVT,
-	SDIO_MAX_CHANNELS
-};
-
-enum sdio_test_results {
-	TEST_NO_RESULT,
-	TEST_FAILED,
-	TEST_PASSED
-};
-
-enum sdio_lpm_vote_state {
-	SDIO_NO_VOTE,
-	SDIO_VOTE_FOR_SLEEP,
-	SDIO_VOTE_AGAINST_SLEEP
-};
-
-struct sdio_test_device {
-	int open_channels_counter_to_recv;
-	int open_channels_counter_to_send;
-	struct lpm_entry_type *lpm_arr;
-	int array_size;
-	void *sdio_al_device;
-	spinlock_t lpm_array_lock;
-	unsigned long lpm_array_lock_flags;
-	u32 next_avail_entry_in_array;
-	struct lpm_task lpm_test_task;
-	u32 next_mask_id;
-	u32 read_avail_mask;
-	int modem_result_per_dev;
-	int final_result_per_dev;
-};
-
-struct test_channel {
-	struct sdio_channel *ch;
-
-	char name[CHANNEL_NAME_SIZE];
-	int ch_id;
-
-	struct sdio_test_device *test_device;
-
-	u32 *buf;
-	u32 buf_size;
-
-	struct workqueue_struct *workqueue;
-	struct test_work test_work;
-
-	u32 rx_bytes;
-	u32 tx_bytes;
-
-	wait_queue_head_t   wait_q;
-	atomic_t rx_notify_count;
-	atomic_t tx_notify_count;
-	atomic_t any_notify_count;
-	atomic_t wakeup_client;
-	atomic_t card_detected_event;
-
-	int wait_counter;
-
-	int is_used;
-	int test_type;
-	int ch_ready;
-
-	struct test_config_msg config_msg;
-
-	int test_completed;
-	int test_result;
-	struct timer_list timer;
-	int timer_interval_ms;
-
-	struct timer_list timeout_timer;
-	int timeout_ms;
-	void *sdio_al_device;
-	int is_ok_to_sleep;
-	unsigned int packet_length;
-	int random_packet_size;
-	int next_index_in_sent_msg_per_chan;
-	int channel_mask_id;
-	int modem_result_per_chan;
-	int notify_counter_per_chan;
-	int max_burst_size;        /* number of writes before close/open */
-	int card_removed;
-};
-
-struct sdio_al_test_debug {
-	u32 dun_throughput;
-	u32 rmnt_throughput;
-	struct dentry *debug_root;
-	struct dentry *debug_test_result;
-	struct dentry *debug_dun_throughput;
-	struct dentry *debug_rmnt_throughput;
-	struct dentry *rpc_sender_test;
-	struct dentry *rpc_qmi_diag_sender_test;
-	struct dentry *smem_test;
-	struct dentry *smem_rpc_test;
-	struct dentry *rmnet_a2_validation_test;
-	struct dentry *dun_a2_validation_test;
-	struct dentry *rmnet_a2_perf_test;
-	struct dentry *dun_a2_perf_test;
-	struct dentry *csvt_a2_perf_test;
-	struct dentry *rmnet_dun_a2_perf_test;
-	struct dentry *rpc_sender_rmnet_a2_perf_test;
-	struct dentry *all_channels_test;
-	struct dentry *host_sender_no_lp_diag_test;
-	struct dentry *host_sender_no_lp_diag_rpc_test;
-	struct dentry *rmnet_small_packets_test;
-	struct dentry *rmnet_rtt_test;
-	struct dentry *csvt_rtt_test;
-	struct dentry *modem_reset_rpc_test;
-	struct dentry *modem_reset_rmnet_test;
-	struct dentry *modem_reset_channels_4bit_dev_test;
-	struct dentry *modem_reset_channels_8bit_dev_test;
-	struct dentry *modem_reset_all_channels_test;
-	struct dentry *open_close_test;
-	struct dentry *open_close_dun_rmnet_test;
-	struct dentry *close_chan_lpm_test;
-	struct dentry *lpm_test_client_wakes_host_test;
-	struct dentry *lpm_test_host_wakes_client_test;
-	struct dentry *lpm_test_random_single_channel_test;
-	struct dentry *lpm_test_random_multi_channel_test;
-};
-
-struct test_context {
-	dev_t dev_num;
-	struct device *dev;
-	struct cdev *cdev;
-	int number_of_active_devices;
-	int max_number_of_devices;
-
-	struct sdio_test_device test_dev_arr[MAX_NUM_OF_SDIO_DEVICES];
-
-	struct test_channel *test_ch;
-
-	struct test_channel *test_ch_arr[SDIO_MAX_CHANNELS];
-
-	long testcase;
-
-	const char *name;
-
-	int exit_flag;
-
-	u32 signature;
-
-	int runtime_debug;
-
-	struct platform_device *smem_pdev;
-	struct sdio_smem_client *sdio_smem;
-	int smem_was_init;
-	u8 *smem_buf;
-	uint32_t smem_counter;
-
-	struct platform_device *csvt_app_pdev;
-
-	wait_queue_head_t   wait_q;
-	int test_completed;
-	int test_result;
-	struct sdio_al_test_debug debug;
-
-	struct wake_lock wake_lock;
-
-	unsigned int lpm_pseudo_random_seed;
-};
-
-/* FORWARD DECLARATIONS */
-static int set_params_loopback_9k(struct test_channel *tch);
-static int set_params_smem_test(struct test_channel *tch);
-static int set_params_a2_validation(struct test_channel *tch);
-static int set_params_a2_perf(struct test_channel *tch);
-static int set_params_8k_sender_no_lp(struct test_channel *tch);
-static int set_params_a2_small_pkts(struct test_channel *tch);
-static int set_params_rtt(struct test_channel *tch);
-static int set_params_loopback_9k_close(struct test_channel *tch);
-static int close_channel_lpm_test(int channel_num);
-static int set_params_lpm_test(struct test_channel *tch,
-				enum sdio_test_case_type test,
-				int timer_interval_ms);
-static void set_pseudo_random_seed(void);
-static int set_params_modem_reset(struct test_channel *tch);
-static int test_start(void);
-static void rx_cleanup(struct test_channel *test_ch, int *rx_packet_count);
-static void sdio_al_test_cleanup_channels(void);
-static void notify(void *priv, unsigned channel_event);
-#ifdef CONFIG_MSM_SDIO_SMEM
-static int sdio_smem_open(struct sdio_smem_client *sdio_smem);
-#endif
-
-/*
- * Seed for pseudo random time sleeping in Random LPM test.
- * If not set, current time in jiffies is used.
- */
-static unsigned int seed;
-module_param(seed, int, 0);
-static struct test_context *test_ctx;
-
-static void sdio_al_test_initial_dev_and_chan(struct test_context *test_ctx)
-{
-	int i = 0;
-
-	if (!test_ctx) {
-		pr_err(TEST_MODULE_NAME ":%s - test_ctx is NULL.\n", __func__);
-		return;
-	}
-
-	for (i = 0 ; i < MAX_NUM_OF_SDIO_DEVICES ; ++i)
-		test_ctx->test_dev_arr[i].sdio_al_device = NULL;
-
-	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
-		struct test_channel *tch = test_ctx->test_ch_arr[i];
-		if (!tch)
-			continue;
-		tch->is_used = 0;
-	}
-
-	sdio_al_test_cleanup_channels();
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-static int message_repeat;
-
-static int sdio_al_test_extract_number(const char __user *buf,
-					size_t count)
-{
-	int ret = 0;
-	int number = -1;
-	char local_buf[MAX_STR_SIZE] = {0};
-	char *start = NULL;
-
-	if (count > MAX_STR_SIZE) {
-		pr_err(TEST_MODULE_NAME ": %s - MAX_STR_SIZE(%d) < count(%d). "
-		       "Please choose smaller number\n",
-		       __func__, MAX_STR_SIZE, (int)count);
-		return -EINVAL;
-	}
-
-	if (copy_from_user(local_buf, buf, count)) {
-		pr_err(TEST_MODULE_NAME ": %s - copy_from_user() failed\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	/* adding null termination to the string */
-	local_buf[count] = '\0';
-
-	/* stripping leading and trailing white spaces */
-	start = strstrip(local_buf);
-
-	ret = kstrtoint(start, 10, &number);
-
-	if (ret) {
-		pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
-		       __func__);
-		return ret;
-	}
-
-	return number;
-}
-
-static int sdio_al_test_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	message_repeat = 1;
-	return 0;
-}
-
-static void sdio_al_test_cleanup_channels(void)
-{
-	int channel_num;
-	int dummy = 0;
-
-	for (channel_num = 0 ; channel_num < SDIO_MAX_CHANNELS ;
-	      ++channel_num) {
-		if (channel_num == SDIO_SMEM)
-			continue;
-
-		 rx_cleanup(test_ctx->test_ch_arr[channel_num], &dummy);
-	}
-
-	return;
-}
-
-/* RPC SENDER TEST */
-static ssize_t rpc_sender_test_write(struct file *file,
-				      const char __user *buf,
-				      size_t count,
-				      loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- RPC SENDER TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t rpc_sender_test_read(struct file *file,
-				     char __user *buffer,
-				     size_t count,
-				     loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nRPC_SENDER_TEST\n"
-		 "===============\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations rpc_sender_test_ops = {
-	.open = sdio_al_test_open,
-	.write = rpc_sender_test_write,
-	.read = rpc_sender_test_read,
-};
-
-/* RPC, QMI & DIAG SENDER TEST */
-static ssize_t rpc_qmi_diag_sender_test_write(struct file *file,
-					       const char __user *buf,
-					       size_t count,
-					       loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- RPC, QMI AND DIAG SENDER TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_QMI]);
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_DIAG]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t rpc_qmi_diag_sender_test_read(struct file *file,
-					      char __user
-					      *buffer, size_t count,
-					      loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nRPC_QMI_DIAG_SENDER_TEST\n"
-		 "========================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations rpc_qmi_diag_sender_test_ops = {
-	.open = sdio_al_test_open,
-	.write = rpc_qmi_diag_sender_test_write,
-	.read = rpc_qmi_diag_sender_test_read,
-};
-
-/* SMEM TEST */
-static ssize_t smem_test_write(struct file *file,
-				const char __user *buf,
-				size_t count,
-				loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- SMEM TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_smem_test(test_ctx->test_ch_arr[SDIO_SMEM]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t smem_test_read(struct file *file,
-			       char __user *buffer,
-			       size_t count,
-			       loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nSMEM_TEST\n"
-		 "=========\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations smem_test_ops = {
-	.open = sdio_al_test_open,
-	.write = smem_test_write,
-	.read = smem_test_read,
-};
-
-/* SMEM & RPC TEST */
-static ssize_t smem_rpc_test_write(struct file *file,
-				    const char __user *buf,
-				    size_t count,
-				    loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- SMEM AND RPC TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
-		set_params_smem_test(test_ctx->test_ch_arr[SDIO_SMEM]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t smem_rpc_test_read(struct file *file,
-				   char __user *buffer,
-				   size_t count,
-				   loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nSMEM_RPC_TEST\n"
-		 "=============\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations smem_rpc_test_ops = {
-	.open = sdio_al_test_open,
-	.write = smem_rpc_test_write,
-	.read = smem_rpc_test_read,
-};
-
-/* RMNET A2 VALIDATION TEST */
-static ssize_t rmnet_a2_validation_test_write(struct file *file,
-						const char __user *buf,
-						size_t count,
-						loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- RMNET A2 VALIDATION TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_a2_validation(test_ctx->test_ch_arr[SDIO_RMNT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t rmnet_a2_validation_test_read(struct file *file,
-						char __user *buffer,
-						size_t count,
-						loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nRMNET_A2_VALIDATION_TEST\n"
-		 "=========================\n"
-		 "Description:\n"
-		 "In this test, the HOST sends multiple packets to the\n"
-		 "CLIENT and validates the packets loop backed from A2\n"
-		 "for the RMNET channel.\n\n"
-		 "END OF DESCRIPTION\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations rmnet_a2_validation_test_ops = {
-	.open = sdio_al_test_open,
-	.write = rmnet_a2_validation_test_write,
-	.read = rmnet_a2_validation_test_read,
-};
-
-/* DUN A2 VALIDATION TEST */
-static ssize_t dun_a2_validation_test_write(struct file *file,
-						const char __user *buf,
-						size_t count,
-						loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- DUN A2 VALIDATION TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_a2_validation(test_ctx->test_ch_arr[SDIO_DUN]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t dun_a2_validation_test_read(struct file *file,
-						char __user *buffer,
-						size_t count,
-						loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		"\nDUN_A2_VALIDATION_TEST\n"
-		"=========================\n"
-		"Description:\n"
-		"In this test, the HOST sends multiple packets to the\n"
-		"CLIENT and validates the packets loop backed from A2\n"
-		"for the DUN channel.\n\n"
-		"END OF DESCRIPTION\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations dun_a2_validation_test_ops = {
-	.open = sdio_al_test_open,
-	.write = dun_a2_validation_test_write,
-	.read = dun_a2_validation_test_read,
-};
-
-/* RMNET A2 PERFORMANCE TEST */
-static ssize_t rmnet_a2_perf_test_write(struct file *file,
-					 const char __user *buf,
-					 size_t count,
-					 loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- RMNET A2 PERFORMANCE TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t rmnet_a2_perf_test_read(struct file *file,
-					char __user *buffer,
-					size_t count,
-					loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nRMNET_A2_PERFORMANCE_TEST\n"
-		 "=========================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations rmnet_a2_perf_test_ops = {
-	.open = sdio_al_test_open,
-	.write = rmnet_a2_perf_test_write,
-	.read = rmnet_a2_perf_test_read,
-};
-
-/* DUN A2 PERFORMANCE TEST */
-static ssize_t dun_a2_perf_test_write(struct file *file,
-				       const char __user *buf,
-				       size_t count,
-				       loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- DUN A2 PERFORMANCE TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_DUN]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t dun_a2_perf_test_read(struct file *file,
-				      char __user *buffer,
-				      size_t count,
-				      loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nDUN_A2_PERFORMANCE_TEST\n"
-		 "=======================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations dun_a2_perf_test_ops = {
-	.open = sdio_al_test_open,
-	.write = dun_a2_perf_test_write,
-	.read = dun_a2_perf_test_read,
-};
-
-/* CSVT A2 PERFORMANCE TEST */
-static ssize_t csvt_a2_perf_test_write(struct file *file,
-					const char __user *buf,
-					size_t count,
-					loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- CSVT A2 PERFORMANCE TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_CSVT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t csvt_a2_perf_test_read(struct file *file,
-				       char __user *buffer,
-				       size_t count,
-				       loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nCSVT_A2_PERFORMANCE_TEST\n"
-		 "========================\n"
-		 "Description:\n"
-		 "Loopback test on the CSVT Channel, in order to check "
-		 "throughput performance.\n"
-		 "Packet size that are sent on the CSVT channel in this "
-		 "test is %d.bytes\n\n"
-		 "END OF DESCRIPTION\n", CSVT_PACKET_SIZE);
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations csvt_a2_perf_test_ops = {
-	.open = sdio_al_test_open,
-	.write = csvt_a2_perf_test_write,
-	.read = csvt_a2_perf_test_read,
-};
-
-/* RMNET DUN A2 PERFORMANCE TEST */
-static ssize_t rmnet_dun_a2_perf_test_write(struct file *file,
-					     const char __user *buf,
-					     size_t count,
-					     loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- RMNET AND DUN A2 PERFORMANCE TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
-		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_DUN]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t rmnet_dun_a2_perf_test_read(struct file *file,
-					    char __user *buffer,
-					    size_t count,
-					    loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nRMNET_DUN_A2_PERFORMANCE_TEST\n"
-		 "=============================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations rmnet_dun_a2_perf_test_ops = {
-	.open = sdio_al_test_open,
-	.write = rmnet_dun_a2_perf_test_write,
-	.read = rmnet_dun_a2_perf_test_read,
-};
-
-/* RPC SENDER & RMNET A2 PERFORMANCE TEST */
-static ssize_t rpc_sender_rmnet_a2_perf_test_write(struct file *file,
-						    const char __user *buf,
-						    size_t count,
-						    loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "--RPC SENDER AND RMNET A2 "
-		"PERFORMANCE --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
-		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t rpc_sender_rmnet_a2_perf_test_read(struct file *file,
-						   char __user *buffer,
-						   size_t count,
-						   loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nRPC_SENDER_RMNET_A2_PERFORMANCE_TEST\n"
-		 "====================================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations rpc_sender_rmnet_a2_perf_test_ops = {
-	.open = sdio_al_test_open,
-	.write = rpc_sender_rmnet_a2_perf_test_write,
-	.read = rpc_sender_rmnet_a2_perf_test_read,
-};
-
-/* ALL CHANNELS TEST */
-static ssize_t all_channels_test_write(struct file *file,
-					const char __user *buf,
-					size_t count,
-					loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- ALL THE CHANNELS TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_QMI]);
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_DIAG]);
-		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
-		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_DUN]);
-		set_params_smem_test(test_ctx->test_ch_arr[SDIO_SMEM]);
-		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_CSVT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t all_channels_test_read(struct file *file,
-				       char __user *buffer,
-				       size_t count,
-				       loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nALL_CHANNELS_TEST\n"
-		 "=================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations all_channels_test_ops = {
-	.open = sdio_al_test_open,
-	.write = all_channels_test_write,
-	.read = all_channels_test_read,
-};
-
-/* HOST SENDER NO LP DIAG TEST */
-static ssize_t host_sender_no_lp_diag_test_write(struct file *file,
-						  const char __user *buf,
-						  size_t count,
-						  loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- HOST SENDER NO LP FOR DIAG TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_DIAG]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t host_sender_no_lp_diag_test_read(struct file *file,
-						 char __user *buffer,
-						 size_t count,
-						 loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nHOST_SENDER_NO_LP_DIAG_TEST\n"
-		 "===========================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations host_sender_no_lp_diag_test_ops = {
-	.open = sdio_al_test_open,
-	.write = host_sender_no_lp_diag_test_write,
-	.read = host_sender_no_lp_diag_test_read,
-};
-
-/* HOST SENDER NO LP DIAG, RPC TEST */
-static ssize_t host_sender_no_lp_diag_rpc_test_write(
-						 struct file *file,
-						 const char __user *buf,
-						 size_t count,
-						 loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- HOST SENDER NO LP FOR DIAG, RPC "
-		"TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_DIAG]);
-		set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_RPC]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t host_sender_no_lp_diag_rpc_test_read(
-						 struct file *file,
-						 char __user *buffer,
-						 size_t count,
-						 loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nHOST_SENDER_NO_LP_DIAG_RPC_TEST\n"
-		 "===================================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations host_sender_no_lp_diag_rpc_test_ops = {
-	.open = sdio_al_test_open,
-	.write = host_sender_no_lp_diag_rpc_test_write,
-	.read = host_sender_no_lp_diag_rpc_test_read,
-};
-
-/* RMNET SMALL PACKETS TEST */
-static ssize_t rmnet_small_packets_test_write(struct file *file,
-					       const char __user *buf,
-					       size_t count,
-					       loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- RMNET SMALL PACKETS (5-128) TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_a2_small_pkts(test_ctx->test_ch_arr[SDIO_RMNT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t rmnet_small_packets_test_read(struct file *file,
-					      char __user *buffer,
-					      size_t count,
-					      loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nRMNET_SMALL_PACKETS_TEST\n"
-		 "========================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations rmnet_small_packets_test_ops = {
-	.open = sdio_al_test_open,
-	.write = rmnet_small_packets_test_write,
-	.read = rmnet_small_packets_test_read,
-};
-
-/* RMNET RTT TEST */
-static ssize_t rmnet_rtt_test_write(struct file *file,
-				     const char __user *buf,
-				     size_t count,
-				     loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- RMNET RTT TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_rtt(test_ctx->test_ch_arr[SDIO_RMNT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t rmnet_rtt_test_read(struct file *file,
-				    char __user *buffer,
-				    size_t count,
-				    loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nRMNET_RTT_TEST\n"
-		 "==============\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations rmnet_rtt_test_ops = {
-	.open = sdio_al_test_open,
-	.write = rmnet_rtt_test_write,
-	.read = rmnet_rtt_test_read,
-};
-
-/* CSVT RTT TEST */
-static ssize_t csvt_rtt_test_write(struct file *file,
-				    const char __user *buf,
-				    size_t count,
-				    loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- CSVT RTT TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_rtt(test_ctx->test_ch_arr[SDIO_CSVT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t csvt_rtt_test_read(struct file *file,
-				   char __user *buffer,
-				   size_t count,
-				   loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nCSVT_RTT_TEST\n"
-		 "==============\n"
-		 "Description:\n"
-		 "In this test the HOST send a message of %d bytes "
-		 "to the CLIENT\n\n"
-		 "END OF DESCRIPTION\n", SDIO_CSVT_RTT_PACKET_SIZE);
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations csvt_rtt_test_ops = {
-	.open = sdio_al_test_open,
-	.write = csvt_rtt_test_write,
-	.read = csvt_rtt_test_read,
-};
-
-/* MODEM RESET RPC TEST */
-static ssize_t modem_reset_rpc_test_write(struct file *file,
-					   const char __user *buf,
-					   size_t count,
-					   loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- MODEM RESET - RPC CHANNEL TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RPC]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t modem_reset_rpc_test_read(struct file *file,
-					  char __user *buffer,
-					  size_t count,
-					  loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nMODEM_RESET_RPC_TEST\n"
-		 "====================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations modem_reset_rpc_test_ops = {
-	.open = sdio_al_test_open,
-	.write = modem_reset_rpc_test_write,
-	.read = modem_reset_rpc_test_read,
-};
-
-/* MODEM RESET RMNET TEST */
-static ssize_t modem_reset_rmnet_test_write(struct file *file,
-					     const char __user *buf,
-					     size_t count,
-					     loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- MODEM RESET - RMNT CHANNEL TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t modem_reset_rmnet_test_read(struct file *file,
-					    char __user *buffer,
-					    size_t count,
-					    loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nMODEM_RESET_RMNET_TEST\n"
-		 "======================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations modem_reset_rmnet_test_ops = {
-	.open = sdio_al_test_open,
-	.write = modem_reset_rmnet_test_write,
-	.read = modem_reset_rmnet_test_read,
-};
-
-/* MODEM RESET - CHANNELS IN 4BIT DEVICE TEST */
-static ssize_t modem_reset_channels_4bit_dev_test_write(
-						struct file *file,
-						const char __user *buf,
-						size_t count,
-						loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- MODEM RESET - ALL CHANNELS IN "
-		"4BIT DEVICE TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RPC]);
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_QMI]);
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DIAG]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t modem_reset_channels_4bit_dev_test_read(
-						struct file *file,
-						char __user *buffer,
-						size_t count,
-						loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nMODEM_RESET_CHANNELS_4BIT_DEV_TEST\n"
-		 "==================================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations modem_reset_channels_4bit_dev_test_ops = {
-	.open = sdio_al_test_open,
-	.write = modem_reset_channels_4bit_dev_test_write,
-	.read = modem_reset_channels_4bit_dev_test_read,
-};
-
-/* MODEM RESET - CHANNELS IN 8BIT DEVICE TEST */
-static ssize_t modem_reset_channels_8bit_dev_test_write(
-						struct file *file,
-						const char __user *buf,
-						size_t count,
-						loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- MODEM RESET - ALL CHANNELS IN "
-		"8BIT DEVICE TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DUN]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t modem_reset_channels_8bit_dev_test_read(
-						struct file *file,
-						char __user *buffer,
-						size_t count,
-						loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nMODEM_RESET_CHANNELS_8BIT_DEV_TEST\n"
-		 "==================================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations modem_reset_channels_8bit_dev_test_ops = {
-	.open = sdio_al_test_open,
-	.write = modem_reset_channels_8bit_dev_test_write,
-	.read = modem_reset_channels_8bit_dev_test_read,
-};
-
-/* MODEM RESET - ALL CHANNELS TEST */
-static ssize_t modem_reset_all_channels_test_write(struct file *file,
-						    const char __user *buf,
-						    size_t count,
-						    loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- MODEM RESET - ALL CHANNELS TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RPC]);
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_QMI]);
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DIAG]);
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DUN]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t modem_reset_all_channels_test_read(struct file *file,
-						   char __user *buffer,
-						   size_t count,
-						   loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nMODEM_RESET_ALL_CHANNELS_TEST\n"
-		 "=============================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations modem_reset_all_channels_test_ops = {
-	.open = sdio_al_test_open,
-	.write = modem_reset_all_channels_test_write,
-	.read = modem_reset_all_channels_test_read,
-};
-
-/* HOST SENDER WITH OPEN/CLOSE TEST */
-static ssize_t open_close_test_write(struct file *file,
-						   const char __user *buf,
-						   size_t count,
-						   loff_t *ppos)
-{
-	int ret = 0;
-	struct test_channel **ch_arr = test_ctx->test_ch_arr;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- HOST SENDER WITH OPEN/CLOSE TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_loopback_9k_close(ch_arr[SDIO_DIAG]);
-		set_params_loopback_9k_close(ch_arr[SDIO_RPC]);
-		set_params_loopback_9k_close(ch_arr[SDIO_SMEM]);
-		set_params_loopback_9k_close(ch_arr[SDIO_QMI]);
-		set_params_loopback_9k_close(ch_arr[SDIO_RMNT]);
-		set_params_loopback_9k_close(ch_arr[SDIO_DUN]);
-		set_params_loopback_9k_close(ch_arr[SDIO_CSVT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-
-		pr_info(TEST_MODULE_NAME " -- correctness test for"
-				"DIAG ");
-		set_params_loopback_9k(ch_arr[SDIO_DIAG]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t open_close_test_read(struct file *file,
-						  char __user *buffer,
-						  size_t count,
-						  loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nOPEN_CLOSE_TEST\n"
-		 "============================\n"
-		 "Description:\n"
-		 "In this test the host sends 5k packets to the modem in the "
-		 "following sequence: Send a random burst of packets on "
-		 "Diag and Rmnet channels, read 0 or a random number "
-		 "of packets, close and re-open the channel. At the end of the "
-		 "test, the channel is verified by running a loopback test\n\n"
-		 "END OF DESCRIPTION\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations open_close_test_ops = {
-	.open = sdio_al_test_open,
-	.write = open_close_test_write,
-	.read = open_close_test_read,
-};
-
-/* HOST SENDER WITH OPEN/CLOSE FOR DUN & RMNET TEST */
-static ssize_t open_close_dun_rmnet_test_write(struct file *file,
-						   const char __user *buf,
-						   size_t count,
-						   loff_t *ppos)
-{
-	int ret = 0;
-	struct test_channel **ch_arr = test_ctx->test_ch_arr;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- HOST SENDER WITH OPEN/CLOSE FOR "
-		"DUN AND RMNET TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_loopback_9k_close(ch_arr[SDIO_DUN]);
-		set_params_loopback_9k_close(ch_arr[SDIO_RMNT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t open_close_dun_rmnet_test_read(struct file *file,
-						  char __user *buffer,
-						  size_t count,
-						  loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nOPEN_CLOSE_DUN_RMNET_TEST\n"
-		 "============================\n"
-		 "Description:\n"
-		 "In this test the host sends 5k packets to the modem in the "
-		 "following sequence: Send a random burst of packets on "
-		 "DUN and Rmnet channels, read 0 or a random number "
-		 "of packets, close and re-open the channel.\n\n"
-		 "END OF DESCRIPTION\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations open_close_dun_rmnet_test_ops = {
-	.open = sdio_al_test_open,
-	.write = open_close_dun_rmnet_test_write,
-	.read = open_close_dun_rmnet_test_read,
-};
-
-/* CLOSE CHANNEL & LPM TEST HOST WAKES THE CLIENT TEST */
-static ssize_t close_chan_lpm_test_write(struct file *file,
-					  const char __user *buf,
-					  size_t count,
-					  loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int channel_num = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- CLOSE CHANNEL & LPM TEST "
-		"HOST WAKES THE CLIENT TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		for (channel_num = 0 ; channel_num < SDIO_MAX_CHANNELS ;
-		     channel_num++) {
-
-			ret = close_channel_lpm_test(channel_num);
-
-			if (ret)
-				break;
-
-			set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
-					    SDIO_TEST_LPM_HOST_WAKER, 120);
-
-			ret = test_start();
-
-			if (ret)
-				break;
-		}
-
-		if (ret) {
-			pr_err(TEST_MODULE_NAME " -- Close channel & LPM Test "
-			       "FAILED: %d --\n", ret);
-		} else {
-			pr_err(TEST_MODULE_NAME " -- Close channel & LPM Test "
-			       "PASSED\n");
-		}
-	}
-
-	return count;
-}
-
-static ssize_t close_chan_lpm_test_read(struct file *file,
-					 char __user *buffer,
-					 size_t count,
-					 loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nCLOSE_CHAN_LPM_TEST\n"
-		 "===================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations close_chan_lpm_test_ops = {
-	.open = sdio_al_test_open,
-	.write = close_chan_lpm_test_write,
-	.read = close_chan_lpm_test_read,
-};
-
-/* LPM TEST FOR DEVICE 1. CLIENT WAKES THE HOST TEST */
-static ssize_t lpm_test_client_wakes_host_test_write(struct file *file,
-						      const char __user *buf,
-						      size_t count,
-						      loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- LPM TEST FOR DEVICE 1. CLIENT "
-		"WAKES THE HOST TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
-				    SDIO_TEST_LPM_CLIENT_WAKER, 90);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t lpm_test_client_wakes_host_test_read(struct file *file,
-						     char __user *buffer,
-						     size_t count,
-						     loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nLPM_TEST_CLIENT_WAKES_HOST_TEST\n"
-		 "===============================\n"
-		 "Description:\n"
-		 "In this test, the HOST is going into LPM mode,\n"
-		 "and the CLIENT is responsible to send it a message\n"
-		 "in order to wake it up\n\n"
-		 "END OF DESCRIPTION\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations lpm_test_client_wakes_host_test_ops = {
-	.open = sdio_al_test_open,
-	.write = lpm_test_client_wakes_host_test_write,
-	.read = lpm_test_client_wakes_host_test_read,
-};
-
-/* LPM TEST FOR DEVICE 1. HOST WAKES THE CLIENT TEST */
-static ssize_t lpm_test_host_wakes_client_test_write(struct file *file,
-						      const char __user *buf,
-						      size_t count,
-						      loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- LPM TEST FOR DEVICE 1. HOST "
-		"WAKES THE CLIENT TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
-			    SDIO_TEST_LPM_HOST_WAKER, 120);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t lpm_test_host_wakes_client_test_read(struct file *file,
-						     char __user *buffer,
-						     size_t count,
-						     loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nLPM_TEST_HOST_WAKES_CLIENT_TEST\n"
-		 "===============================\n"
-		 "Description:\n"
-		 "In this test, the CLIENT goes into LPM mode, and the\n"
-		 "HOST is responsible to send it a message\n"
-		 "in order to wake it up\n\n"
-		 "END OF DESCRIPTION\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations lpm_test_host_wakes_client_test_ops = {
-	.open = sdio_al_test_open,
-	.write = lpm_test_host_wakes_client_test_write,
-	.read = lpm_test_host_wakes_client_test_read,
-};
-
-/* LPM TEST RANDOM, SINGLE CHANNEL TEST */
-static ssize_t lpm_test_random_single_channel_test_write(
-						struct file *file,
-						const char __user *buf,
-						size_t count,
-						loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- LPM TEST RANDOM SINGLE "
-		"CHANNEL TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_pseudo_random_seed();
-		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
-				    SDIO_TEST_LPM_RANDOM, 0);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t lpm_test_random_single_channel_test_read(
-						struct file *file,
-						char __user *buffer,
-						size_t count,
-						loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nLPM_TEST_RANDOM_SINGLE_CHANNEL_TEST\n"
-		 "===================================\n"
-		 "Description:\n"
-		 "In this test, the HOST and CLIENT "
-		 "send messages to each other,\n"
-		 "random in time, over RPC channel only.\n"
-		 "All events are being recorded, and later on,\n"
-		 "they are being analysed by the HOST and by the CLIENT\n,"
-		 "in order to check if the LPM mechanism worked properly,\n"
-		 "meaning:"
-		 " When all the relevant conditions are met, a device should:\n"
-		 "1. Go to sleep\n"
-		 "2. Wake up\n"
-		 "3. Stay awake\n\n"
-		 "END OF DESCRIPTION\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations lpm_test_random_single_channel_test_ops = {
-	.open = sdio_al_test_open,
-	.write = lpm_test_random_single_channel_test_write,
-	.read = lpm_test_random_single_channel_test_read,
-};
-
-/* LPM TEST RANDOM, MULTI CHANNEL TEST */
-static ssize_t lpm_test_random_multi_channel_test_write(
-						struct file *file,
-						const char __user *buf,
-						size_t count,
-						loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- LPM TEST RANDOM MULTI CHANNEL TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_pseudo_random_seed();
-
-		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
-				    SDIO_TEST_LPM_RANDOM, 0);
-		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_DIAG],
-				    SDIO_TEST_LPM_RANDOM, 0);
-		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_QMI],
-				SDIO_TEST_LPM_RANDOM, 0);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t lpm_test_random_multi_channel_test_read(
-				 struct file *file,
-				 char __user *buffer,
-				 size_t count,
-				 loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nLPM_TEST_RANDOM_MULTI_CHANNEL_TEST\n"
-		 "==================================\n"
-		 "Description:\n"
-		 "In this test, the HOST and CLIENT "
-		 "send messages to each other,\n"
-		 "random in time, over RPC, QMI AND DIAG channels\n"
-		 "(i.e, on both SDIO devices).\n"
-		 "All events are being recorded, and later on,\n"
-		 "they are being analysed by the HOST and by the CLIENT,\n"
-		 "in order to check if the LPM mechanism worked properly,\n"
-		 "meaning:"
-		 " When all the relevant conditions are met, a device should:\n"
-		 "1. Go to sleep\n"
-		 "2. Wake up\n"
-		 "3. Stay awake\n\n"
-		 "END OF DESCRIPTION\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations lpm_test_random_multi_channel_test_ops = {
-	.open = sdio_al_test_open,
-	.write = lpm_test_random_multi_channel_test_write,
-	.read = lpm_test_random_multi_channel_test_read,
-};
-
-static int sdio_al_test_debugfs_init(void)
-{
-	test_ctx->debug.debug_root = debugfs_create_dir("sdio_al_test",
-							       NULL);
-	if (!test_ctx->debug.debug_root)
-		return -ENOENT;
-
-	test_ctx->debug.debug_test_result = debugfs_create_u32(
-					"test_result",
-					S_IRUGO | S_IWUGO,
-					test_ctx->debug.debug_root,
-					&test_ctx->test_result);
-
-	test_ctx->debug.debug_dun_throughput = debugfs_create_u32(
-					"dun_throughput",
-					S_IRUGO | S_IWUGO,
-					test_ctx->debug.debug_root,
-					&test_ctx->debug.dun_throughput);
-
-	test_ctx->debug.debug_rmnt_throughput = debugfs_create_u32(
-					"rmnt_throughput",
-					S_IRUGO | S_IWUGO,
-					test_ctx->debug.debug_root,
-					&test_ctx->debug.rmnt_throughput);
-
-	test_ctx->debug.rpc_sender_test =
-		debugfs_create_file("10_rpc_sender_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &rpc_sender_test_ops);
-
-	test_ctx->debug.rpc_qmi_diag_sender_test =
-		debugfs_create_file("20_rpc_qmi_diag_sender_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &rpc_qmi_diag_sender_test_ops);
-
-	test_ctx->debug.rmnet_a2_validation_test =
-		debugfs_create_file("30_rmnet_a2_validation_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &rmnet_a2_validation_test_ops);
-
-	test_ctx->debug.dun_a2_validation_test =
-		debugfs_create_file("40_dun_a2_validation_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &dun_a2_validation_test_ops);
-
-	test_ctx->debug.rmnet_a2_perf_test =
-		debugfs_create_file("50_rmnet_a2_perf_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &rmnet_a2_perf_test_ops);
-
-	test_ctx->debug.dun_a2_perf_test =
-		debugfs_create_file("60_dun_a2_perf_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &dun_a2_perf_test_ops);
-
-	test_ctx->debug.csvt_a2_perf_test =
-		debugfs_create_file("71_csvt_a2_perf_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &csvt_a2_perf_test_ops);
-
-	test_ctx->debug.rmnet_dun_a2_perf_test =
-		debugfs_create_file("70_rmnet_dun_a2_perf_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &rmnet_dun_a2_perf_test_ops);
-
-	test_ctx->debug.rpc_sender_rmnet_a2_perf_test =
-		debugfs_create_file("80_rpc_sender_rmnet_a2_perf_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &rpc_sender_rmnet_a2_perf_test_ops);
-
-	test_ctx->debug.smem_test =
-		debugfs_create_file("90_smem_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &smem_test_ops);
-
-	test_ctx->debug.smem_rpc_test =
-		debugfs_create_file("100_smem_rpc_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &smem_rpc_test_ops);
-
-	test_ctx->debug.all_channels_test =
-		debugfs_create_file("150_all_channels_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &all_channels_test_ops);
-
-	test_ctx->debug.host_sender_no_lp_diag_test =
-		debugfs_create_file("160_host_sender_no_lp_diag_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &host_sender_no_lp_diag_test_ops);
-
-	test_ctx->debug.host_sender_no_lp_diag_rpc_test =
-		debugfs_create_file("170_host_sender_no_lp_diag_rpc_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &host_sender_no_lp_diag_rpc_test_ops);
-
-	test_ctx->debug.rmnet_small_packets_test =
-		debugfs_create_file("180_rmnet_small_packets_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &rmnet_small_packets_test_ops);
-
-	test_ctx->debug.rmnet_rtt_test =
-		debugfs_create_file("190_rmnet_rtt_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &rmnet_rtt_test_ops);
-
-	test_ctx->debug.csvt_rtt_test =
-		debugfs_create_file("191_csvt_rtt_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &csvt_rtt_test_ops);
-
-	test_ctx->debug.modem_reset_rpc_test =
-		debugfs_create_file("220_modem_reset_rpc_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &modem_reset_rpc_test_ops);
-
-	test_ctx->debug.modem_reset_rmnet_test =
-		debugfs_create_file("230_modem_reset_rmnet_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &modem_reset_rmnet_test_ops);
-
-	test_ctx->debug.modem_reset_channels_4bit_dev_test =
-		debugfs_create_file("240_modem_reset_channels_4bit_dev_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &modem_reset_channels_4bit_dev_test_ops);
-
-	test_ctx->debug.modem_reset_channels_8bit_dev_test =
-		debugfs_create_file("250_modem_reset_channels_8bit_dev_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &modem_reset_channels_8bit_dev_test_ops);
-
-	test_ctx->debug.modem_reset_all_channels_test =
-		debugfs_create_file("260_modem_reset_all_channels_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &modem_reset_all_channels_test_ops);
-
-	test_ctx->debug.open_close_test =
-		debugfs_create_file("270_open_close_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &open_close_test_ops);
-
-	test_ctx->debug.open_close_dun_rmnet_test =
-		debugfs_create_file("271_open_close_dun_rmnet_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &open_close_dun_rmnet_test_ops);
-
-	test_ctx->debug.close_chan_lpm_test =
-		debugfs_create_file("280_close_chan_lpm_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &close_chan_lpm_test_ops);
-
-	test_ctx->debug.lpm_test_client_wakes_host_test =
-		debugfs_create_file("600_lpm_test_client_wakes_host_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &lpm_test_client_wakes_host_test_ops);
-
-	test_ctx->debug.lpm_test_host_wakes_client_test =
-		debugfs_create_file("610_lpm_test_host_wakes_client_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &lpm_test_host_wakes_client_test_ops);
-
-	test_ctx->debug.lpm_test_random_single_channel_test =
-		debugfs_create_file("620_lpm_test_random_single_channel_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &lpm_test_random_single_channel_test_ops);
-
-	test_ctx->debug.lpm_test_random_multi_channel_test =
-		debugfs_create_file("630_lpm_test_random_multi_channel_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &lpm_test_random_multi_channel_test_ops);
-
-	if ((!test_ctx->debug.debug_dun_throughput) &&
-	    (!test_ctx->debug.debug_rmnt_throughput)) {
-		debugfs_remove_recursive(test_ctx->debug.debug_root);
-		test_ctx->debug.debug_root = NULL;
-		return -ENOENT;
-	}
-	return 0;
-}
-
-static void sdio_al_test_debugfs_cleanup(void)
-{
-       debugfs_remove(test_ctx->debug.debug_dun_throughput);
-       debugfs_remove(test_ctx->debug.debug_rmnt_throughput);
-       debugfs_remove(test_ctx->debug.debug_root);
-}
-#endif
-
-static int channel_name_to_id(char *name)
-{
-	pr_info(TEST_MODULE_NAME "%s: channel name %s\n",
-		__func__, name);
-
-	if (!strncmp(name, "SDIO_RPC_TEST",
-		     strnlen("SDIO_RPC_TEST", CHANNEL_NAME_SIZE)))
-		return SDIO_RPC;
-	else if (!strncmp(name, "SDIO_QMI_TEST",
-			  strnlen("SDIO_QMI_TEST", TEST_CH_NAME_SIZE)))
-		return SDIO_QMI;
-	else if (!strncmp(name, "SDIO_RMNT_TEST",
-			  strnlen("SDIO_RMNT_TEST", TEST_CH_NAME_SIZE)))
-		return SDIO_RMNT;
-	else if (!strncmp(name, "SDIO_DIAG_TEST",
-			  strnlen("SDIO_DIAG", TEST_CH_NAME_SIZE)))
-		return SDIO_DIAG;
-	else if (!strncmp(name, "SDIO_DUN_TEST",
-			  strnlen("SDIO_DUN_TEST", TEST_CH_NAME_SIZE)))
-		return SDIO_DUN;
-	else if (!strncmp(name, "SDIO_SMEM_TEST",
-			  strnlen("SDIO_SMEM_TEST", TEST_CH_NAME_SIZE)))
-		return SDIO_SMEM;
-	else if (!strncmp(name, "SDIO_CSVT_TEST",
-			  strnlen("SDIO_CSVT_TEST", TEST_CH_NAME_SIZE)))
-		return SDIO_CSVT;
-	else
-		return SDIO_MAX_CHANNELS;
-
-	return SDIO_MAX_CHANNELS;
-}
-
-/**
- * Allocate and add SDIO_SMEM platform device
- */
-#ifdef CONFIG_MSM_SDIO_SMEM
-static int add_sdio_smem(void)
-{
-	int ret = 0;
-
-	test_ctx->smem_pdev = platform_device_alloc("SDIO_SMEM", -1);
-	ret = platform_device_add(test_ctx->smem_pdev);
-	if (ret) {
-		pr_err(TEST_MODULE_NAME ": platform_device_add failed, "
-				   "ret=%d\n", ret);
-		return ret;
-	}
-	return 0;
-}
-#endif
-
-static int open_sdio_ch(struct test_channel *tch)
-{
-	int ret = 0;
-
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ": %s NULL tch\n", __func__);
-		return -EINVAL;
-	}
-
-	if (!tch->ch_ready) {
-		TEST_DBG(TEST_MODULE_NAME ":openning channel %s\n",
-			tch->name);
-		if (tch->ch_id == SDIO_SMEM) {
-#ifdef CONFIG_MSM_SDIO_SMEM
-			if (!test_ctx->smem_pdev)
-				ret = add_sdio_smem();
-			else
-				ret = sdio_smem_open(test_ctx->sdio_smem);
-			if (ret) {
-				pr_err(TEST_MODULE_NAME
-					":openning channel %s failed\n",
-				tch->name);
-				tch->ch_ready = false;
-				return -EINVAL;
-			}
-#endif
-		} else {
-			tch->ch_ready = true;
-			ret = sdio_open(tch->name , &tch->ch, tch,
-					notify);
-			if (ret) {
-				pr_err(TEST_MODULE_NAME
-					":openning channel %s failed\n",
-				tch->name);
-				tch->ch_ready = false;
-				return -EINVAL;
-			}
-		}
-	}
-	return ret;
-}
-
-static int close_sdio_ch(struct test_channel *tch)
-{
-	int ret = 0;
-
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ": %s NULL tch\n", __func__);
-		return -EINVAL;
-	}
-
-	if (tch->ch_id == SDIO_SMEM) {
-#ifdef CONFIG_MSM_SDIO_SMEM
-		TEST_DBG(TEST_MODULE_NAME":%s closing channel %s",
-		       __func__, tch->name);
-		ret = sdio_smem_unregister_client();
-		test_ctx->smem_counter = 0;
-#endif
-	} else {
-		ret = sdio_close(tch->ch);
-	}
-
-	if (ret) {
-		pr_err(TEST_MODULE_NAME":%s close channel %s"
-				" failed\n", __func__, tch->name);
-	} else {
-		TEST_DBG(TEST_MODULE_NAME":%s close channel %s"
-				" success\n", __func__, tch->name);
-		tch->ch_ready = false;
-	}
-	return ret;
-}
-
-/**
- * Config message
- */
-
-static void send_config_msg(struct test_channel *test_ch)
-{
-	int ret = 0 ;
-	u32 write_avail = 0;
-	int size = sizeof(test_ch->config_msg);
-
-	pr_debug(TEST_MODULE_NAME "%s\n", __func__);
-
-	memcpy(test_ch->buf, (void *)&test_ch->config_msg, size);
-
-	if (test_ctx->exit_flag) {
-		pr_info(TEST_MODULE_NAME ":Exit Test.\n");
-		return;
-	}
-
-	pr_info(TEST_MODULE_NAME ":Sending the config message.\n");
-
-	/* wait for data ready event */
-	write_avail = sdio_write_avail(test_ch->ch);
-	pr_debug(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
-	if (write_avail < size) {
-		wait_event(test_ch->wait_q,
-			   atomic_read(&test_ch->tx_notify_count));
-		atomic_dec(&test_ch->tx_notify_count);
-	}
-
-	write_avail = sdio_write_avail(test_ch->ch);
-	pr_debug(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
-	if (write_avail < size) {
-		pr_info(TEST_MODULE_NAME ":not enough write avail.\n");
-		return;
-	}
-
-	ret = sdio_write(test_ch->ch, test_ch->buf, size);
-	if (ret)
-		pr_err(TEST_MODULE_NAME ":%s sdio_write err=%d.\n",
-			__func__, -ret);
-	else
-		pr_info(TEST_MODULE_NAME ":%s sent config_msg successfully.\n",
-		       __func__);
-}
-
-/**
- * Loopback Test
- */
-static void loopback_test(struct test_channel *test_ch)
-{
-	int ret = 0 ;
-	u32 read_avail = 0;
-	u32 write_avail = 0;
-
-	while (1) {
-
-		if (test_ctx->exit_flag) {
-			pr_info(TEST_MODULE_NAME ":Exit Test.\n");
-			return;
-		}
-
-		TEST_DBG(TEST_MODULE_NAME "--LOOPBACK WAIT FOR EVENT--.\n");
-		/* wait for data ready event */
-		wait_event(test_ch->wait_q,
-			   atomic_read(&test_ch->rx_notify_count));
-		atomic_dec(&test_ch->rx_notify_count);
-
-		read_avail = sdio_read_avail(test_ch->ch);
-		if (read_avail == 0)
-			continue;
-
-
-		write_avail = sdio_write_avail(test_ch->ch);
-		if (write_avail < read_avail) {
-			pr_info(TEST_MODULE_NAME
-				":not enough write avail.\n");
-			continue;
-		}
-
-		ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
-		if (ret) {
-			pr_info(TEST_MODULE_NAME
-			       ":worker, sdio_read err=%d.\n", -ret);
-			continue;
-		}
-		test_ch->rx_bytes += read_avail;
-
-		TEST_DBG(TEST_MODULE_NAME ":worker total rx bytes = 0x%x.\n",
-			 test_ch->rx_bytes);
-
-
-		ret = sdio_write(test_ch->ch,
-				 test_ch->buf, read_avail);
-		if (ret) {
-			pr_info(TEST_MODULE_NAME
-				":loopback sdio_write err=%d.\n",
-				-ret);
-			continue;
-		}
-		test_ch->tx_bytes += read_avail;
-
-		TEST_DBG(TEST_MODULE_NAME
-			 ":loopback total tx bytes = 0x%x.\n",
-			 test_ch->tx_bytes);
-	} /* end of while */
-}
-
-/**
- * Check if all tests completed
- */
-static void check_test_completion(void)
-{
-	int i;
-
-	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
-		struct test_channel *tch = test_ctx->test_ch_arr[i];
-
-		if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
-			continue;
-		if (!tch->test_completed) {
-			pr_info(TEST_MODULE_NAME ": %s - Channel %s test is "
-				"not completed", __func__, tch->name);
-			return;
-		}
-	}
-	pr_info(TEST_MODULE_NAME ": %s - Test is completed", __func__);
-	test_ctx->test_completed = 1;
-	wake_up(&test_ctx->wait_q);
-}
-
-static int pseudo_random_seed(unsigned int *seed_number)
-{
-	if (!seed_number)
-		return 0;
-
-	*seed_number = (unsigned int)(((unsigned long)*seed_number *
-				(unsigned long)1103515367) + 35757);
-	return (int)((*seed_number / (64*1024)) % 500);
-}
-
-/* this function must be locked before accessing it */
-static void lpm_test_update_entry(struct test_channel *tch,
-				  enum lpm_test_msg_type msg_type,
-				   char *msg_name,
-				  int counter)
-{
-	u32 index = 0;
-	static int print_full = 1;
-	struct sdio_test_device *test_device;
-
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL test channel\n", __func__);
-		return;
-	}
-
-	test_device = tch->test_device;
-
-	if (!test_device) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL test device\n", __func__);
-		return;
-	}
-
-	if (!test_device->lpm_arr) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL lpm_arr\n", __func__);
-		return;
-	}
-
-	if (test_device->next_avail_entry_in_array >=
-					test_device->array_size) {
-		pr_err(TEST_MODULE_NAME ": %s - lpm array is full",
-			__func__);
-
-		if (print_full) {
-			print_hex_dump(KERN_INFO, TEST_MODULE_NAME ": lpm_arr:",
-				0, 32, 2,
-				(void *)test_device->lpm_arr,
-				sizeof(test_device->lpm_arr), false);
-			print_full = 0;
-		}
-		return;
-	}
-
-	index = test_device->next_avail_entry_in_array;
-	if ((msg_type == LPM_MSG_SEND) || (msg_type == LPM_MSG_REC))
-		test_device->lpm_arr[index].counter = counter;
-	else
-		test_device->lpm_arr[index].counter = 0;
-
-	test_device->lpm_arr[index].msg_type = msg_type;
-	memcpy(test_device->lpm_arr[index].msg_name, msg_name,
-	       LPM_MSG_NAME_SIZE);
-	test_device->lpm_arr[index].current_ms =
-		jiffies_to_msecs(get_jiffies_64());
-
-	test_device->lpm_arr[index].read_avail_mask =
-		test_device->read_avail_mask;
-
-	if ((msg_type == LPM_SLEEP) || (msg_type == LPM_WAKEUP))
-		memcpy(test_device->lpm_arr[index].chan_name, "DEVICE  ",
-		       CHANNEL_NAME_SIZE);
-	else
-		memcpy(test_device->lpm_arr[index].chan_name, tch->name,
-		       CHANNEL_NAME_SIZE);
-
-	test_device->next_avail_entry_in_array++;
-}
-
-static int wait_for_result_msg(struct test_channel *test_ch)
-{
-	u32 read_avail = 0;
-	int ret = 0;
-
-	pr_info(TEST_MODULE_NAME ": %s - START, channel %s\n",
-		__func__, test_ch->name);
-
-	while (1) {
-		read_avail = sdio_read_avail(test_ch->ch);
-
-		if (read_avail == 0) {
-			pr_info(TEST_MODULE_NAME
-				": read_avail is 0 for chan %s\n",
-				test_ch->name);
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->rx_notify_count));
-			atomic_dec(&test_ch->rx_notify_count);
-			continue;
-		}
-
-		memset(test_ch->buf, 0x00, test_ch->buf_size);
-
-		ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
-		if (ret) {
-			pr_info(TEST_MODULE_NAME ":  sdio_read for chan"
-				"%s failed, err=%d.\n",
-				test_ch->name, -ret);
-			goto exit_err;
-		}
-
-		if (test_ch->buf[0] != TEST_CONFIG_SIGNATURE) {
-			pr_info(TEST_MODULE_NAME ": Not a test_result "
-				"signature. expected 0x%x. received 0x%x "
-				"for chan %s\n",
-				TEST_CONFIG_SIGNATURE,
-				test_ch->buf[0],
-				test_ch->name);
-			continue;
-		} else {
-			pr_info(TEST_MODULE_NAME ": Signature is "
-				"TEST_CONFIG_SIGNATURE as expected for"
-				"channel %s\n", test_ch->name);
-			break;
-		}
-	}
-
-	return test_ch->buf[1];
-
-exit_err:
-	return 0;
-}
-
-static void print_random_lpm_test_array(struct sdio_test_device *test_dev)
-{
-	int i;
-
-	if (!test_dev) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL test device\n", __func__);
-		return;
-	}
-
-	for (i = 0 ; i < test_dev->next_avail_entry_in_array ; ++i) {
-		if (i == 0)
-			pr_err(TEST_MODULE_NAME ": index %4d, chan=%2s, "
-			       "code=%1d=%4s, msg#%1d, ms from before=-1, "
-			       "read_mask=0x%d, ms=%2u",
-			       i,
-			       test_dev->lpm_arr[i].chan_name,
-			       test_dev->lpm_arr[i].msg_type,
-			       test_dev->lpm_arr[i].msg_name,
-			       test_dev->lpm_arr[i].counter,
-			       test_dev->lpm_arr[i].read_avail_mask,
-			       test_dev->lpm_arr[i].current_ms);
-		else
-			pr_err(TEST_MODULE_NAME ": index "
-			       "%4d, %2s, code=%1d=%4s, msg#%1d, ms from "
-			       "before=%2u, read_mask=0x%d, ms=%2u",
-			       i,
-			       test_dev->lpm_arr[i].chan_name,
-			       test_dev->lpm_arr[i].msg_type,
-			       test_dev->lpm_arr[i].msg_name,
-			       test_dev->lpm_arr[i].counter,
-			       test_dev->lpm_arr[i].current_ms -
-			       test_dev->lpm_arr[i-1].current_ms,
-			       test_dev->lpm_arr[i].read_avail_mask,
-			       test_dev->lpm_arr[i].current_ms);
-
-		udelay(1000);
-	}
-}
-
-static int check_random_lpm_test_array(struct sdio_test_device *test_dev)
-{
-	int i = 0, j = 0;
-	unsigned int delta_ms = 0;
-	int arr_ind = 0;
-	int ret = 0;
-	int notify_counter = 0;
-	int sleep_counter = 0;
-	int wakeup_counter = 0;
-	int lpm_activity_counter = 0;
-
-	if (!test_dev) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL test device\n", __func__);
-		return -ENODEV;
-	}
-
-	for (i = 0; i < test_dev->next_avail_entry_in_array; i++) {
-		notify_counter = 0;
-		sleep_counter = 0;
-		wakeup_counter = 0;
-
-		if ((test_dev->lpm_arr[i].msg_type == LPM_MSG_SEND) ||
-		     (test_dev->lpm_arr[i].msg_type == LPM_MSG_REC)) {
-			/* find the next message in the array */
-			arr_ind = test_dev->next_avail_entry_in_array;
-			for (j = i+1; j < arr_ind; j++) {
-				if ((test_dev->lpm_arr[j].msg_type ==
-				     LPM_MSG_SEND) ||
-				    (test_dev->lpm_arr[j].msg_type ==
-				     LPM_MSG_REC) ||
-				    (test_dev->lpm_arr[j].msg_type ==
-				     LPM_NOTIFY))
-					break;
-				if (test_dev->lpm_arr[j].msg_type ==
-				    LPM_SLEEP)
-					sleep_counter++;
-				if (test_dev->lpm_arr[j].msg_type ==
-				    LPM_WAKEUP)
-					wakeup_counter++;
-			}
-			if (j == arr_ind) {
-				ret = 0;
-				break;
-			}
-
-			delta_ms = test_dev->lpm_arr[j].current_ms -
-				test_dev->lpm_arr[i].current_ms;
-			if (delta_ms < 30) {
-				if ((sleep_counter == 0)
-				    && (wakeup_counter == 0)) {
-					continue;
-				} else {
-					pr_err(TEST_MODULE_NAME "%s: lpm "
-						"activity while delta is less "
-						"than 30, i=%d, j=%d, "
-						"sleep_counter=%d, "
-						"wakeup_counter=%d",
-					       __func__, i, j,
-					       sleep_counter, wakeup_counter);
-					ret = -ENODEV;
-					break;
-				}
-			} else {
-				if ((delta_ms > 90) &&
-				    (test_dev->lpm_arr[i].
-						read_avail_mask == 0)) {
-					if (j != i+3) {
-						pr_err(TEST_MODULE_NAME
-						       "%s: unexpected "
-						       "lpm activity "
-						       "while delta is "
-						       "bigger than "
-						       "90, i=%d, "
-						       "j=%d, "
-						       "notify_counter"
-						       "=%d",
-						       __func__, i, j,
-						       notify_counter);
-						ret = -ENODEV;
-						break;
-					}
-					lpm_activity_counter++;
-				}
-			}
-		}
-	}
-
-	pr_info(TEST_MODULE_NAME ": %s - lpm_activity_counter=%d",
-		__func__, lpm_activity_counter);
-
-	return ret;
-}
-
-static int lpm_test_main_task(void *ptr)
-{
-	u32 read_avail = 0;
-	int last_msg_index = 0;
-	struct test_channel *test_ch = (struct test_channel *)ptr;
-	struct sdio_test_device *test_dev;
-	struct lpm_msg lpm_msg;
-	int ret = 0;
-	int host_result = 0;
-
-	if (!test_ch) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL channel\n", __func__);
-		return -ENODEV;
-	}
-
-	pr_err(TEST_MODULE_NAME ": %s - STARTED. channel %s\n",
-	       __func__, test_ch->name);
-
-	test_dev = test_ch->test_device;
-
-	if (!test_dev) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL Test Device\n", __func__);
-		return -ENODEV;
-	}
-
-	while (last_msg_index < test_ch->config_msg.num_packets - 1) {
-
-		TEST_DBG(TEST_MODULE_NAME ": %s - "
-			"IN LOOP last_msg_index=%d\n",
-		       __func__, last_msg_index);
-
-		read_avail = sdio_read_avail(test_ch->ch);
-		if (read_avail == 0) {
-			TEST_DBG(TEST_MODULE_NAME
-					":read_avail 0 for chan %s, "
-					"wait for event\n",
-					test_ch->name);
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->rx_notify_count));
-			atomic_dec(&test_ch->rx_notify_count);
-
-			read_avail = sdio_read_avail(test_ch->ch);
-			if (read_avail == 0) {
-				pr_err(TEST_MODULE_NAME
-					":read_avail size %d for chan %s not as"
-					" expected\n",
-					read_avail, test_ch->name);
-				continue;
-			}
-		}
-
-		memset(test_ch->buf, 0x00, sizeof(test_ch->buf));
-
-		ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
-		if (ret) {
-			pr_info(TEST_MODULE_NAME ":sdio_read for chan %s"
-				" err=%d.\n", test_ch->name, -ret);
-			goto exit_err;
-		}
-
-		memcpy((void *)&lpm_msg, test_ch->buf, sizeof(lpm_msg));
-
-		/*
-		 * when reading from channel, we want to turn off the bit
-		 * mask that implies that there is pending data on that channel
-		 */
-		if (test_ch->test_device != NULL) {
-			spin_lock_irqsave(&test_dev->lpm_array_lock,
-					  test_dev->lpm_array_lock_flags);
-
-			test_ch->notify_counter_per_chan--;
-
-			/*
-			 * if the channel has no pending data, turn off the
-			 * pending data bit mask of the channel
-			 */
-			if (test_ch->notify_counter_per_chan == 0) {
-				test_ch->test_device->read_avail_mask =
-					test_ch->test_device->read_avail_mask &
-					~test_ch->channel_mask_id;
-			}
-
-			last_msg_index = lpm_msg.counter;
-			lpm_test_update_entry(test_ch,
-					      LPM_MSG_REC,
-					      "RECEIVE",
-					      last_msg_index);
-
-			spin_unlock_irqrestore(&test_dev->lpm_array_lock,
-					       test_dev->lpm_array_lock_flags);
-		}
-	}
-
-	pr_info(TEST_MODULE_NAME ":%s: Finished to recieve all (%d) "
-		"packets from the modem %s. Waiting for result_msg",
-		__func__, test_ch->config_msg.num_packets, test_ch->name);
-
-	/* Wait for the resault message from the modem */
-	test_ch->modem_result_per_chan = wait_for_result_msg(test_ch);
-
-	/*
-	 * the DEVICE modem result is a failure if one of the channels on
-	 * that device, got modem_result = 0. this is why we bitwise "AND" each
-	 * time another channel completes its task
-	 */
-	test_dev->modem_result_per_dev &= test_ch->modem_result_per_chan;
-
-	/*
-	 * when reading from channel, we want to turn off the bit
-	 * mask that implies that there is pending data on that channel
-	 */
-	spin_lock_irqsave(&test_dev->lpm_array_lock,
-					  test_dev->lpm_array_lock_flags);
-
-	test_dev->open_channels_counter_to_recv--;
-
-	/* turning off the read_avail bit of the channel */
-	test_ch->test_device->read_avail_mask =
-		test_ch->test_device->read_avail_mask &
-		~test_ch->channel_mask_id;
-
-	spin_unlock_irqrestore(&test_dev->lpm_array_lock,
-					       test_dev->lpm_array_lock_flags);
-
-	/* Wait for all the packets to be sent to the modem */
-	while (1) {
-		spin_lock_irqsave(&test_dev->lpm_array_lock,
-				  test_dev->lpm_array_lock_flags);
-
-		if (test_ch->next_index_in_sent_msg_per_chan >=
-		    test_ch->config_msg.num_packets - 1) {
-
-			spin_unlock_irqrestore(&test_dev->lpm_array_lock,
-					       test_dev->lpm_array_lock_flags);
-			break;
-		} else {
-			pr_info(TEST_MODULE_NAME ":%s: Didn't finished to send "
-				"all packets, "
-				"next_index_in_sent_msg_per_chan = %d ",
-				__func__,
-				test_ch->next_index_in_sent_msg_per_chan);
-		}
-		spin_unlock_irqrestore(&test_dev->lpm_array_lock,
-				       test_dev->lpm_array_lock_flags);
-		msleep(60);
-	}
-
-	/*
-	 * if device has still open channels to test, then the test on the
-	 * device is still running but the test on current channel is completed
-	 */
-	if (test_dev->open_channels_counter_to_recv != 0 ||
-	    test_dev->open_channels_counter_to_send != 0) {
-		test_ch->test_completed = 1;
-		return 0;
-	} else {
-		test_ctx->number_of_active_devices--;
-		sdio_al_unregister_lpm_cb(test_ch->sdio_al_device);
-
-		if (test_ch->test_type == SDIO_TEST_LPM_RANDOM)
-			host_result = check_random_lpm_test_array(test_dev);
-
-		if (host_result ||
-		    !test_dev->modem_result_per_dev ||
-		    test_ctx->runtime_debug)
-			print_random_lpm_test_array(test_dev);
-
-		pr_info(TEST_MODULE_NAME ": %s - host_result=%d.(0 for "
-			"SUCCESS) device_modem_result=%d (1 for SUCCESS)",
-			__func__, host_result, test_dev->modem_result_per_dev);
-
-		test_ch->test_completed = 1;
-		if (test_dev->modem_result_per_dev && !host_result) {
-			pr_info(TEST_MODULE_NAME ": %s - Random LPM "
-				"TEST_PASSED for device %d of %d\n",
-				__func__,
-				(test_ctx->max_number_of_devices-
-				test_ctx->number_of_active_devices),
-				test_ctx->max_number_of_devices);
-			test_dev->final_result_per_dev = 1; /* PASSED */
-		} else {
-			pr_info(TEST_MODULE_NAME ": %s - Random LPM "
-				"TEST_FAILED for device %d of %d\n",
-				__func__,
-				(test_ctx->max_number_of_devices-
-				test_ctx->number_of_active_devices),
-				test_ctx->max_number_of_devices);
-			test_dev->final_result_per_dev = 0; /* FAILED */
-		}
-
-		check_test_completion();
-
-		kfree(test_ch->test_device->lpm_arr);
-
-		return 0;
-	}
-
-exit_err:
-	pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
-		test_ch->name);
-	test_ch->test_completed = 1;
-	test_dev->open_channels_counter_to_recv--;
-	test_dev->next_avail_entry_in_array = 0;
-	test_ch->next_index_in_sent_msg_per_chan = 0;
-	test_ch->test_result = TEST_FAILED;
-	check_test_completion();
-	return -ENODEV;
-}
-
-static int lpm_test_create_read_thread(struct test_channel *test_ch)
-{
-	struct sdio_test_device *test_dev;
-
-	pr_info(TEST_MODULE_NAME ": %s - STARTED channel %s\n",
-		__func__, test_ch->name);
-
-	if (!test_ch) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL test channel\n", __func__);
-		return -ENODEV;
-	}
-
-	test_dev = test_ch->test_device;
-
-	if (!test_dev) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL test device\n", __func__);
-		return -ENODEV;
-	}
-
-	test_dev->lpm_test_task.task_name = SDIO_LPM_TEST;
-
-	test_dev->lpm_test_task.lpm_task =
-		kthread_create(lpm_test_main_task,
-			       (void *)(test_ch),
-			       test_dev->lpm_test_task.task_name);
-
-	if (IS_ERR(test_dev->lpm_test_task.lpm_task)) {
-		pr_err(TEST_MODULE_NAME ": %s - kthread_create() failed\n",
-			__func__);
-		return -ENOMEM;
-	}
-
-	wake_up_process(test_dev->lpm_test_task.lpm_task);
-
-	return 0;
-}
-
-static void lpm_continuous_rand_test(struct test_channel *test_ch)
-{
-	unsigned int local_ms = 0;
-	int ret = 0;
-	unsigned int write_avail = 0;
-	struct sdio_test_device *test_dev;
-
-	pr_info(MODULE_NAME ": %s - STARTED\n", __func__);
-
-	if (!test_ch) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL channel\n", __func__);
-		return;
-	}
-
-	test_dev = test_ch->test_device;
-
-	if (!test_dev) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL Test Device\n", __func__);
-		return;
-	}
-
-	ret = lpm_test_create_read_thread(test_ch);
-	if (ret != 0) {
-		pr_err(TEST_MODULE_NAME ": %s - failed to create lpm reading "
-		       "thread", __func__);
-	}
-
-	while (1) {
-
-		struct lpm_msg msg;
-		u32 ret = 0;
-
-		/* sleeping period is dependent on number of open channels */
-		test_ch->config_msg.test_param =
-				test_ctx->lpm_pseudo_random_seed;
-
-		local_ms = test_dev->open_channels_counter_to_send *
-			test_ctx->lpm_pseudo_random_seed;
-		TEST_DBG(TEST_MODULE_NAME ":%s: SLEEPING for %d ms",
-		       __func__, local_ms);
-		msleep(local_ms);
-
-		msg.counter = test_ch->next_index_in_sent_msg_per_chan;
-		msg.signature = LPM_TEST_CONFIG_SIGNATURE;
-		msg.reserve1 = 0;
-		msg.reserve2 = 0;
-
-		/* wait for data ready event */
-		write_avail = sdio_write_avail(test_ch->ch);
-		pr_debug(TEST_MODULE_NAME ": %s: write_avail=%d\n",
-		       __func__, write_avail);
-		if (write_avail < sizeof(msg)) {
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->tx_notify_count));
-			atomic_dec(&test_ch->tx_notify_count);
-		}
-
-		write_avail = sdio_write_avail(test_ch->ch);
-		if (write_avail < sizeof(msg)) {
-			pr_info(TEST_MODULE_NAME ": %s: not enough write "
-				"avail.\n", __func__);
-			break;
-		}
-
-		ret = sdio_write(test_ch->ch, (u32 *)&msg, sizeof(msg));
-		if (ret)
-			pr_err(TEST_MODULE_NAME ":%s: sdio_write err=%d.\n",
-				__func__, -ret);
-
-		TEST_DBG(TEST_MODULE_NAME ": %s: for chan %s, write, "
-			 "msg # %d\n",
-			 __func__,
-			 test_ch->name,
-			 test_ch->next_index_in_sent_msg_per_chan);
-
-		if (test_ch->test_type == SDIO_TEST_LPM_RANDOM) {
-			spin_lock_irqsave(&test_dev->lpm_array_lock,
-					  test_dev->lpm_array_lock_flags);
-			lpm_test_update_entry(test_ch, LPM_MSG_SEND,
-					      "SEND  ",
-					      test_ch->
-					      next_index_in_sent_msg_per_chan);
-
-			test_ch->next_index_in_sent_msg_per_chan++;
-
-			if (test_ch->next_index_in_sent_msg_per_chan ==
-			    test_ch->config_msg.num_packets) {
-				spin_unlock_irqrestore(
-				    &test_dev->lpm_array_lock,
-				    test_dev->lpm_array_lock_flags);
-				break;
-			}
-
-			spin_unlock_irqrestore(&test_dev->lpm_array_lock,
-					       test_dev->lpm_array_lock_flags);
-		}
-	}
-
-	spin_lock_irqsave(&test_dev->lpm_array_lock,
-				  test_dev->lpm_array_lock_flags);
-	test_dev->open_channels_counter_to_send--;
-	spin_unlock_irqrestore(&test_dev->lpm_array_lock,
-				       test_dev->lpm_array_lock_flags);
-
-	pr_info(TEST_MODULE_NAME ": %s: - Finished to send all (%d) "
-		"packets to the modem on channel %s",
-		__func__, test_ch->config_msg.num_packets, test_ch->name);
-
-	return;
-}
-
-static void lpm_test(struct test_channel *test_ch)
-{
-	pr_info(TEST_MODULE_NAME ": %s - START channel %s\n", __func__,
-		test_ch->name);
-
-	if (!test_ch) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL test channel\n", __func__);
-		return;
-	}
-
-	test_ch->modem_result_per_chan = wait_for_result_msg(test_ch);
-	pr_debug(TEST_MODULE_NAME ": %s - delete the timeout timer\n",
-	       __func__);
-	del_timer_sync(&test_ch->timeout_timer);
-
-	if (test_ch->modem_result_per_chan == 0) {
-		pr_err(TEST_MODULE_NAME ": LPM TEST - Client didn't sleep. "
-		       "Result Msg - is_successful=%d\n", test_ch->buf[1]);
-		goto exit_err;
-	} else {
-		pr_info(TEST_MODULE_NAME ": %s -"
-			"LPM 9K WAS SLEEPING - PASS\n", __func__);
-		if (test_ch->test_result == TEST_PASSED) {
-			pr_info(TEST_MODULE_NAME ": LPM TEST_PASSED\n");
-			test_ch->test_completed = 1;
-			check_test_completion();
-		} else {
-			pr_err(TEST_MODULE_NAME ": LPM TEST - Host didn't "
-			       "sleep. Client slept\n");
-			goto exit_err;
-		}
-	}
-
-	return;
-
-exit_err:
-	pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
-		test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_FAILED;
-	check_test_completion();
-	return;
-}
-
-
-/**
- * LPM Test while the host wakes up the modem
- */
-static void lpm_test_host_waker(struct test_channel *test_ch)
-{
-	pr_info(TEST_MODULE_NAME ": %s - START\n", __func__);
-	wait_event(test_ch->wait_q, atomic_read(&test_ch->wakeup_client));
-	atomic_set(&test_ch->wakeup_client, 0);
-
-	pr_info(TEST_MODULE_NAME ": %s - Sending the config_msg to wakeup "
-		" the client\n", __func__);
-	send_config_msg(test_ch);
-
-	lpm_test(test_ch);
-}
-
-/**
-  * Writes number of packets into test channel
-  * @test_ch: test channel control struct
-  * @burst_size: number of packets to send
-  */
-static int write_packet_burst(struct test_channel *test_ch,
-		int burst_size)
-{
-	int ret = 0;
-	int packet_count = 0;
-	unsigned int random_num = 0;
-	int size = test_ch->packet_length; /* first packet size */
-	u32 write_avail = 0;
-
-	while (packet_count < burst_size) {
-		/* wait for data ready event */
-		write_avail = sdio_write_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":%s write_avail=%d,size=%d on chan"
-				" %s\n", __func__,
-				write_avail, size, test_ch->name);
-		if (write_avail < size) {
-			TEST_DBG(TEST_MODULE_NAME ":%s wait for event on"
-					" chan %s\n", __func__, test_ch->name);
-			wait_event(test_ch->wait_q,
-					atomic_read(&test_ch->tx_notify_count));
-			atomic_dec(&test_ch->tx_notify_count);
-		}
-		write_avail = sdio_write_avail(test_ch->ch);
-		if (write_avail < size) {
-			pr_info(TEST_MODULE_NAME ":%s not enough write"
-					" avail %d, need %d on chan %s\n",
-					__func__, write_avail, size,
-					test_ch->name);
-			continue;
-		}
-		ret = sdio_write(test_ch->ch, test_ch->buf, size);
-		if (ret) {
-			pr_err(TEST_MODULE_NAME ":%s sdio_write "
-					"failed (%d) on chan %s\n", __func__,
-					ret, test_ch->name);
-			break;
-		}
-		udelay(1000); /*low bus usage while running number of channels*/
-		TEST_DBG(TEST_MODULE_NAME ":%s() successfully write %d bytes"
-				", packet_count=%d on chan %s\n", __func__,
-				size, packet_count, test_ch->name);
-		test_ch->tx_bytes += size;
-		packet_count++;
-		/* get next packet size */
-		random_num = get_random_int();
-		size = (random_num % test_ch->packet_length) + 1;
-	}
-	return ret;
-}
-
-/**
-  * Reads packet from test channel and checks that packet number
-  * encoded into the packet is equal to packet_counter
-  * This function is applicable for packet mode channels only
-  *
-  * @test_ch: test channel
-  * @size: expected packet size
-  * @packet_counter: number to validate readed packet
-  */
-static int read_data_from_packet_ch(struct test_channel *test_ch,
-				unsigned int size,
-				int packet_counter)
-{
-	u32 read_avail = 0;
-	int ret = 0;
-
-	if (!test_ch || !test_ch->ch) {
-		pr_err(TEST_MODULE_NAME
-				":%s: NULL channel\n", __func__);
-		return -EINVAL;
-	}
-
-	if (!test_ch->ch->is_packet_mode) {
-		pr_err(TEST_MODULE_NAME
-				":%s:not packet mode ch %s\n",
-				__func__, test_ch->name);
-		return -EINVAL;
-	}
-	read_avail = sdio_read_avail(test_ch->ch);
-	/* wait for read data ready event */
-	if (read_avail < size) {
-		TEST_DBG(TEST_MODULE_NAME ":%s() wait for rx data on "
-				"chan %s\n", __func__, test_ch->name);
-		wait_event(test_ch->wait_q,
-				atomic_read(&test_ch->rx_notify_count));
-		atomic_dec(&test_ch->rx_notify_count);
-	}
-	read_avail = sdio_read_avail(test_ch->ch);
-	TEST_DBG(TEST_MODULE_NAME ":%s read_avail=%d bytes on chan %s\n",
-			__func__, read_avail, test_ch->name);
-
-	if (read_avail != size) {
-		pr_err(TEST_MODULE_NAME
-				":read_avail size %d for chan %s not as "
-				"expected size %d\n",
-				read_avail, test_ch->name, size);
-		return -EINVAL;
-	}
-
-	ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
-	if (ret) {
-		pr_err(TEST_MODULE_NAME ":%s() sdio_read for chan %s (%d)\n",
-				__func__, test_ch->name, -ret);
-		return ret;
-	}
-	if ((test_ch->buf[0] != packet_counter) && (size != 1)) {
-		pr_err(TEST_MODULE_NAME ":Read WRONG DATA"
-				" for chan %s, size=%d\n",
-				test_ch->name, size);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-
-/**
-  * Reads packet from test channel and checks that packet number
-  * encoded into the packet is equal to packet_counter
-  * This function is applicable for streaming mode channels only
-  *
-  * @test_ch: test channel
-  * @size: expected packet size
-  * @packet_counter: number to validate readed packet
-  */
-static int read_data_from_stream_ch(struct test_channel *test_ch,
-				unsigned int size,
-				int packet_counter)
-{
-	u32 read_avail = 0;
-	int ret = 0;
-
-	if (!test_ch || !test_ch->ch) {
-		pr_err(TEST_MODULE_NAME
-				":%s: NULL channel\n", __func__);
-		return -EINVAL;
-	}
-
-	if (test_ch->ch->is_packet_mode) {
-		pr_err(TEST_MODULE_NAME
-				":%s:not streaming mode ch %s\n",
-				__func__, test_ch->name);
-		return -EINVAL;
-	}
-	read_avail = sdio_read_avail(test_ch->ch);
-	/* wait for read data ready event */
-	if (read_avail < size) {
-		TEST_DBG(TEST_MODULE_NAME ":%s() wait for rx data on "
-				"chan %s\n", __func__, test_ch->name);
-		wait_event(test_ch->wait_q,
-				atomic_read(&test_ch->rx_notify_count));
-		atomic_dec(&test_ch->rx_notify_count);
-	}
-	read_avail = sdio_read_avail(test_ch->ch);
-	TEST_DBG(TEST_MODULE_NAME ":%s read_avail=%d bytes on chan %s\n",
-			__func__, read_avail, test_ch->name);
-
-	if (read_avail < size) {
-		pr_err(TEST_MODULE_NAME
-				":read_avail size %d for chan %s not as "
-				"expected size %d\n",
-				read_avail, test_ch->name, size);
-		return -EINVAL;
-	}
-
-	ret = sdio_read(test_ch->ch, test_ch->buf, size + A2_HEADER_OVERHEAD);
-	if (ret) {
-		pr_err(TEST_MODULE_NAME ":%s() sdio_read for chan %s (%d)\n",
-				__func__, test_ch->name, -ret);
-		return ret;
-	}
-	if ((test_ch->buf[A2_HEADER_OVERHEAD/4] != packet_counter) &&
-	    (size != 1)) {
-		pr_err(TEST_MODULE_NAME ":Read WRONG DATA"
-				" for chan %s, size=%d, packet_counter=%d\n",
-				test_ch->name, size, packet_counter);
-		print_hex_dump(KERN_INFO, TEST_MODULE_NAME ": rmnet:",
-				0, 32, 2,
-				(void *)test_ch->buf,
-				size + A2_HEADER_OVERHEAD, false);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-/**
- *   Test close channel feature for SDIO_SMEM channel:
- *   close && re-open the SDIO_SMEM channel.
- */
-#ifdef CONFIG_MSM_SDIO_SMEM
-static void open_close_smem_test(struct test_channel *test_ch)
-{
-	int i = 0;
-	int ret = 0;
-
-	pr_info(TEST_MODULE_NAME ":%s\n", __func__);
-
-	for (i = 0; i < 100 ; ++i) {
-		ret = close_sdio_ch(test_ch);
-		if (ret) {
-			pr_err(TEST_MODULE_NAME ":%s close_sdio_ch for ch %s"
-						" failed\n",
-						__func__, test_ch->name);
-			goto exit_err;
-		}
-		ret = open_sdio_ch(test_ch);
-		if (ret) {
-			pr_err(TEST_MODULE_NAME ":%s open_sdio_ch for ch %s "
-						" failed\n",
-						__func__, test_ch->name);
-			goto exit_err;
-		}
-	}
-
-	pr_info(TEST_MODULE_NAME ":%s TEST PASS for chan %s.\n", __func__,
-			test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_PASSED;
-	check_test_completion();
-	return;
-exit_err:
-	pr_info(TEST_MODULE_NAME ":%s TEST FAIL for chan %s.\n", __func__,
-			test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_FAILED;
-	check_test_completion();
-	return;
-}
-#endif
-
-/**
- *   Test close channel feature:
- *   1. write random packet number into channel
- *   2. read some data from channel (do this only for second half of
- *   requested packets to send).
- *   3. close && re-open then repeat 1.
- *
- *   Total packets to send: test_ch->config_msg.num_packets.
- *   Burst size is random in [1..test_ch->max_burst_size] range
- *   Packet size is random in [1..test_ch->packet_length]
- */
-static void open_close_test(struct test_channel *test_ch)
-{
-	int ret = 0;
-	u32 read_avail = 0;
-	int total_packet_count = 0;
-	int size = 0;
-	u16 *buf16 = NULL;
-	int i;
-	int max_packet_count = 0;
-	unsigned int random_num = 0;
-	int curr_burst_size = 0;
-
-	if (!test_ch || !test_ch->ch) {
-		pr_err(TEST_MODULE_NAME ":%s NULL channel\n",
-				__func__);
-		return;
-	}
-
-	curr_burst_size = test_ch->max_burst_size;
-	size = test_ch->packet_length;
-	buf16 = (u16 *) test_ch->buf;
-
-	/* the test sends configured number of packets in
-	   2 portions: first without reading between write bursts,
-	   second with it */
-	max_packet_count = test_ch->config_msg.num_packets / 2;
-
-	pr_info(TEST_MODULE_NAME ":%s channel %s, total packets:%d,"
-			" max packet size %d, max burst size:%d\n",
-			__func__, test_ch->name,
-			test_ch->config_msg.num_packets, test_ch->packet_length,
-			test_ch->max_burst_size);
-	for (i = 0 ; i < size / 2 ; i++)
-		buf16[i] = (u16) (i & 0xFFFF);
-
-	for (i = 0; i < 2 ; i++) {
-		total_packet_count = 0;
-		while (total_packet_count < max_packet_count) {
-			if (test_ctx->exit_flag) {
-				pr_info(TEST_MODULE_NAME ":%s exit test\n",
-						__func__);
-				return;
-			}
-			test_ch->buf[0] = total_packet_count;
-			random_num = get_random_int();
-			curr_burst_size = (random_num %
-					test_ch->max_burst_size) + 1;
-
-			/* limit burst size to send
-			 * no more than configured packets */
-			if (curr_burst_size + total_packet_count >
-					max_packet_count) {
-				curr_burst_size = max_packet_count -
-					total_packet_count;
-			}
-			TEST_DBG(TEST_MODULE_NAME ":%s Current burst size:%d"
-					" on chan %s\n", __func__,
-					curr_burst_size, test_ch->name);
-			ret = write_packet_burst(test_ch, curr_burst_size);
-			if (ret) {
-				pr_err(TEST_MODULE_NAME ":%s write burst failed (%d), ch %s\n",
-						__func__, ret, test_ch->name);
-				goto exit_err;
-			}
-			if (i > 0) {
-				/* read from channel */
-				if (test_ch->ch->is_packet_mode)
-					ret = read_data_from_packet_ch(test_ch,
-							size,
-							total_packet_count);
-				else
-					ret = read_data_from_stream_ch(test_ch,
-							size,
-							total_packet_count);
-				if (ret) {
-					pr_err(TEST_MODULE_NAME ":%s read"
-							" failed:%d, chan %s\n",
-							__func__, ret,
-							test_ch->name);
-					goto exit_err;
-				}
-			}
-			TEST_DBG(TEST_MODULE_NAME ":%s before close, ch %s\n",
-					__func__, test_ch->name);
-			ret = close_sdio_ch(test_ch);
-			if (ret) {
-				pr_err(TEST_MODULE_NAME":%s close channel %s"
-						" failed (%d)\n",
-						__func__, test_ch->name, ret);
-				goto exit_err;
-			} else {
-				TEST_DBG(TEST_MODULE_NAME":%s close channel %s"
-						" success\n", __func__,
-						test_ch->name);
-				total_packet_count += curr_burst_size;
-				atomic_set(&test_ch->rx_notify_count, 0);
-				atomic_set(&test_ch->tx_notify_count, 0);
-				atomic_set(&test_ch->any_notify_count, 0);
-			}
-			TEST_DBG(TEST_MODULE_NAME ":%s before open, ch %s\n",
-					__func__, test_ch->name);
-			ret = open_sdio_ch(test_ch);
-			if (ret) {
-				pr_err(TEST_MODULE_NAME":%s open channel %s"
-						" failed (%d)\n",
-						__func__, test_ch->name, ret);
-				goto exit_err;
-			} else {
-				read_avail = sdio_read_avail(test_ch->ch);
-				if (read_avail > 0) {
-					pr_err(TEST_MODULE_NAME": after open"
-						" ch %s read_availis not zero"
-						" (%d bytes)\n",
-						test_ch->name, read_avail);
-					goto exit_err;
-				}
-			}
-			TEST_DBG(TEST_MODULE_NAME ":%s total tx = %d,"
-					" packet# = %d, size = %d for ch %s\n",
-					__func__, test_ch->tx_bytes,
-					total_packet_count, size,
-					test_ch->name);
-		} /* end of while */
-	}
-	pr_info(TEST_MODULE_NAME ":%s Test end: total rx bytes = 0x%x,"
-			" total tx bytes = 0x%x for chan %s\n", __func__,
-			test_ch->rx_bytes, test_ch->tx_bytes, test_ch->name);
-	pr_info(TEST_MODULE_NAME ":%s TEST PASS for chan %s.\n", __func__,
-			test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_PASSED;
-	check_test_completion();
-	return;
-exit_err:
-	pr_info(TEST_MODULE_NAME ":%s TEST FAIL for chan %s.\n", __func__,
-			test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_FAILED;
-	check_test_completion();
-	return;
-}
-
-/**
- * sender Test
- */
-static void sender_test(struct test_channel *test_ch)
-{
-	int ret = 0 ;
-	u32 read_avail = 0;
-	u32 write_avail = 0;
-	int packet_count = 0;
-	int size = 512;
-	u16 *buf16 = (u16 *) test_ch->buf;
-	int i;
-	int max_packet_count = 10000;
-	int random_num = 0;
-
-	max_packet_count = test_ch->config_msg.num_packets;
-
-	for (i = 0 ; i < size / 2 ; i++)
-		buf16[i] = (u16) (i & 0xFFFF);
-
-
-	pr_info(TEST_MODULE_NAME
-		 ":SENDER TEST START for chan %s\n", test_ch->name);
-
-	while (packet_count < max_packet_count) {
-
-		if (test_ctx->exit_flag) {
-			pr_info(TEST_MODULE_NAME ":Exit Test.\n");
-			return;
-		}
-
-		random_num = get_random_int();
-		size = (random_num % test_ch->packet_length) + 1;
-
-		TEST_DBG(TEST_MODULE_NAME "SENDER WAIT FOR EVENT for chan %s\n",
-			test_ch->name);
-
-		/* wait for data ready event */
-		write_avail = sdio_write_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
-		if (write_avail < size) {
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->tx_notify_count));
-			atomic_dec(&test_ch->tx_notify_count);
-		}
-
-		write_avail = sdio_write_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
-		if (write_avail < size) {
-			pr_info(TEST_MODULE_NAME ":not enough write avail.\n");
-			continue;
-		}
-
-		test_ch->buf[0] = packet_count;
-
-		ret = sdio_write(test_ch->ch, test_ch->buf, size);
-		if (ret) {
-			pr_info(TEST_MODULE_NAME ":sender sdio_write err=%d.\n",
-				-ret);
-			goto exit_err;
-		}
-
-		/* wait for read data ready event */
-		TEST_DBG(TEST_MODULE_NAME ":sender wait for rx data for "
-					  "chan %s\n",
-			 test_ch->name);
-		read_avail = sdio_read_avail(test_ch->ch);
-		wait_event(test_ch->wait_q,
-			   atomic_read(&test_ch->rx_notify_count));
-		atomic_dec(&test_ch->rx_notify_count);
-
-		read_avail = sdio_read_avail(test_ch->ch);
-
-		if (read_avail != size) {
-			pr_info(TEST_MODULE_NAME
-				":read_avail size %d for chan %s not as "
-				"expected size %d.\n",
-				read_avail, test_ch->name, size);
-			goto exit_err;
-		}
-
-		memset(test_ch->buf, 0x00, size);
-
-		ret = sdio_read(test_ch->ch, test_ch->buf, size);
-		if (ret) {
-			pr_info(TEST_MODULE_NAME ":sender sdio_read for chan %s"
-						 " err=%d.\n",
-				test_ch->name, -ret);
-			goto exit_err;
-		}
-
-
-		if ((test_ch->buf[0] != packet_count) && (size != 1)) {
-			pr_info(TEST_MODULE_NAME ":sender sdio_read WRONG DATA"
-						 " for chan %s, size=%d\n",
-				test_ch->name, size);
-			goto exit_err;
-		}
-
-		test_ch->tx_bytes += size;
-		test_ch->rx_bytes += size;
-		packet_count++;
-
-		TEST_DBG(TEST_MODULE_NAME
-			 ":sender total rx bytes = 0x%x , packet#=%d, size=%d"
-			 " for chan %s\n",
-			 test_ch->rx_bytes, packet_count, size, test_ch->name);
-		TEST_DBG(TEST_MODULE_NAME
-			 ":sender total tx bytes = 0x%x , packet#=%d, size=%d"
-			 " for chan %s\n",
-			 test_ch->tx_bytes, packet_count, size, test_ch->name);
-
-	} /* end of while */
-
-	pr_info(TEST_MODULE_NAME
-		 ":SENDER TEST END: total rx bytes = 0x%x, "
-		 " total tx bytes = 0x%x for chan %s\n",
-		 test_ch->rx_bytes, test_ch->tx_bytes, test_ch->name);
-
-	pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s.\n",
-		test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_PASSED;
-	check_test_completion();
-	return;
-
-exit_err:
-	pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
-		test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_FAILED;
-	check_test_completion();
-	return;
-}
-
-/**
- * A2 Perf Test
- */
-static void a2_performance_test(struct test_channel *test_ch)
-{
-	int ret = 0 ;
-	u32 read_avail = 0;
-	u32 write_avail = 0;
-	int tx_packet_count = 0;
-	int rx_packet_count = 0;
-	int size = 0;
-	u16 *buf16 = (u16 *) test_ch->buf;
-	int i;
-	int total_bytes = 0;
-	int max_packets = 10000;
-	u32 packet_size = test_ch->buf_size;
-	int rand_size = 0;
-
-	u64 start_jiffy, end_jiffy, delta_jiffies;
-	unsigned int time_msec = 0;
-	u32 throughput = 0;
-
-	max_packets = test_ch->config_msg.num_packets;
-	packet_size = test_ch->packet_length;
-
-	for (i = 0; i < packet_size / 2; i++)
-		buf16[i] = (u16) (i & 0xFFFF);
-
-	pr_info(TEST_MODULE_NAME ": A2 PERFORMANCE TEST START for chan %s\n",
-		test_ch->name);
-
-	start_jiffy = get_jiffies_64(); /* read the current time */
-
-	while (tx_packet_count < max_packets) {
-
-		if (test_ctx->exit_flag) {
-			pr_info(TEST_MODULE_NAME ":Exit Test.\n");
-			return;
-		}
-
-		if (test_ch->random_packet_size) {
-			rand_size = get_random_int();
-			packet_size = (rand_size % test_ch->packet_length) + 1;
-			if (packet_size < A2_MIN_PACKET_SIZE)
-				packet_size = A2_MIN_PACKET_SIZE;
-		}
-
-		/* wait for data ready event */
-		/* use a func to avoid compiler optimizations */
-		write_avail = sdio_write_avail(test_ch->ch);
-		read_avail = sdio_read_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d, "
-					 "read_avail=%d for chan %s\n",
-			test_ch->name, write_avail, read_avail,
-			test_ch->name);
-		if ((write_avail == 0) && (read_avail == 0)) {
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->any_notify_count));
-			atomic_set(&test_ch->any_notify_count, 0);
-		}
-
-		write_avail = sdio_write_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d\n",
-			 test_ch->name, write_avail);
-		if (write_avail > 0) {
-			size = min(packet_size, write_avail) ;
-			TEST_DBG(TEST_MODULE_NAME ":tx size = %d for chan %s\n",
-				 size, test_ch->name);
-			test_ch->buf[0] = tx_packet_count;
-			test_ch->buf[(size/4)-1] = tx_packet_count;
-
-			ret = sdio_write(test_ch->ch, test_ch->buf, size);
-			if (ret) {
-				pr_info(TEST_MODULE_NAME ":sdio_write err=%d"
-							 " for chan %s\n",
-					-ret, test_ch->name);
-				goto exit_err;
-			}
-			tx_packet_count++;
-			test_ch->tx_bytes += size;
-		}
-
-		read_avail = sdio_read_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":channel %s, read_avail=%d\n",
-			 test_ch->name, read_avail);
-		if (read_avail > 0) {
-			size = min(packet_size, read_avail);
-			pr_debug(TEST_MODULE_NAME ":rx size = %d.\n", size);
-			ret = sdio_read(test_ch->ch, test_ch->buf, size);
-			if (ret) {
-				pr_info(TEST_MODULE_NAME ": sdio_read size %d "
-							 " err=%d"
-							 " for chan %s\n",
-					size, -ret, test_ch->name);
-				goto exit_err;
-			}
-			rx_packet_count++;
-			test_ch->rx_bytes += size;
-		}
-
-		TEST_DBG(TEST_MODULE_NAME
-			 ":total rx bytes = %d , rx_packet#=%d"
-			 " for chan %s\n",
-			 test_ch->rx_bytes, rx_packet_count, test_ch->name);
-		TEST_DBG(TEST_MODULE_NAME
-			 ":total tx bytes = %d , tx_packet#=%d"
-			 " for chan %s\n",
-			 test_ch->tx_bytes, tx_packet_count, test_ch->name);
-
-	} /* while (tx_packet_count < max_packets ) */
-
-	end_jiffy = get_jiffies_64(); /* read the current time */
-
-	delta_jiffies = end_jiffy - start_jiffy;
-	time_msec = jiffies_to_msecs(delta_jiffies);
-
-	pr_info(TEST_MODULE_NAME ":total rx bytes = 0x%x , rx_packet#=%d for"
-				 " chan %s.\n",
-		test_ch->rx_bytes, rx_packet_count, test_ch->name);
-	pr_info(TEST_MODULE_NAME ":total tx bytes = 0x%x , tx_packet#=%d"
-				 " for chan %s.\n",
-		test_ch->tx_bytes, tx_packet_count, test_ch->name);
-
-	total_bytes = (test_ch->tx_bytes + test_ch->rx_bytes);
-	pr_err(TEST_MODULE_NAME ":total bytes = %d, time msec = %d"
-				" for chan %s\n",
-		   total_bytes , (int) time_msec, test_ch->name);
-
-	if (!test_ch->random_packet_size) {
-		if (time_msec) {
-			throughput = (total_bytes / time_msec) * 8 / 1000;
-			pr_err(TEST_MODULE_NAME ": %s - Performance = "
-			       "%d Mbit/sec for chan %s\n",
-			       __func__, throughput, test_ch->name);
-		} else {
-			pr_err(TEST_MODULE_NAME ": %s - time_msec = 0 Couldn't "
-			       "calculate performence for chan %s\n",
-			   __func__, test_ch->name);
-		}
-
-	}
-
-#ifdef CONFIG_DEBUG_FS
-	switch (test_ch->ch_id) {
-	case SDIO_DUN:
-		test_ctx->debug.dun_throughput = throughput;
-		break;
-	case SDIO_RMNT:
-		test_ctx->debug.rmnt_throughput = throughput;
-		break;
-	default:
-		pr_err(TEST_MODULE_NAME "No debugfs for this channel "
-					"throughput");
-	}
-#endif
-
-	pr_err(TEST_MODULE_NAME ": A2 PERFORMANCE TEST END for chan %s.\n",
-	       test_ch->name);
-
-	pr_err(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_PASSED;
-	check_test_completion();
-	return;
-
-exit_err:
-	pr_err(TEST_MODULE_NAME ": TEST FAIL for chan %s\n", test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_FAILED;
-	check_test_completion();
-	return;
-}
-
-/**
- * rx_cleanup
- * This function reads all the messages sent by the modem until
- * the read_avail is 0 after 1 second of sleep.
- * The function returns the number of packets that was received.
- */
-static void rx_cleanup(struct test_channel *test_ch, int *rx_packet_count)
-{
-	int read_avail = 0;
-	int ret = 0;
-	int counter = 0;
-
-	if (!test_ch || !test_ch->ch) {
-		pr_err(TEST_MODULE_NAME ":%s NULL channel\n",
-				__func__);
-		return;
-	}
-
-	read_avail = sdio_read_avail(test_ch->ch);
-	TEST_DBG(TEST_MODULE_NAME ":channel %s, read_avail=%d\n",
-		 test_ch->name, read_avail);
-
-	/* If no pending messages, wait to see if the modem sends data */
-	if (read_avail == 0) {
-		msleep(1000);
-		read_avail = sdio_read_avail(test_ch->ch);
-	}
-
-	while ((read_avail > 0) && (counter < 10)) {
-		TEST_DBG(TEST_MODULE_NAME ": read_avail=%d for ch %s\n",
-			 read_avail, test_ch->name);
-
-		ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
-		if (ret) {
-			pr_info(TEST_MODULE_NAME ": sdio_read size %d "
-						 " err=%d for chan %s\n",
-				read_avail, -ret, test_ch->name);
-			break;
-		}
-		(*rx_packet_count)++;
-		test_ch->rx_bytes += read_avail;
-		read_avail = sdio_read_avail(test_ch->ch);
-		if (read_avail == 0) {
-			msleep(1000);
-			counter++;
-			read_avail = sdio_read_avail(test_ch->ch);
-		}
-	}
-	pr_info(TEST_MODULE_NAME ": finished cleanup for ch %s, "
-				 "rx_packet_count=%d, total rx bytes=%d\n",
-			 test_ch->name, *rx_packet_count, test_ch->rx_bytes);
-}
-
-
-/**
- * A2 RTT Test
- * This function sends a packet and calculate the RTT time of
- * this packet.
- * The test also calculte Min, Max and Average RTT
- */
-static void a2_rtt_test(struct test_channel *test_ch)
-{
-	int ret = 0 ;
-	u32 read_avail = 0;
-	u32 write_avail = 0;
-	int tx_packet_count = 0;
-	int rx_packet_count = 0;
-	u16 *buf16 = NULL;
-	int i;
-	int max_packets = 0;
-	u32 packet_size = 0;
-	s64 start_time, end_time;
-	int delta_usec = 0;
-	int time_average = 0;
-	int min_delta_usec = 0xFFFF;
-	int max_delta_usec = 0;
-	int total_time = 0;
-	int expected_read_size = 0;
-	int delay_ms = 0;
-	int slow_rtt_counter = 0;
-	int read_avail_so_far = 0;
-
-	if (test_ch) {
-		/*
-		 * Cleanup the pending RX data (such as loopback of the
-		 * config msg)
-		 */
-		rx_cleanup(test_ch, &rx_packet_count);
-		rx_packet_count = 0;
-	} else {
-		return;
-	}
-
-	max_packets = test_ch->config_msg.num_packets;
-	packet_size = test_ch->packet_length;
-	buf16 = (u16 *) test_ch->buf;
-
-	for (i = 0; i < packet_size / 2; i++)
-		buf16[i] = (u16) (i & 0xFFFF);
-
-	pr_info(TEST_MODULE_NAME ": A2 RTT TEST START for chan %s\n",
-		test_ch->name);
-
-	switch (test_ch->ch_id) {
-	case SDIO_RMNT:
-		delay_ms = 100;
-		break;
-	case SDIO_CSVT:
-		delay_ms = 0;
-		break;
-	default:
-		pr_err(TEST_MODULE_NAME ": %s - ch_id invalid.\n",
-		       __func__);
-		return;
-	}
-
-	while (tx_packet_count < max_packets) {
-		if (test_ctx->exit_flag) {
-			pr_info(TEST_MODULE_NAME ":Exit Test.\n");
-			return;
-		}
-		start_time = 0;
-		end_time = 0;
-		read_avail_so_far = 0;
-
-		if (delay_ms)
-			msleep(delay_ms);
-
-		/* wait for data ready event */
-		write_avail = sdio_write_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":ch %s: write_avail=%d\n",
-			test_ch->name, write_avail);
-		if (write_avail == 0) {
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->tx_notify_count));
-			atomic_dec(&test_ch->tx_notify_count);
-		}
-
-		write_avail = sdio_write_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d\n",
-			 test_ch->name, write_avail);
-		if (write_avail > 0) {
-			TEST_DBG(TEST_MODULE_NAME ":tx size = %d for chan %s\n",
-				 packet_size, test_ch->name);
-			test_ch->buf[0] = tx_packet_count;
-
-			start_time = ktime_to_us(ktime_get());
-			ret = sdio_write(test_ch->ch, test_ch->buf,
-					 packet_size);
-			if (ret) {
-				pr_err(TEST_MODULE_NAME ":sdio_write err=%d"
-							 " for chan %s\n",
-					-ret, test_ch->name);
-				goto exit_err;
-			}
-			tx_packet_count++;
-			test_ch->tx_bytes += packet_size;
-		} else {
-				pr_err(TEST_MODULE_NAME ": Invalid write_avail"
-							 " %d for chan %s\n",
-					write_avail, test_ch->name);
-				goto exit_err;
-		}
-
-		expected_read_size = packet_size + A2_HEADER_OVERHEAD;
-
-		while (read_avail_so_far < expected_read_size) {
-
-			read_avail = sdio_read_avail(test_ch->ch);
-
-			if (!read_avail) {
-				wait_event(test_ch->wait_q,
-					   atomic_read(&test_ch->
-						       rx_notify_count));
-
-				atomic_dec(&test_ch->rx_notify_count);
-				continue;
-			}
-
-			read_avail_so_far += read_avail;
-
-			if (read_avail_so_far > expected_read_size) {
-				pr_err(TEST_MODULE_NAME ": %s - Invalid "
-				       "read_avail(%d)  read_avail_so_far(%d) "
-				       "can't be larger than "
-				       "expected_read_size(%d).",
-				       __func__,
-				       read_avail,
-				       read_avail_so_far,
-				       expected_read_size);
-				goto exit_err;
-			}
-
-			/*
-			 * must read entire pending bytes, so later, we will
-			 * get a notification when more data arrives
-			 */
-			ret = sdio_read(test_ch->ch, test_ch->buf,
-					read_avail);
-
-			if (ret) {
-				pr_info(TEST_MODULE_NAME ": sdio_read size %d "
-					" err=%d for chan %s\n",
-					read_avail, -ret,
-					test_ch->name);
-				goto exit_err;
-			}
-		}
-
-		end_time = ktime_to_us(ktime_get());
-		rx_packet_count++;
-		test_ch->rx_bytes += expected_read_size;
-
-		delta_usec = (int)(end_time - start_time);
-		total_time += delta_usec;
-		if (delta_usec < min_delta_usec)
-				min_delta_usec = delta_usec;
-		if (delta_usec > max_delta_usec)
-				max_delta_usec = delta_usec;
-
-		/* checking the RTT per channel criteria */
-		if (delta_usec > MAX_AVG_RTT_TIME_USEC) {
-			pr_err(TEST_MODULE_NAME ": %s - "
-			       "msg # %d - rtt time (%d usec) is "
-			       "longer than %d usec\n",
-			       __func__,
-			       tx_packet_count,
-			       delta_usec,
-			       MAX_AVG_RTT_TIME_USEC);
-			slow_rtt_counter++;
-		}
-
-		TEST_DBG(TEST_MODULE_NAME
-			 ":RTT time=%d for packet #%d for chan %s\n",
-			 delta_usec, tx_packet_count, test_ch->name);
-	} /* while (tx_packet_count < max_packets ) */
-
-	pr_info(TEST_MODULE_NAME ": %s - tx_packet_count = %d\n",
-		__func__, tx_packet_count);
-
-	pr_info(TEST_MODULE_NAME ": %s - total rx bytes = 0x%x, "
-		"rx_packet# = %d for chan %s.\n",
-		__func__, test_ch->rx_bytes, rx_packet_count, test_ch->name);
-
-	pr_info(TEST_MODULE_NAME ": %s - total tx bytes = 0x%x, "
-		"tx_packet# = %d for chan %s.\n",
-		__func__, test_ch->tx_bytes, tx_packet_count, test_ch->name);
-
-	pr_info(TEST_MODULE_NAME ": %s - slow_rtt_counter = %d for "
-		"chan %s.\n",
-		__func__, slow_rtt_counter, test_ch->name);
-
-	if (tx_packet_count) {
-		time_average = total_time / tx_packet_count;
-		pr_info(TEST_MODULE_NAME ":Average RTT time = %d for chan %s\n",
-		   time_average, test_ch->name);
-	} else {
-		pr_err(TEST_MODULE_NAME ": %s - tx_packet_count=0. couldn't "
-		       "calculate average rtt time", __func__);
-	}
-
-	pr_info(TEST_MODULE_NAME ":MIN RTT time = %d for chan %s\n",
-		   min_delta_usec, test_ch->name);
-	pr_info(TEST_MODULE_NAME ":MAX RTT time = %d for chan %s\n",
-		   max_delta_usec, test_ch->name);
-
-	pr_info(TEST_MODULE_NAME ": A2 RTT TEST END for chan %s.\n",
-	       test_ch->name);
-
-	if (ret)
-		goto exit_err;
-
-	if (time_average == 0 || time_average > MAX_AVG_RTT_TIME_USEC) {
-		pr_err(TEST_MODULE_NAME ": %s - average_time = %d. Invalid "
-		       "value",
-		       __func__, time_average);
-		goto exit_err;
-
-	}
-
-	pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_PASSED;
-	check_test_completion();
-	return;
-
-exit_err:
-	pr_err(TEST_MODULE_NAME ": TEST FAIL for chan %s\n", test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_FAILED;
-	check_test_completion();
-	return;
-}
-
-/**
- * Process Rx Data - Helper for A2 Validation Test
- * @test_ch(in/out) : Test channel that contains Rx data buffer to process.
- *
- * @rx_unprocessed_bytes(in) : Number of bytes to process in the buffer.
- *
- * @rx_process_packet_state(in/out) :
- * Current processing state (used to identify what to process
- * next in a partial packet)
- *
- * @rx_packet_size(in/out) :
- * Number of bytes remaining in the packet to be processed.
- *
- * @rx_packet_count(in/out) :
- * Number of packets processed.
- */
-static int process_rx_data(struct test_channel *test_ch,
-			   u32 rx_unprocessed_bytes,
-			   int *rx_process_packet_state,
-			   u16 *rx_packet_size,
-			   int *rx_packet_count)
-{
-	u8 *buf = (u8 *)test_ch->buf;
-	int eop = 0;
-	int i = 0;
-	int ret = 0;
-	u32 *ptr = 0;
-	u16 size = 0;
-
-	/* process rx data */
-	while (rx_unprocessed_bytes) {
-		TEST_DBG(TEST_MODULE_NAME ": unprocessed bytes : %u\n",
-			rx_unprocessed_bytes);
-
-		switch (*rx_process_packet_state) {
-		case RX_PROCESS_PACKET_INIT:
-			/* process the A2 header */
-			TEST_DBG(TEST_MODULE_NAME ": "
-				"RX_PROCESS_PACKET_INIT\n");
-			*rx_process_packet_state = RX_PROCESS_PACKET_INIT;
-			if (rx_unprocessed_bytes < 4)
-				break;
-
-			i += 4;
-			rx_unprocessed_bytes -= 4;
-
-		case RX_PROCESS_A2_HEADER:
-			/* process the rest of A2 header */
-			TEST_DBG(TEST_MODULE_NAME ": RX_PROCESS_A2_HEADER\n");
-			*rx_process_packet_state = RX_PROCESS_A2_HEADER;
-			if (rx_unprocessed_bytes < 4)
-				break;
-
-			ptr = (u32 *)&buf[i];
-			/*
-			 * upper 2 bytes of the last 4 bytes of A2 header
-			 * contains the size of the packet
-			 */
-			*rx_packet_size = *ptr >> 0x10;
-
-			i += 4;
-			rx_unprocessed_bytes -= 4;
-
-		case RX_PROCESS_PACKET_DATA:
-			/* process the2_2_ packet data */
-			TEST_DBG(TEST_MODULE_NAME ": RX_PROCESS_PACKET_DATA "
-				 "- packet size - %u\n", *rx_packet_size);
-			*rx_process_packet_state = RX_PROCESS_PACKET_DATA;
-
-			size = *rx_packet_size;
-			if (*rx_packet_size <= rx_unprocessed_bytes) {
-				eop = *rx_packet_size;
-				*rx_packet_size = 0;
-			} else {
-				eop = rx_unprocessed_bytes;
-				*rx_packet_size = *rx_packet_size -
-						  rx_unprocessed_bytes;
-			}
-
-			/* no more bytes available to process */
-			if (!eop)
-				break;
-			/*
-			 * end of packet is starting from
-			 * the current position
-			 */
-			eop = eop + i;
-			TEST_DBG(TEST_MODULE_NAME ": size - %u, "
-				 "packet size - %u eop - %d\n",
-				 size, *rx_packet_size, eop);
-
-			/* validate the data */
-			for (; i < eop; i++) {
-				if (buf[i] != (test_ch->rx_bytes % 256)) {
-					pr_err(TEST_MODULE_NAME ": "
-					       "Corrupt data. buf:%u, "
-					       "data:%u\n", buf[i],
-					       test_ch->rx_bytes % 256);
-					ret = -EINVAL;
-					goto err;
-				}
-				rx_unprocessed_bytes--;
-				test_ch->rx_bytes++;
-			}
-
-			/* have more data to be processed */
-			if (*rx_packet_size)
-				break;
-
-			/*
-			 * A2 sends data in 4 byte alignment,
-			 * skip the padding
-			 */
-			if (size % 4) {
-				i += 4 - (size % 4);
-				rx_unprocessed_bytes -= 4 - (size % 4);
-			}
-			*rx_packet_count = *rx_packet_count + 1;
-
-			/* re init the state to process new packet */
-			*rx_process_packet_state = RX_PROCESS_PACKET_INIT;
-			break;
-		default:
-			pr_err(TEST_MODULE_NAME ": Invalid case: %d\n",
-			       *rx_process_packet_state);
-			ret = -EINVAL;
-			goto err;
-		}
-		TEST_DBG(TEST_MODULE_NAME ": Continue processing "
-			"if more data is available\n");
-	}
-
-err:
-	return ret;
-}
-
-/**
- * A2 Validation Test
- * Send packets and validate the returned packets.
- * Transmit one packet at a time, while process multiple rx
- * packets in a single transaction.
- * A transaction is of size min(random number, write_avail).
- * A packet consists of a min of 1 byte to channel supported max.
- */
-static void a2_validation_test(struct test_channel *test_ch)
-{
-	int ret = 0 ;
-	u32 read_avail = 0;
-	u32 write_avail = 0;
-	int tx_packet_count = 0;
-	int rx_packet_count = 0;
-	int initial_rx_packet_count = 0;
-	u32 size = 0;
-	u8 *buf8 = (u8 *)test_ch->buf;
-	int i = 0;
-	int max_packets = test_ch->config_msg.num_packets;
-	u16 tx_packet_size = 0;
-	u16 rx_packet_size = 0;
-	u32 random_num = 0;
-	int rx_process_packet_state = RX_PROCESS_PACKET_INIT;
-
-	pr_info(TEST_MODULE_NAME ": A2 VALIDATION TEST START for chan %s\n",
-		test_ch->name);
-
-	/* Wait for the initial rx messages before starting the test. */
-	rx_cleanup(test_ch, &initial_rx_packet_count);
-
-	test_ch->tx_bytes = 0;
-	test_ch->rx_bytes = 0;
-
-	/* Continue till we have transmitted and received all packets */
-	while ((tx_packet_count < max_packets) ||
-	       (rx_packet_count < max_packets)) {
-
-		if (test_ctx->exit_flag) {
-			pr_info(TEST_MODULE_NAME ":Exit Test.\n");
-			return;
-		}
-
-		random_num = get_random_int();
-		size = (random_num % test_ch->packet_length) + 1;
-		TEST_DBG(TEST_MODULE_NAME ": Random tx packet size =%u", size);
-
-		/*
-		 * wait for data ready event
-		 * use a func to avoid compiler optimizations
-		 */
-		write_avail = sdio_write_avail(test_ch->ch);
-		read_avail = sdio_read_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ": write_avail=%d, "
-			"read_avail=%d for chan %s\n",
-			write_avail, read_avail, test_ch->name);
-
-		if ((write_avail == 0) && (read_avail == 0)) {
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->any_notify_count));
-			atomic_set(&test_ch->any_notify_count, 0);
-		}
-
-		/* Transmit data */
-		write_avail = sdio_write_avail(test_ch->ch);
-		if ((tx_packet_count < max_packets) && (write_avail > 0)) {
-			tx_packet_size = min(size, write_avail) ;
-			TEST_DBG(TEST_MODULE_NAME ": tx size = %u, "
-				"write_avail = %u tx_packet# = %d\n",
-				tx_packet_size, write_avail,
-				tx_packet_count);
-			memset(test_ch->buf, 0, test_ch->buf_size);
-			/* populate the buffer */
-			for (i = 0; i < tx_packet_size; i++) {
-				buf8[i] = test_ch->tx_bytes % 256;
-				test_ch->tx_bytes++;
-			}
-
-			ret = sdio_write(test_ch->ch, test_ch->buf,
-					  tx_packet_size);
-			if (ret) {
-				pr_err(TEST_MODULE_NAME ":sdio_write err=%d"
-					" for chan %s\n",
-					-ret, test_ch->name);
-				goto exit_err;
-			}
-			tx_packet_count++;
-		}
-
-		/* Receive data */
-		read_avail = sdio_read_avail(test_ch->ch);
-		if (read_avail > 0) {
-			TEST_DBG(TEST_MODULE_NAME ": rx size = %u, "
-				"rx_packet#=%d.\n",
-				read_avail, rx_packet_count);
-			memset(test_ch->buf, 0, test_ch->buf_size);
-
-			ret = sdio_read(test_ch->ch, test_ch->buf,
-					read_avail);
-			if (ret) {
-				pr_err(TEST_MODULE_NAME ": sdio_read "
-					"size %d err=%d for chan %s\n",
-					size, -ret, test_ch->name);
-				goto exit_err;
-			}
-
-			/* Process data */
-			ret = process_rx_data(test_ch, read_avail,
-					      &rx_process_packet_state,
-					      &rx_packet_size,
-					      &rx_packet_count);
-
-			if (ret != 0)
-				goto exit_err;
-		}
-		TEST_DBG(TEST_MODULE_NAME ": Continue loop ...\n");
-	}
-
-	if (test_ch->tx_bytes != test_ch->rx_bytes) {
-		pr_err(TEST_MODULE_NAME ": Total number of bytes "
-			"transmitted (%u) does not match the total "
-			"number of bytes received (%u).", test_ch->tx_bytes,
-			test_ch->rx_bytes);
-		goto exit_err;
-	}
-
-	pr_info(TEST_MODULE_NAME ": A2 VALIDATION TEST END for chan %s.\n",
-		test_ch->name);
-
-	pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_PASSED;
-	check_test_completion();
-	return;
-
-exit_err:
-	pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s\n", test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_FAILED;
-	check_test_completion();
-	return;
-}
-
-/**
- * sender No loopback Test
- */
-static void sender_no_loopback_test(struct test_channel *test_ch)
-{
-	int ret = 0 ;
-	u32 write_avail = 0;
-	int packet_count = 0;
-	int size = 512;
-	u16 *buf16 = (u16 *) test_ch->buf;
-	int i;
-	int max_packet_count = 10000;
-	unsigned int random_num = 0;
-
-	max_packet_count = test_ch->config_msg.num_packets;
-
-	for (i = 0 ; i < size / 2 ; i++)
-		buf16[i] = (u16) (i & 0xFFFF);
-
-	pr_info(TEST_MODULE_NAME
-		 ":SENDER NO LP TEST START for chan %s\n", test_ch->name);
-
-	while (packet_count < max_packet_count) {
-
-		if (test_ctx->exit_flag) {
-			pr_info(TEST_MODULE_NAME ":Exit Test.\n");
-			return;
-		}
-
-		random_num = get_random_int();
-		size = (random_num % test_ch->packet_length) + 1;
-
-		TEST_DBG(TEST_MODULE_NAME ":SENDER WAIT FOR EVENT "
-					  "for chan %s\n",
-			test_ch->name);
-
-		/* wait for data ready event */
-		write_avail = sdio_write_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
-		if (write_avail < size) {
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->tx_notify_count));
-			atomic_dec(&test_ch->tx_notify_count);
-		}
-
-		write_avail = sdio_write_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
-		if (write_avail < size) {
-			pr_info(TEST_MODULE_NAME ":not enough write avail.\n");
-			continue;
-		}
-
-		test_ch->buf[0] = packet_count;
-
-		ret = sdio_write(test_ch->ch, test_ch->buf, size);
-		if (ret) {
-			pr_info(TEST_MODULE_NAME ":sender sdio_write err=%d.\n",
-				-ret);
-			goto exit_err;
-		}
-
-		test_ch->tx_bytes += size;
-		packet_count++;
-
-		TEST_DBG(TEST_MODULE_NAME
-			 ":sender total tx bytes = 0x%x , packet#=%d, size=%d"
-			 " for chan %s\n",
-			 test_ch->tx_bytes, packet_count, size, test_ch->name);
-
-	} /* end of while */
-
-	pr_info(TEST_MODULE_NAME
-		 ":SENDER TEST END: total tx bytes = 0x%x, "
-		 " for chan %s\n",
-		 test_ch->tx_bytes, test_ch->name);
-
-	test_ch->modem_result_per_chan = wait_for_result_msg(test_ch);
-
-	if (test_ch->modem_result_per_chan) {
-		pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s.\n",
-			test_ch->name);
-		test_ch->test_result = TEST_PASSED;
-	} else {
-		pr_info(TEST_MODULE_NAME ": TEST FAILURE for chan %s.\n",
-			test_ch->name);
-		test_ch->test_result = TEST_FAILED;
-	}
-	test_ch->test_completed = 1;
-	check_test_completion();
-	return;
-
-exit_err:
-	pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
-		test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_FAILED;
-	check_test_completion();
-	return;
-}
-
-
-/**
- * Modem reset Test
- * The test verifies that it finished sending all the packets
- * while there might be modem reset in the middle
- */
-static void modem_reset_test(struct test_channel *test_ch)
-{
-	int ret = 0 ;
-	u32 read_avail = 0;
-	u32 write_avail = 0;
-	int tx_packet_count = 0;
-	int rx_packet_count = 0;
-	int size = 0;
-	u16 *buf16 = (u16 *) test_ch->buf;
-	int i;
-	int max_packets = 10000;
-	u32 packet_size = test_ch->buf_size;
-	int is_err = 0;
-
-	max_packets = test_ch->config_msg.num_packets;
-	packet_size = test_ch->packet_length;
-
-	for (i = 0; i < packet_size / 2; i++)
-		buf16[i] = (u16) (i & 0xFFFF);
-
-	pr_info(TEST_MODULE_NAME ": Modem Reset TEST START for chan %s\n",
-		test_ch->name);
-
-	while (tx_packet_count < max_packets) {
-
-		if (test_ctx->exit_flag) {
-			pr_info(TEST_MODULE_NAME ":Exit Test.\n");
-			return;
-		}
-
-		if (test_ch->card_removed) {
-			pr_info(TEST_MODULE_NAME ": card removal was detected "
-				"for chan %s, tx_total=0x%x\n",
-				test_ch->name, test_ch->tx_bytes);
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->card_detected_event));
-			atomic_set(&test_ch->card_detected_event, 0);
-			pr_info(TEST_MODULE_NAME ": card_detected_event "
-					"for chan %s\n", test_ch->name);
-			if (test_ch->card_removed)
-				continue;
-			is_err = 0;
-			/* Need to wait for the modem to be ready */
-			msleep(5000);
-			pr_info(TEST_MODULE_NAME ": sending the config message "
-					"for chan %s\n", test_ch->name);
-			send_config_msg(test_ch);
-		}
-
-		/* wait for data ready event */
-		/* use a func to avoid compiler optimizations */
-		write_avail = sdio_write_avail(test_ch->ch);
-		read_avail = sdio_read_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d, "
-					 "read_avail=%d for chan %s\n",
-			test_ch->name, write_avail, read_avail,
-			test_ch->name);
-		if ((write_avail == 0) && (read_avail == 0)) {
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->any_notify_count));
-			atomic_set(&test_ch->any_notify_count, 0);
-		}
-		if (atomic_read(&test_ch->card_detected_event)) {
-			atomic_set(&test_ch->card_detected_event, 0);
-			pr_info(TEST_MODULE_NAME ": card_detected_event "
-				"for chan %s, tx_total=0x%x\n",
-				test_ch->name,  test_ch->tx_bytes);
-			if (test_ch->card_removed)
-				continue;
-			/* Need to wait for the modem to be ready */
-			msleep(5000);
-			is_err = 0;
-			pr_info(TEST_MODULE_NAME ": sending the config message "
-					"for chan %s\n", test_ch->name);
-			send_config_msg(test_ch);
-		}
-
-		write_avail = sdio_write_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d\n",
-			 test_ch->name, write_avail);
-		if (write_avail > 0) {
-			size = min(packet_size, write_avail) ;
-			pr_debug(TEST_MODULE_NAME ":tx size = %d for chan %s\n",
-				 size, test_ch->name);
-			test_ch->buf[0] = tx_packet_count;
-			test_ch->buf[(size/4)-1] = tx_packet_count;
-
-			TEST_DBG(TEST_MODULE_NAME ":channel %s, sdio_write, "
-				"size=%d\n", test_ch->name, size);
-			if (is_err) {
-				msleep(100);
-				continue;
-			}
-			ret = sdio_write(test_ch->ch, test_ch->buf, size);
-			if (ret) {
-				pr_info(TEST_MODULE_NAME ":sdio_write err=%d"
-							 " for chan %s\n",
-					-ret, test_ch->name);
-				is_err = 1;
-				msleep(20);
-				continue;
-			}
-			tx_packet_count++;
-			test_ch->tx_bytes += size;
-			test_ch->config_msg.num_packets--;
-		}
-
-		read_avail = sdio_read_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":channel %s, read_avail=%d\n",
-			 test_ch->name, read_avail);
-		if (read_avail > 0) {
-			size = min(packet_size, read_avail);
-			pr_debug(TEST_MODULE_NAME ":rx size = %d.\n", size);
-			TEST_DBG(TEST_MODULE_NAME ":channel %s, sdio_read, "
-				"size=%d\n", test_ch->name, size);
-			if (is_err) {
-				msleep(100);
-				continue;
-			}
-			ret = sdio_read(test_ch->ch, test_ch->buf, size);
-			if (ret) {
-				pr_info(TEST_MODULE_NAME ": sdio_read size %d "
-							 " err=%d"
-							 " for chan %s\n",
-					size, -ret, test_ch->name);
-				is_err = 1;
-				msleep(20);
-				continue;
-			}
-			rx_packet_count++;
-			test_ch->rx_bytes += size;
-		}
-
-		TEST_DBG(TEST_MODULE_NAME
-			 ":total rx bytes = %d , rx_packet#=%d"
-			 " for chan %s\n",
-			 test_ch->rx_bytes, rx_packet_count, test_ch->name);
-		TEST_DBG(TEST_MODULE_NAME
-			 ":total tx bytes = %d , tx_packet#=%d"
-			 " for chan %s\n",
-			 test_ch->tx_bytes, tx_packet_count, test_ch->name);
-
-		udelay(500);
-
-	} /* while (tx_packet_count < max_packets ) */
-
-	pr_info(TEST_MODULE_NAME ":total rx bytes = 0x%x , rx_packet#=%d for"
-				 " chan %s.\n",
-		test_ch->rx_bytes, rx_packet_count, test_ch->name);
-	pr_info(TEST_MODULE_NAME ":total tx bytes = 0x%x , tx_packet#=%d"
-				 " for chan %s.\n",
-		test_ch->tx_bytes, tx_packet_count, test_ch->name);
-
-	pr_err(TEST_MODULE_NAME ": Modem Reset TEST END for chan %s.\n",
-	       test_ch->name);
-
-	pr_err(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_PASSED;
-	check_test_completion();
-	return;
-}
-
-/**
- * Worker thread to handle the tests types
- */
-static void worker(struct work_struct *work)
-{
-	struct test_channel *test_ch = NULL;
-	struct test_work *test_work = container_of(work,
-						 struct	test_work,
-						 work);
-	int test_type = 0;
-
-	test_ch = test_work->test_ch;
-
-	if (test_ch == NULL) {
-		pr_err(TEST_MODULE_NAME ":NULL test_ch\n");
-		return;
-	}
-
-	test_type = test_ch->test_type;
-
-	switch (test_type) {
-	case SDIO_TEST_LOOPBACK_HOST:
-		loopback_test(test_ch);
-		break;
-	case SDIO_TEST_LOOPBACK_CLIENT:
-		sender_test(test_ch);
-		break;
-	case SDIO_TEST_PERF:
-		a2_performance_test(test_ch);
-		break;
-	case SDIO_TEST_LPM_CLIENT_WAKER:
-		lpm_test(test_ch);
-		break;
-	case SDIO_TEST_LPM_HOST_WAKER:
-		lpm_test_host_waker(test_ch);
-		break;
-	case SDIO_TEST_HOST_SENDER_NO_LP:
-		sender_no_loopback_test(test_ch);
-		break;
-	case SDIO_TEST_LPM_RANDOM:
-		lpm_continuous_rand_test(test_ch);
-		break;
-	case SDIO_TEST_RTT:
-		a2_rtt_test(test_ch);
-		break;
-	case SDIO_TEST_CLOSE_CHANNEL:
-		if (test_ch->ch_id != SDIO_SMEM)
-			open_close_test(test_ch);
-		break;
-	case SDIO_TEST_MODEM_RESET:
-		modem_reset_test(test_ch);
-		break;
-	case SDIO_TEST_A2_VALIDATION:
-		a2_validation_test(test_ch);
-		break;
-	default:
-		pr_err(TEST_MODULE_NAME ":Bad Test type = %d.\n",
-			(int) test_type);
-	}
-}
-
-
-/**
- * Notification Callback
- *
- * Notify the worker
- *
- */
-static void notify(void *priv, unsigned channel_event)
-{
-	struct test_channel *test_ch = (struct test_channel *) priv;
-
-	pr_debug(TEST_MODULE_NAME ": %s - notify event=%d.\n",
-		 __func__, channel_event);
-
-	if (test_ch->ch == NULL) {
-		pr_info(TEST_MODULE_NAME ": %s - notify before ch ready.\n",
-			__func__);
-		return;
-	}
-
-	switch (channel_event) {
-	case SDIO_EVENT_DATA_READ_AVAIL:
-		atomic_inc(&test_ch->rx_notify_count);
-		atomic_set(&test_ch->any_notify_count, 1);
-		TEST_DBG(TEST_MODULE_NAME ": %s - SDIO_EVENT_DATA_READ_AVAIL, "
-			 "any_notify_count=%d, rx_notify_count=%d\n",
-			 __func__,
-			 atomic_read(&test_ch->any_notify_count),
-			 atomic_read(&test_ch->rx_notify_count));
-		/*
-		 * when there is pending data on a channel we would like to
-		 * turn on the bit mask that implies that there is pending
-		 * data for that channel on that deivce
-		 */
-		if (test_ch->test_device != NULL &&
-		    test_ch->test_type == SDIO_TEST_LPM_RANDOM) {
-			spin_lock_irqsave(&test_ch->test_device->lpm_array_lock,
-					  test_ch->test_device->
-						  lpm_array_lock_flags);
-			test_ch->test_device->read_avail_mask |=
-				test_ch->channel_mask_id;
-			test_ch->notify_counter_per_chan++;
-
-			lpm_test_update_entry(test_ch, LPM_NOTIFY, "NOTIFY", 0);
-			spin_unlock_irqrestore(&test_ch->test_device->
-					       lpm_array_lock,
-					       test_ch->test_device->
-						  lpm_array_lock_flags);
-		}
-		break;
-
-	case SDIO_EVENT_DATA_WRITE_AVAIL:
-		atomic_inc(&test_ch->tx_notify_count);
-		atomic_set(&test_ch->any_notify_count, 1);
-		TEST_DBG(TEST_MODULE_NAME ": %s - SDIO_EVENT_DATA_WRITE_AVAIL, "
-			 "any_notify_count=%d, tx_notify_count=%d\n",
-			 __func__,
-			 atomic_read(&test_ch->any_notify_count),
-			 atomic_read(&test_ch->tx_notify_count));
-		break;
-
-	default:
-		BUG();
-	}
-	wake_up(&test_ch->wait_q);
-
-}
-
-#ifdef CONFIG_MSM_SDIO_SMEM
-static int sdio_smem_test_cb(int event)
-{
-	struct test_channel *tch = test_ctx->test_ch_arr[SDIO_SMEM];
-	int i;
-	int *smem_buf = (int *)test_ctx->smem_buf;
-	uint32_t val = 0;
-	int ret = 0;
-
-	pr_debug(TEST_MODULE_NAME ":%s: Received event %d\n", __func__, event);
-
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ": %s NULL tch\n", __func__);
-		return -EINVAL;
-	}
-
-	switch (event) {
-	case SDIO_SMEM_EVENT_READ_DONE:
-		tch->rx_bytes += SMEM_MAX_XFER_SIZE;
-		for (i = 0; i < SMEM_MAX_XFER_SIZE;) {
-			val = (int)*smem_buf;
-			if ((val != test_ctx->smem_counter) && tch->is_used) {
-				pr_err(TEST_MODULE_NAME ":%s: Invalid value %d "
-				"expected %d in smem arr",
-				__func__, val, test_ctx->smem_counter);
-				pr_err(TEST_MODULE_NAME ":SMEM test FAILED\n");
-				tch->test_completed = 1;
-				tch->test_result = TEST_FAILED;
-				check_test_completion();
-				ret = -EINVAL;
-				goto exit;
-			}
-			i += 4;
-			smem_buf++;
-			test_ctx->smem_counter++;
-		}
-		if (tch->rx_bytes >= 40000000) {
-			if ((!tch->test_completed) && tch->is_used) {
-				pr_info(TEST_MODULE_NAME ":SMEM test PASSED\n");
-				tch->test_completed = 1;
-				tch->test_result = TEST_PASSED;
-				check_test_completion();
-			}
-		}
-		break;
-	case SDIO_SMEM_EVENT_READ_ERR:
-		if (tch->is_used) {
-			pr_err(TEST_MODULE_NAME ":Read overflow, "
-						"SMEM test FAILED\n");
-			tch->test_completed = 1;
-			tch->test_result = TEST_FAILED;
-			ret = -EIO;
-		}
-		break;
-	default:
-		if (tch->is_used) {
-			pr_err(TEST_MODULE_NAME ":Unhandled event %d\n", event);
-			ret = -EINVAL;
-		}
-		break;
-	}
-exit:
-	return ret;
-}
-
-static int sdio_smem_open(struct sdio_smem_client *sdio_smem)
-{
-	int ret = 0;
-
-	if (!sdio_smem) {
-		pr_info(TEST_MODULE_NAME "%s: NULL sdio_smem_client\n",
-			__func__);
-		return -EINVAL;
-	}
-
-	if (test_ctx->test_ch_arr[SDIO_SMEM]->ch_ready) {
-		pr_info(TEST_MODULE_NAME "%s: SDIO_SMEM channel is already opened\n",
-			__func__);
-		return 0;
-	}
-
-	test_ctx->test_ch_arr[SDIO_SMEM]->ch_ready = 1;
-	sdio_smem->buf = test_ctx->smem_buf;
-	sdio_smem->size = SMEM_MAX_XFER_SIZE;
-	sdio_smem->cb_func = sdio_smem_test_cb;
-	ret = sdio_smem_register_client();
-	if (ret)
-		pr_info(TEST_MODULE_NAME "%s: Error (%d) registering sdio_smem "
-					 "test client\n",
-			__func__, ret);
-
-	return ret;
-}
-
-static int sdio_smem_test_probe(struct platform_device *pdev)
-{
-	test_ctx->sdio_smem = container_of(pdev, struct sdio_smem_client,
-					   plat_dev);
-
-	return sdio_smem_open(test_ctx->sdio_smem);
-}
-
-static struct platform_driver sdio_smem_client_drv = {
-	.probe		= sdio_smem_test_probe,
-	.driver		= {
-		.name	= "SDIO_SMEM_CLIENT",
-		.owner	= THIS_MODULE,
-	},
-};
-#endif
-
-static void sdio_test_lpm_timeout_handler(unsigned long data)
-{
-	struct test_channel *tch = (struct test_channel *)data;
-
-	pr_info(TEST_MODULE_NAME ": %s - LPM TEST TIMEOUT Expired after "
-			    "%d ms\n", __func__, tch->timeout_ms);
-	tch->test_completed = 1;
-	pr_info(TEST_MODULE_NAME ": %s - tch->test_result = TEST_FAILED\n",
-		__func__);
-	tch->test_completed = 1;
-	tch->test_result = TEST_FAILED;
-	check_test_completion();
-	return;
-}
-
-static void sdio_test_lpm_timer_handler(unsigned long data)
-{
-	struct test_channel *tch = (struct test_channel *)data;
-
-	pr_info(TEST_MODULE_NAME ": %s - LPM TEST Timer Expired after "
-			    "%d ms\n", __func__, tch->timer_interval_ms);
-
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ": %s - LPM TEST FAILED. "
-		       "tch is NULL\n", __func__);
-		return;
-	}
-
-	if (!tch->ch) {
-		pr_err(TEST_MODULE_NAME ": %s - LPM TEST FAILED. tch->ch "
-		       "is NULL\n", __func__);
-		tch->test_result = TEST_FAILED;
-		return;
-	}
-
-	/* Verfiy that we voted for sleep */
-	if (tch->is_ok_to_sleep) {
-		tch->test_result = TEST_PASSED;
-		pr_info(TEST_MODULE_NAME ": %s - 8K voted for sleep\n",
-			__func__);
-	} else {
-		tch->test_result = TEST_FAILED;
-		pr_info(TEST_MODULE_NAME ": %s - 8K voted against sleep\n",
-			__func__);
-
-	}
-
-	sdio_al_unregister_lpm_cb(tch->sdio_al_device);
-
-	if (tch->test_type == SDIO_TEST_LPM_HOST_WAKER) {
-		atomic_set(&tch->wakeup_client, 1);
-		wake_up(&tch->wait_q);
-	}
-}
-
-int sdio_test_wakeup_callback(void *device_handle, int is_vote_for_sleep)
-{
-	int i = 0;
-
-	TEST_DBG(TEST_MODULE_NAME ": %s is_vote_for_sleep=%d!!!",
-		__func__, is_vote_for_sleep);
-
-	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
-		struct test_channel *tch = test_ctx->test_ch_arr[i];
-
-		if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
-			continue;
-		if (tch->sdio_al_device == device_handle) {
-			tch->is_ok_to_sleep = is_vote_for_sleep;
-
-			if (tch->test_type == SDIO_TEST_LPM_RANDOM) {
-				spin_lock_irqsave(&tch->test_device->
-						  lpm_array_lock,
-						  tch->test_device->
-						  lpm_array_lock_flags);
-				if (is_vote_for_sleep == 1)
-					lpm_test_update_entry(tch,
-							      LPM_SLEEP,
-							      "SLEEP ", 0);
-				else
-					lpm_test_update_entry(tch,
-							      LPM_WAKEUP,
-							      "WAKEUP", 0);
-
-				spin_unlock_irqrestore(&tch->test_device->
-						       lpm_array_lock,
-						       tch->test_device->
-						       lpm_array_lock_flags);
-				break;
-			}
-		}
-	}
-
-	return 0;
-}
-
-static int sdio_test_find_dev(struct test_channel *tch)
-{
-	int j;
-	int null_index = -1;
-
-	for (j = 0 ; j < MAX_NUM_OF_SDIO_DEVICES; ++j) {
-
-		struct sdio_test_device *test_dev =
-		&test_ctx->test_dev_arr[j];
-
-		if (test_dev->sdio_al_device == NULL) {
-			if (null_index == -1)
-				null_index = j;
-			continue;
-		}
-
-		if (test_dev->sdio_al_device ==
-		    tch->ch->sdio_al_dev) {
-			test_dev->open_channels_counter_to_recv++;
-			test_dev->open_channels_counter_to_send++;
-			tch->test_device = test_dev;
-			/* setting mask id for pending data for
-			   this channel */
-			tch->channel_mask_id = test_dev->next_mask_id;
-			test_dev->next_mask_id *= 2;
-			pr_info(TEST_MODULE_NAME ": %s - channel %s "
-				"got read_mask_id = 0x%x. device "
-				"next_mask_id=0x%x",
-				__func__, tch->name, tch->channel_mask_id,
-				test_dev->next_mask_id);
-			break;
-		}
-	}
-
-	/*
-	 * happens ones a new device is "discovered" while testing. i.e
-	 * if testing a few channels, a new deivce will be "discovered" once
-	 * the first channel of a device is being tested
-	 */
-	if (j == MAX_NUM_OF_SDIO_DEVICES) {
-
-		struct sdio_test_device *test_dev =
-			&test_ctx->
-			test_dev_arr[null_index];
-		test_dev->sdio_al_device =
-			tch->ch->sdio_al_dev;
-
-		test_ctx->number_of_active_devices++;
-		test_ctx->max_number_of_devices++;
-		test_dev->open_channels_counter_to_recv++;
-		test_dev->open_channels_counter_to_send++;
-		test_dev->next_avail_entry_in_array = 0;
-		tch->test_device = test_dev;
-		tch->test_device->array_size =
-			LPM_ARRAY_SIZE;
-		test_dev->modem_result_per_dev = 1;
-		tch->modem_result_per_chan = 0;
-		test_dev->next_avail_entry_in_array = 0;
-
-		spin_lock_init(&test_dev->
-			       lpm_array_lock);
-
-		if (tch->test_type == SDIO_TEST_LPM_RANDOM) {
-			pr_err(MODULE_NAME ": %s - "
-			       "Allocating Msg Array for "
-			       "Maximum open channels for device (%d) "
-			       "Channels. Array has %d entries",
-			       __func__,
-			       LPM_MAX_OPEN_CHAN_PER_DEV,
-			       test_dev->array_size);
-
-			test_dev->lpm_arr =
-				kzalloc(sizeof(
-				struct lpm_entry_type) *
-					tch->
-					test_device->array_size,
-				GFP_KERNEL);
-
-			if (!test_dev->lpm_arr) {
-				pr_err(MODULE_NAME ": %s - "
-					"lpm_arr is NULL",
-					__func__);
-				return -ENOMEM;
-			}
-		}
-
-		/*
-		 * in new device, initialize next_mask_id, and setting
-		 * mask_id to the channel
-		 */
-		test_dev->next_mask_id = 0x1;
-		tch->channel_mask_id = test_dev->next_mask_id;
-		test_dev->next_mask_id *= 2;
-		pr_info(TEST_MODULE_NAME ": %s - channel %s got "
-			"read_mask_id = 0x%x. device next_mask_id=0x%x",
-			__func__,
-			tch->name,
-			tch->channel_mask_id,
-			test_dev->next_mask_id);
-	}
-
-	return 0;
-}
-
-static void check_test_result(void)
-{
-	int result = 1;
-	int i = 0;
-
-	test_ctx->max_number_of_devices = 0;
-
-	pr_info(TEST_MODULE_NAME ": %s - Woke Up\n", __func__);
-
-	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
-		struct test_channel *tch = test_ctx->test_ch_arr[i];
-
-		if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
-			continue;
-
-		if (tch->test_type == SDIO_TEST_LPM_RANDOM)
-			result &= tch->test_device->final_result_per_dev;
-		else
-			if (tch->test_result == TEST_FAILED) {
-				pr_info(TEST_MODULE_NAME ": %s - "
-					"Test FAILED\n", __func__);
-				test_ctx->test_result = TEST_FAILED;
-				pr_err(TEST_MODULE_NAME ": %s - "
-				       "test_result %d",
-				       __func__, test_ctx->test_result);
-				return;
-			}
-	}
-
-	if (result == 0) {
-		pr_info(TEST_MODULE_NAME ": %s - Test FAILED\n", __func__);
-		test_ctx->test_result = TEST_FAILED;
-		pr_err(TEST_MODULE_NAME ": %s - "
-		       "test_result %d",
-		       __func__, test_ctx->test_result);
-		return;
-	}
-
-	pr_info(TEST_MODULE_NAME ": %s - Test PASSED", __func__);
-	test_ctx->test_result = TEST_PASSED;
-	pr_err(TEST_MODULE_NAME ": %s - "
-	       "test_result %d",
-	       __func__, test_ctx->test_result);
-	return;
-}
-
-/**
- * Test Main
- */
-static int test_start(void)
-{
-	int ret = -ENOMEM;
-	int i;
-
-	pr_debug(TEST_MODULE_NAME ":Starting Test ....\n");
-
-	test_ctx->test_completed = 0;
-	test_ctx->test_result = TEST_NO_RESULT;
-	test_ctx->debug.dun_throughput = 0;
-	test_ctx->debug.rmnt_throughput = 0;
-	test_ctx->number_of_active_devices = 0;
-
-	pr_err(TEST_MODULE_NAME ": %s - test_result %d",
-	       __func__, test_ctx->test_result);
-
-	memset(test_ctx->test_dev_arr, 0,
-		sizeof(struct sdio_test_device)*MAX_NUM_OF_SDIO_DEVICES);
-
-	/* Open The Channels */
-	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
-		struct test_channel *tch = test_ctx->test_ch_arr[i];
-
-		if ((!tch) || (!tch->is_used))
-			continue;
-
-		tch->rx_bytes = 0;
-		tch->tx_bytes = 0;
-
-		atomic_set(&tch->tx_notify_count, 0);
-		atomic_set(&tch->rx_notify_count, 0);
-		atomic_set(&tch->any_notify_count, 0);
-		atomic_set(&tch->wakeup_client, 0);
-
-		/* in case there are values left from previous tests */
-		tch->notify_counter_per_chan = 0;
-		tch->next_index_in_sent_msg_per_chan = 0;
-
-		memset(tch->buf, 0x00, tch->buf_size);
-		tch->test_result = TEST_NO_RESULT;
-
-		tch->test_completed = 0;
-
-		ret = open_sdio_ch(tch);
-		if (ret)
-			continue;
-
-		if (tch->ch_id != SDIO_SMEM) {
-			ret = sdio_test_find_dev(tch);
-
-			if (ret) {
-				pr_err(TEST_MODULE_NAME ": %s - "
-				       "sdio_test_find_dev() returned with "
-				       "error", __func__);
-				return -ENODEV;
-			}
-
-			tch->sdio_al_device = tch->ch->sdio_al_dev;
-		}
-
-		if ((tch->test_type == SDIO_TEST_LPM_HOST_WAKER) ||
-		    (tch->test_type == SDIO_TEST_LPM_CLIENT_WAKER) ||
-		    (tch->test_type == SDIO_TEST_LPM_RANDOM))
-			sdio_al_register_lpm_cb(tch->sdio_al_device,
-					 sdio_test_wakeup_callback);
-	}
-
-	/*
-	 * make some space between opening the channels and sending the
-	 * config messages
-	 */
-	msleep(100);
-
-	/*
-	 * try to delay send_config_msg of all channels to after the point
-	 * when we open them all
-	 */
-	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
-		struct test_channel *tch = test_ctx->test_ch_arr[i];
-
-		if ((!tch) || (!tch->is_used))
-			continue;
-
-		if ((tch->ch_ready) && (tch->ch_id != SDIO_SMEM))
-			send_config_msg(tch);
-
-		if ((tch->test_type == SDIO_TEST_LPM_HOST_WAKER) ||
-		    (tch->test_type == SDIO_TEST_LPM_CLIENT_WAKER) ||
-		    (tch->test_type == SDIO_TEST_LPM_RANDOM)) {
-			if (tch->timer_interval_ms > 0) {
-				pr_info(TEST_MODULE_NAME ": %s - init timer, "
-					"ms=%d\n",
-					__func__, tch->timer_interval_ms);
-				init_timer(&tch->timer);
-				tch->timer.data = (unsigned long)tch;
-				tch->timer.function =
-					sdio_test_lpm_timer_handler;
-				tch->timer.expires = jiffies +
-				    msecs_to_jiffies(tch->timer_interval_ms);
-				add_timer(&tch->timer);
-			}
-		}
-	}
-
-	pr_debug(TEST_MODULE_NAME ":queue_work..\n");
-	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
-		struct test_channel *tch = test_ctx->test_ch_arr[i];
-
-		if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
-			continue;
-
-		if (tch->ch_id == SDIO_SMEM) {
-#ifdef CONFIG_MSM_SDIO_SMEM
-			if (tch->test_type == SDIO_TEST_CLOSE_CHANNEL)
-				open_close_smem_test(tch);
-#endif
-		} else {
-			queue_work(tch->workqueue, &tch->test_work.work);
-		}
-
-	}
-
-	pr_info(TEST_MODULE_NAME ": %s - Waiting for the test completion\n",
-		__func__);
-
-	wait_event(test_ctx->wait_q, test_ctx->test_completed);
-	check_test_result();
-
-	/*
-	 * Close the channels and zero the is_used flag so that if the modem
-	 * will be reset after the test completion we won't re-open
-	 * the channels
-	 */
-	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
-		struct test_channel *tch = test_ctx->test_ch_arr[i];
-
-		if ((!tch) || (!tch->is_used))
-			continue;
-		if (!tch->ch_ready) {
-			tch->is_used = 0;
-			continue;
-		}
-
-		close_sdio_ch(tch);
-		tch->is_used = 0;
-	}
-
-	if (test_ctx->test_result == TEST_PASSED)
-		return 0;
-	else
-		return -EINVAL;
-}
-
-static int set_params_loopback_9k(struct test_channel *tch)
-{
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ":NULL channel\n");
-		return -EINVAL;
-	}
-	tch->is_used = 1;
-	tch->test_type = SDIO_TEST_LOOPBACK_CLIENT;
-	tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
-	tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
-	tch->config_msg.num_packets = 10000;
-	tch->config_msg.num_iterations = 1;
-
-	tch->packet_length = 512;
-	if (tch->ch_id == SDIO_RPC)
-		tch->packet_length = 128;
-	tch->timer_interval_ms = 0;
-
-	return 0;
-}
-static int set_params_loopback_9k_close(struct test_channel *tch)
-{
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ":NULL channel\n");
-		return -EINVAL;
-	}
-	tch->is_used = 1;
-	tch->test_type = SDIO_TEST_CLOSE_CHANNEL;
-	tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
-	tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
-	tch->config_msg.num_packets = 5000;
-	tch->config_msg.num_iterations = 1;
-	tch->max_burst_size = 10;
-	switch (tch->ch_id) {
-	case SDIO_DUN:
-	case SDIO_RPC:
-		tch->packet_length = 128; /* max is 2K*/
-		break;
-	case SDIO_DIAG:
-	case SDIO_RMNT:
-	default:
-		tch->packet_length = 512; /* max is 4k */
-	}
-	tch->timer_interval_ms = 0;
-	return 0;
-}
-static int set_params_a2_perf(struct test_channel *tch)
-{
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ":NULL channel\n");
-		return -EINVAL;
-	}
-	tch->is_used = 1;
-	tch->test_type = SDIO_TEST_PERF;
-	tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
-	tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
-
-	switch (tch->ch_id) {
-	case SDIO_DIAG:
-		tch->packet_length = 512;
-		break;
-	case SDIO_DUN:
-		tch->packet_length = DUN_PACKET_SIZE;
-		break;
-	case SDIO_CSVT:
-		tch->packet_length = CSVT_PACKET_SIZE;
-		break;
-	default:
-		tch->packet_length = MAX_XFER_SIZE;
-		break;
-	}
-
-	pr_info(TEST_MODULE_NAME ": %s: packet_length=%d", __func__,
-			tch->packet_length);
-
-	tch->config_msg.num_packets = 10000;
-	tch->config_msg.num_iterations = 1;
-	tch->random_packet_size = 0;
-
-	tch->timer_interval_ms = 0;
-
-	return 0;
-}
-
-static int set_params_rtt(struct test_channel *tch)
-{
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ":NULL channel\n");
-		return -EINVAL;
-	}
-	tch->is_used = 1;
-	tch->test_type = SDIO_TEST_RTT;
-	tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
-	tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
-
-	switch (tch->ch_id) {
-	case SDIO_RMNT:
-		tch->packet_length = SDIO_RMNT_RTT_PACKET_SIZE;
-		break;
-	case SDIO_CSVT:
-		tch->packet_length = SDIO_CSVT_RTT_PACKET_SIZE;
-		break;
-	default:
-		pr_err(TEST_MODULE_NAME ": %s - ch_id invalid.\n", __func__);
-		return -EINVAL;
-	}
-
-	pr_info(TEST_MODULE_NAME ": %s: packet_length=%d", __func__,
-			tch->packet_length);
-
-	tch->config_msg.num_packets = 200;
-	tch->config_msg.num_iterations = 1;
-	tch->random_packet_size = 0;
-
-	tch->timer_interval_ms = 0;
-
-	return 0;
-}
-
-static int set_params_a2_small_pkts(struct test_channel *tch)
-{
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ":NULL channel\n");
-		return -EINVAL;
-	}
-	tch->is_used = 1;
-	tch->test_type = SDIO_TEST_PERF;
-	tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
-	tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
-	tch->packet_length = 128;
-
-	tch->config_msg.num_packets = 1000000;
-	tch->config_msg.num_iterations = 1;
-	tch->random_packet_size = 1;
-
-	tch->timer_interval_ms = 0;
-
-	return 0;
-}
-
-static int set_params_modem_reset(struct test_channel *tch)
-{
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ":NULL channel\n");
-		return -EINVAL;
-	}
-	tch->is_used = 1;
-	tch->test_type = SDIO_TEST_MODEM_RESET;
-	tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
-	tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
-	tch->packet_length = 512;
-	if (tch->ch_id == SDIO_RPC)
-		tch->packet_length = 128;
-	else if ((tch->ch_id == SDIO_RMNT) || (tch->ch_id == SDIO_DUN))
-		tch->packet_length = MAX_XFER_SIZE;
-
-	tch->config_msg.num_packets = 50000;
-	tch->config_msg.num_iterations = 1;
-
-	tch->timer_interval_ms = 0;
-
-	return 0;
-}
-
-static int set_params_a2_validation(struct test_channel *tch)
-{
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ":NULL channel\n");
-		return -EINVAL;
-	}
-	tch->is_used = 1;
-	tch->test_type = SDIO_TEST_A2_VALIDATION;
-	tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
-	tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
-
-	if (tch->ch_id == SDIO_RMNT)
-		tch->packet_length = RMNT_PACKET_SIZE;
-	else if (tch->ch_id == SDIO_DUN)
-		tch->packet_length = DUN_PACKET_SIZE;
-	else
-		tch->packet_length = MAX_XFER_SIZE;
-
-	tch->config_msg.num_packets = 10000;
-	tch->config_msg.num_iterations = 1;
-	tch->timer_interval_ms = 0;
-
-	return 0;
-}
-
-static int set_params_smem_test(struct test_channel *tch)
-{
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ":NULL channel\n");
-		return -EINVAL;
-	}
-	tch->is_used = 1;
-	tch->timer_interval_ms = 0;
-
-	return 0;
-}
-
-static int set_params_lpm_test(struct test_channel *tch,
-				enum sdio_test_case_type test,
-				int timer_interval_ms)
-{
-	static int first_time = 1;
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL channel\n", __func__);
-		return -EINVAL;
-	}
-
-	tch->is_used = 1;
-	tch->test_type = test;
-	tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
-	tch->config_msg.test_case = test;
-	tch->config_msg.num_packets = LPM_TEST_NUM_OF_PACKETS;
-	tch->config_msg.num_iterations = 1;
-	tch->timer_interval_ms = timer_interval_ms;
-	tch->timeout_ms = 10000;
-
-	tch->packet_length = 0;
-	if (test != SDIO_TEST_LPM_RANDOM) {
-		init_timer(&tch->timeout_timer);
-		tch->timeout_timer.data = (unsigned long)tch;
-		tch->timeout_timer.function = sdio_test_lpm_timeout_handler;
-		tch->timeout_timer.expires = jiffies +
-			msecs_to_jiffies(tch->timeout_ms);
-		add_timer(&tch->timeout_timer);
-		pr_info(TEST_MODULE_NAME ": %s - Initiated LPM TIMEOUT TIMER."
-			"set to %d ms\n",
-			__func__, tch->timeout_ms);
-	}
-
-	if (first_time) {
-		pr_info(TEST_MODULE_NAME ": %s - wake_lock_init() called\n",
-		__func__);
-		wake_lock_init(&test_ctx->wake_lock,
-			       WAKE_LOCK_SUSPEND, TEST_MODULE_NAME);
-		first_time = 0;
-	}
-
-	pr_info(TEST_MODULE_NAME ": %s - wake_lock() for the TEST is "
-		"called channel %s. to prevent real sleeping\n",
-		__func__, tch->name);
-	wake_lock(&test_ctx->wake_lock);
-
-	return 0;
-}
-
-static int set_params_8k_sender_no_lp(struct test_channel *tch)
-{
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ":NULL channel\n");
-		return -EINVAL;
-	}
-	tch->is_used = 1;
-	tch->test_type = SDIO_TEST_HOST_SENDER_NO_LP;
-	tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
-	tch->config_msg.test_case = SDIO_TEST_HOST_SENDER_NO_LP;
-	tch->config_msg.num_packets = 1000;
-	tch->config_msg.num_iterations = 1;
-
-	tch->packet_length = 512;
-	if (tch->ch_id == SDIO_RPC)
-		tch->packet_length = 128;
-	tch->timer_interval_ms = 0;
-
-	return 0;
-}
-
-static void set_pseudo_random_seed(void)
-{
-	/* Set the seed accoring to the kernel command parameters if any or
-	   get a random value */
-	if (seed != 0) {
-		test_ctx->lpm_pseudo_random_seed = seed;
-	} else {
-		test_ctx->lpm_pseudo_random_seed =
-			(unsigned int)(get_jiffies_64() & 0xFFFF);
-		test_ctx->lpm_pseudo_random_seed =
-			pseudo_random_seed(&test_ctx->lpm_pseudo_random_seed);
-	}
-
-	pr_info(TEST_MODULE_NAME ":%s: seed is %u",
-		   __func__, test_ctx->lpm_pseudo_random_seed);
-}
-
-/*
-   for each channel
-   1. open channel
-   2. close channel
-*/
-static int close_channel_lpm_test(int channel_num)
-{
-	int ret = 0;
-	struct test_channel *tch = NULL;
-	tch = test_ctx->test_ch_arr[channel_num];
-
-	if (!tch) {
-		pr_info(TEST_MODULE_NAME ":%s ch#%d is NULL\n",
-			__func__, channel_num);
-		return 0;
-	}
-
-	ret = open_sdio_ch(tch);
-	if (ret) {
-		pr_err(TEST_MODULE_NAME":%s open channel %s"
-			" failed\n", __func__, tch->name);
-		return ret;
-	} else {
-		pr_info(TEST_MODULE_NAME":%s open channel %s"
-			" success\n", __func__, tch->name);
-	}
-	ret = close_sdio_ch(tch);
-	if (ret) {
-		pr_err(TEST_MODULE_NAME":%s close channel %s"
-				" failed\n", __func__, tch->name);
-		return ret;
-	} else {
-		pr_info(TEST_MODULE_NAME":%s close channel %s"
-				" success\n", __func__, tch->name);
-	}
-
-	tch->is_used = 0;
-
-	return ret;
-}
-
-/**
- * Write File.
- *
- * @note Trigger the test from user space by:
- * echo 1 > /dev/sdio_al_test
- *
- */
-ssize_t test_write(struct file *filp, const char __user *buf, size_t size,
-		   loff_t *f_pos)
-{
-	sdio_al_test_initial_dev_and_chan(test_ctx);
-
-	if (strict_strtol(buf, 10, &test_ctx->testcase))
-		return -EINVAL;
-
-	switch (test_ctx->testcase) {
-	case 98:
-		pr_info(TEST_MODULE_NAME " set runtime debug on");
-		test_ctx->runtime_debug = 1;
-		return size;
-	case 99:
-		pr_info(TEST_MODULE_NAME " set runtime debug off");
-		test_ctx->runtime_debug = 0;
-		return size;
-	default:
-		pr_info(TEST_MODULE_NAME ":Bad Test number = %d.\n",
-			(int)test_ctx->testcase);
-		return size;
-	}
-
-	return size;
-}
-
-/**
- * Test Channel Init.
- */
-int test_channel_init(char *name)
-{
-	struct test_channel *test_ch;
-	int ch_id = 0;
-	int ret;
-
-	pr_debug(TEST_MODULE_NAME ":%s.\n", __func__);
-	pr_info(TEST_MODULE_NAME ": init test channel %s.\n", name);
-
-	ch_id = channel_name_to_id(name);
-	pr_debug(TEST_MODULE_NAME ":id = %d.\n", ch_id);
-	if (test_ctx->test_ch_arr[ch_id] == NULL) {
-		test_ch = kzalloc(sizeof(*test_ch), GFP_KERNEL);
-		if (test_ch == NULL) {
-			pr_err(TEST_MODULE_NAME ":kzalloc err for allocating "
-						"test_ch %s.\n",
-			       name);
-			return -ENOMEM;
-		}
-		test_ctx->test_ch_arr[ch_id] = test_ch;
-
-		test_ch->ch_id = ch_id;
-
-		strncpy(test_ch->name, name,
-		       strnlen(name, TEST_CH_NAME_SIZE)-SDIO_TEST_POSTFIX_SIZE);
-
-		test_ch->buf_size = MAX_XFER_SIZE;
-
-		test_ch->buf = kzalloc(test_ch->buf_size, GFP_KERNEL);
-		if (test_ch->buf == NULL) {
-			kfree(test_ch);
-			test_ctx->test_ch = NULL;
-			return -ENOMEM;
-		}
-
-		if (test_ch->ch_id == SDIO_SMEM) {
-			test_ctx->smem_buf = kzalloc(SMEM_MAX_XFER_SIZE,
-						     GFP_KERNEL);
-			if (test_ctx->smem_buf == NULL) {
-				pr_err(TEST_MODULE_NAME ":%s: Unable to "
-							"allocate smem buf\n",
-				       __func__);
-				kfree(test_ch);
-				test_ctx->test_ch = NULL;
-				return -ENOMEM;
-			}
-
-#ifdef CONFIG_MSM_SDIO_SMEM
-			ret = platform_driver_register(&sdio_smem_client_drv);
-			if (ret) {
-				pr_err(TEST_MODULE_NAME ":%s: Unable to "
-							"register sdio smem "
-							"test client\n",
-				       __func__);
-				return ret;
-			}
-#endif
-		} else {
-			test_ch->workqueue =
-				create_singlethread_workqueue(test_ch->name);
-			test_ch->test_work.test_ch = test_ch;
-			INIT_WORK(&test_ch->test_work.work, worker);
-
-			init_waitqueue_head(&test_ch->wait_q);
-		}
-	} else {
-		test_ch = test_ctx->test_ch_arr[ch_id];
-		pr_info(TEST_MODULE_NAME ":%s: ch %s was detected again\n",
-			__func__, test_ch->name);
-		test_ch->card_removed = 0;
-		if ((test_ch->is_used) &&
-		    (test_ch->test_type == SDIO_TEST_MODEM_RESET)) {
-			if (test_ch->ch_id == SDIO_SMEM) {
-#ifdef CONFIG_MSM_SDIO_SMEM
-				ret = add_sdio_smem();
-				if (ret) {
-					test_ch->ch_ready = false;
-					return 0;
-				}
-#endif
-			} else {
-				ret = open_sdio_ch(test_ch);
-				if (ret) {
-					pr_info(TEST_MODULE_NAME
-						":%s: open channel %s failed\n",
-					__func__, test_ch->name);
-					return 0;
-				}
-				ret = sdio_test_find_dev(test_ch);
-
-				if (ret) {
-					pr_err(TEST_MODULE_NAME ": %s - "
-					       "sdio_test_find_dev() returned "
-					       "with error", __func__);
-					return -ENODEV;
-				}
-
-				test_ch->sdio_al_device =
-					test_ch->ch->sdio_al_dev;
-			}
-			atomic_set(&test_ch->card_detected_event, 1);
-			wake_up(&test_ch->wait_q);
-		}
-	}
-
-	return 0;
-}
-
-static int sdio_test_channel_probe(struct platform_device *pdev)
-{
-	if (!pdev)
-		return -EIO;
-	return test_channel_init((char *)pdev->name);
-}
-
-static int sdio_test_channel_remove(struct platform_device *pdev)
-{
-	int ch_id;
-
-	if (!pdev)
-		return -EIO;
-
-	ch_id = channel_name_to_id((char *)pdev->name);
-	if (test_ctx->test_ch_arr[ch_id] == NULL)
-		return 0;
-
-	pr_info(TEST_MODULE_NAME "%s: remove ch %s\n",
-		__func__, test_ctx->test_ch_arr[ch_id]->name);
-
-	if ((ch_id == SDIO_SMEM) && (test_ctx->smem_pdev)) {
-		platform_device_unregister(test_ctx->smem_pdev);
-		test_ctx->smem_pdev = NULL;
-	}
-
-	test_ctx->test_ch_arr[ch_id]->ch_ready = 0;
-	test_ctx->test_ch_arr[ch_id]->card_removed = 1;
-
-	return 0;
-
-}
-
-static int sdio_test_channel_csvt_probe(struct platform_device *pdev)
-{
-	int ret = 0;
-
-	if (!pdev)
-		return -ENODEV;
-
-	test_ctx->csvt_app_pdev = platform_device_alloc("SDIO_CSVT_TEST_APP",
-							-1);
-	ret = platform_device_add(test_ctx->csvt_app_pdev);
-		if (ret) {
-			pr_err(MODULE_NAME ":platform_device_add failed, "
-					   "ret=%d\n", ret);
-			return ret;
-		}
-
-	return sdio_test_channel_probe(pdev);
-}
-
-static int sdio_test_channel_csvt_remove(struct platform_device *pdev)
-{
-	if (!pdev)
-		return -ENODEV;
-
-	platform_device_unregister(test_ctx->csvt_app_pdev);
-
-	return sdio_test_channel_remove(pdev);
-}
-
-static struct platform_driver sdio_rpc_drv = {
-	.probe		= sdio_test_channel_probe,
-	.remove		= sdio_test_channel_remove,
-	.driver		= {
-		.name	= "SDIO_RPC_TEST",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static struct platform_driver sdio_qmi_drv = {
-	.probe		= sdio_test_channel_probe,
-	.remove		= sdio_test_channel_remove,
-	.driver		= {
-		.name	= "SDIO_QMI_TEST",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static struct platform_driver sdio_diag_drv = {
-	.probe		= sdio_test_channel_probe,
-	.remove		= sdio_test_channel_remove,
-	.driver		= {
-		.name	= "SDIO_DIAG_TEST",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static struct platform_driver sdio_smem_drv = {
-	.probe		= sdio_test_channel_probe,
-	.remove		= sdio_test_channel_remove,
-	.driver		= {
-		.name	= "SDIO_SMEM_TEST",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static struct platform_driver sdio_rmnt_drv = {
-	.probe		= sdio_test_channel_probe,
-	.remove		= sdio_test_channel_remove,
-	.driver		= {
-		.name	= "SDIO_RMNT_TEST",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static struct platform_driver sdio_dun_drv = {
-	.probe		= sdio_test_channel_probe,
-	.remove		= sdio_test_channel_remove,
-	.driver		= {
-		.name	= "SDIO_DUN_TEST",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static struct platform_driver sdio_csvt_drv = {
-	.probe		= sdio_test_channel_csvt_probe,
-	.remove		= sdio_test_channel_csvt_remove,
-	.driver		= {
-		.name	= "SDIO_CSVT_TEST",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static struct class *test_class;
-
-const struct file_operations test_fops = {
-	.owner = THIS_MODULE,
-	.write = test_write,
-};
-
-/**
- * Module Init.
- */
-static int __init test_init(void)
-{
-	int ret;
-
-	pr_debug(TEST_MODULE_NAME ":test_init.\n");
-
-	test_ctx = kzalloc(sizeof(struct test_context), GFP_KERNEL);
-
-	if (test_ctx == NULL) {
-		pr_err(TEST_MODULE_NAME ":kzalloc err.\n");
-		return -ENOMEM;
-	}
-	test_ctx->test_ch = NULL;
-	test_ctx->signature = TEST_SIGNATURE;
-
-	test_ctx->name = "UNKNOWN";
-
-	init_waitqueue_head(&test_ctx->wait_q);
-
-#ifdef CONFIG_DEBUG_FS
-	sdio_al_test_debugfs_init();
-#endif
-
-	test_class = class_create(THIS_MODULE, TEST_MODULE_NAME);
-
-	ret = alloc_chrdev_region(&test_ctx->dev_num, 0, 1, TEST_MODULE_NAME);
-	if (ret) {
-		pr_err(TEST_MODULE_NAME "alloc_chrdev_region err.\n");
-		return -ENODEV;
-	}
-
-	test_ctx->dev = device_create(test_class, NULL, test_ctx->dev_num,
-				      test_ctx, TEST_MODULE_NAME);
-	if (IS_ERR(test_ctx->dev)) {
-		pr_err(TEST_MODULE_NAME ":device_create err.\n");
-		return -ENODEV;
-	}
-
-	test_ctx->cdev = cdev_alloc();
-	if (test_ctx->cdev == NULL) {
-		pr_err(TEST_MODULE_NAME ":cdev_alloc err.\n");
-		return -ENODEV;
-	}
-	cdev_init(test_ctx->cdev, &test_fops);
-	test_ctx->cdev->owner = THIS_MODULE;
-
-	ret = cdev_add(test_ctx->cdev, test_ctx->dev_num, 1);
-	if (ret)
-		pr_err(TEST_MODULE_NAME ":cdev_add err=%d\n", -ret);
-	else
-		pr_debug(TEST_MODULE_NAME ":SDIO-AL-Test init OK..\n");
-
-	platform_driver_register(&sdio_rpc_drv);
-	platform_driver_register(&sdio_qmi_drv);
-	platform_driver_register(&sdio_diag_drv);
-	platform_driver_register(&sdio_smem_drv);
-	platform_driver_register(&sdio_rmnt_drv);
-	platform_driver_register(&sdio_dun_drv);
-	platform_driver_register(&sdio_csvt_drv);
-
-	return ret;
-}
-
-/**
- * Module Exit.
- */
-static void __exit test_exit(void)
-{
-	int i;
-
-	pr_debug(TEST_MODULE_NAME ":test_exit.\n");
-
-	test_ctx->exit_flag = true;
-
-	msleep(100); /* allow gracefully exit of the worker thread */
-
-	cdev_del(test_ctx->cdev);
-	device_destroy(test_class, test_ctx->dev_num);
-	unregister_chrdev_region(test_ctx->dev_num, 1);
-
-	platform_driver_unregister(&sdio_rpc_drv);
-	platform_driver_unregister(&sdio_qmi_drv);
-	platform_driver_unregister(&sdio_diag_drv);
-	platform_driver_unregister(&sdio_smem_drv);
-	platform_driver_unregister(&sdio_rmnt_drv);
-	platform_driver_unregister(&sdio_dun_drv);
-	platform_driver_unregister(&sdio_csvt_drv);
-
-	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
-		struct test_channel *tch = test_ctx->test_ch_arr[i];
-		if (!tch)
-			continue;
-		kfree(tch->buf);
-		kfree(tch);
-	}
-
-#ifdef CONFIG_DEBUG_FS
-	sdio_al_test_debugfs_cleanup();
-#endif
-
-	kfree(test_ctx);
-
-	pr_debug(TEST_MODULE_NAME ":test_exit complete.\n");
-}
-
-module_init(test_init);
-module_exit(test_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("SDIO_AL Test");
-MODULE_AUTHOR("Amir Samuelov <amirs@codeaurora.org>");
-
-
diff --git a/arch/arm/mach-msm/sdio_cmux.c b/arch/arm/mach-msm/sdio_cmux.c
deleted file mode 100644
index 48ca6b7..0000000
--- a/arch/arm/mach-msm/sdio_cmux.c
+++ /dev/null
@@ -1,901 +0,0 @@
-/* Copyright (c) 2010-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.
- */
-
-#define DEBUG
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
-#include <linux/uaccess.h>
-#include <linux/workqueue.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/termios.h>
-#include <linux/debugfs.h>
-#include <linux/moduleparam.h>
-
-#include <mach/sdio_al.h>
-#include <mach/sdio_cmux.h>
-
-#include "modem_notifier.h"
-
-#define MAX_WRITE_RETRY 5
-#define MAGIC_NO_V1 0x33FC
-
-static int msm_sdio_cmux_debug_mask;
-module_param_named(debug_mask, msm_sdio_cmux_debug_mask,
-		   int, S_IRUGO | S_IWUSR | S_IWGRP);
-
-enum cmd_type {
-	DATA = 0,
-	OPEN,
-	CLOSE,
-	STATUS,
-	NUM_CMDS
-};
-
-#define DSR_POS 0x1
-#define CTS_POS 0x2
-#define RI_POS 0x4
-#define CD_POS 0x8
-
-struct sdio_cmux_ch {
-	int lc_id;
-
-	struct mutex lc_lock;
-	wait_queue_head_t open_wait_queue;
-	int is_remote_open;
-	int is_local_open;
-	int is_channel_reset;
-
-	char local_status;
-	char remote_status;
-
-	struct mutex tx_lock;
-	struct list_head tx_list;
-
-	void *priv;
-	struct mutex rx_cb_lock;
-	void (*receive_cb)(void *, int, void *);
-	void (*write_done)(void *, int, void *);
-	void (*status_callback)(int, void *);
-} logical_ch[SDIO_CMUX_NUM_CHANNELS];
-
-struct sdio_cmux_hdr {
-	uint16_t magic_no;
-	uint8_t status;         /* This field is reserved for commands other
-				 * than STATUS */
-	uint8_t cmd;
-	uint8_t pad_bytes;
-	uint8_t lc_id;
-	uint16_t pkt_len;
-};
-
-struct sdio_cmux_pkt {
-	struct sdio_cmux_hdr *hdr;
-	void *data;
-};
-
-struct sdio_cmux_list_elem {
-	struct list_head list;
-	struct sdio_cmux_pkt cmux_pkt;
-};
-
-#define logical_ch_is_local_open(x)                        \
-	(logical_ch[(x)].is_local_open)
-
-#define logical_ch_is_remote_open(x)                       \
-	(logical_ch[(x)].is_remote_open)
-
-static void sdio_cdemux_fn(struct work_struct *work);
-static DECLARE_WORK(sdio_cdemux_work, sdio_cdemux_fn);
-static struct workqueue_struct *sdio_cdemux_wq;
-
-static DEFINE_MUTEX(write_lock);
-static uint32_t bytes_to_write;
-static DEFINE_MUTEX(temp_rx_lock);
-static LIST_HEAD(temp_rx_list);
-
-static void sdio_cmux_fn(struct work_struct *work);
-static DECLARE_WORK(sdio_cmux_work, sdio_cmux_fn);
-static struct workqueue_struct *sdio_cmux_wq;
-
-static struct sdio_channel *sdio_qmi_chl;
-static uint32_t sdio_cmux_inited;
-
-static uint32_t abort_tx;
-static DEFINE_MUTEX(modem_reset_lock);
-
-static DEFINE_MUTEX(probe_lock);
-
-enum {
-	MSM_SDIO_CMUX_DEBUG = 1U << 0,
-	MSM_SDIO_CMUX_DUMP_BUFFER = 1U << 1,
-};
-
-static struct platform_device sdio_ctl_dev = {
-	.name		= "SDIO_CTL",
-	.id		= -1,
-};
-
-#if defined(DEBUG)
-#define D_DUMP_BUFFER(prestr, cnt, buf) \
-do { \
-	if (msm_sdio_cmux_debug_mask & MSM_SDIO_CMUX_DUMP_BUFFER) { \
-		int i; \
-		pr_debug("%s", prestr); \
-		for (i = 0; i < cnt; i++) \
-			pr_info("%.2x", buf[i]); \
-		pr_debug("\n"); \
-	} \
-} while (0)
-
-#define D(x...) \
-do { \
-	if (msm_sdio_cmux_debug_mask & MSM_SDIO_CMUX_DEBUG) \
-		pr_debug(x); \
-} while (0)
-
-#else
-#define D_DUMP_BUFFER(prestr, cnt, buf) do {} while (0)
-#define D(x...) do {} while (0)
-#endif
-
-static int sdio_cmux_ch_alloc(int id)
-{
-	if (id < 0 || id >= SDIO_CMUX_NUM_CHANNELS) {
-		pr_err("%s: Invalid lc_id - %d\n", __func__, id);
-		return -EINVAL;
-	}
-
-	logical_ch[id].lc_id = id;
-	mutex_init(&logical_ch[id].lc_lock);
-	init_waitqueue_head(&logical_ch[id].open_wait_queue);
-	logical_ch[id].is_remote_open = 0;
-	logical_ch[id].is_local_open = 0;
-	logical_ch[id].is_channel_reset = 0;
-
-	INIT_LIST_HEAD(&logical_ch[id].tx_list);
-	mutex_init(&logical_ch[id].tx_lock);
-
-	logical_ch[id].priv = NULL;
-	mutex_init(&logical_ch[id].rx_cb_lock);
-	logical_ch[id].receive_cb = NULL;
-	logical_ch[id].write_done = NULL;
-	return 0;
-}
-
-static int sdio_cmux_ch_clear_and_signal(int id)
-{
-	struct sdio_cmux_list_elem *list_elem;
-
-	if (id < 0 || id >= SDIO_CMUX_NUM_CHANNELS) {
-		pr_err("%s: Invalid lc_id - %d\n", __func__, id);
-		return -EINVAL;
-	}
-
-	mutex_lock(&logical_ch[id].lc_lock);
-	logical_ch[id].is_remote_open = 0;
-	mutex_lock(&logical_ch[id].tx_lock);
-	while (!list_empty(&logical_ch[id].tx_list)) {
-		list_elem = list_first_entry(&logical_ch[id].tx_list,
-					     struct sdio_cmux_list_elem,
-					     list);
-		list_del(&list_elem->list);
-		kfree(list_elem->cmux_pkt.hdr);
-		kfree(list_elem);
-	}
-	mutex_unlock(&logical_ch[id].tx_lock);
-	mutex_lock(&logical_ch[id].rx_cb_lock);
-	if (logical_ch[id].receive_cb)
-		logical_ch[id].receive_cb(NULL, 0, logical_ch[id].priv);
-	mutex_unlock(&logical_ch[id].rx_cb_lock);
-	if (logical_ch[id].write_done)
-		logical_ch[id].write_done(NULL, 0, logical_ch[id].priv);
-	mutex_unlock(&logical_ch[id].lc_lock);
-	wake_up(&logical_ch[id].open_wait_queue);
-	return 0;
-}
-
-static int sdio_cmux_write_cmd(const int id, enum cmd_type type)
-{
-	int write_size = 0;
-	void *write_data = NULL;
-	struct sdio_cmux_list_elem *list_elem;
-
-	if (id < 0 || id >= SDIO_CMUX_NUM_CHANNELS) {
-		pr_err("%s: Invalid lc_id - %d\n", __func__, id);
-		return -EINVAL;
-	}
-
-	if (type < 0 || type > NUM_CMDS) {
-		pr_err("%s: Invalid cmd - %d\n", __func__, type);
-		return -EINVAL;
-	}
-
-	write_size = sizeof(struct sdio_cmux_hdr);
-	list_elem = kmalloc(sizeof(struct sdio_cmux_list_elem), GFP_KERNEL);
-	if (!list_elem) {
-		pr_err("%s: list_elem alloc failed\n", __func__);
-		return -ENOMEM;
-	}
-
-	write_data = kmalloc(write_size, GFP_KERNEL);
-	if (!write_data) {
-		pr_err("%s: write_data alloc failed\n", __func__);
-		kfree(list_elem);
-		return -ENOMEM;
-	}
-
-	list_elem->cmux_pkt.hdr = (struct sdio_cmux_hdr *)write_data;
-	list_elem->cmux_pkt.data = NULL;
-
-	list_elem->cmux_pkt.hdr->lc_id = (uint8_t)id;
-	list_elem->cmux_pkt.hdr->pkt_len = (uint16_t)0;
-	list_elem->cmux_pkt.hdr->cmd = (uint8_t)type;
-	list_elem->cmux_pkt.hdr->status = (uint8_t)0;
-	if (type == STATUS)
-		list_elem->cmux_pkt.hdr->status = logical_ch[id].local_status;
-	list_elem->cmux_pkt.hdr->pad_bytes = (uint8_t)0;
-	list_elem->cmux_pkt.hdr->magic_no = (uint16_t)MAGIC_NO_V1;
-
-	mutex_lock(&logical_ch[id].tx_lock);
-	list_add_tail(&list_elem->list, &logical_ch[id].tx_list);
-	mutex_unlock(&logical_ch[id].tx_lock);
-
-	mutex_lock(&write_lock);
-	bytes_to_write += write_size;
-	mutex_unlock(&write_lock);
-	queue_work(sdio_cmux_wq, &sdio_cmux_work);
-
-	return 0;
-}
-
-int sdio_cmux_open(const int id,
-		   void (*receive_cb)(void *, int, void *),
-		   void (*write_done)(void *, int, void *),
-		   void (*status_callback)(int, void *),
-		   void *priv)
-{
-	int r;
-	struct sdio_cmux_list_elem *list_elem, *list_elem_tmp;
-
-	if (!sdio_cmux_inited)
-		return -ENODEV;
-	if (id < 0 || id >= SDIO_CMUX_NUM_CHANNELS) {
-		pr_err("%s: Invalid id - %d\n", __func__, id);
-		return -EINVAL;
-	}
-
-	r = wait_event_timeout(logical_ch[id].open_wait_queue,
-				logical_ch[id].is_remote_open, (1 * HZ));
-	if (r < 0) {
-		pr_err("ERROR %s: wait_event_timeout() failed for"
-		       " ch%d with rc %d\n", __func__, id, r);
-		return r;
-	}
-	if (r == 0) {
-		pr_err("ERROR %s: Wait Timed Out for ch%d\n", __func__, id);
-		return -ETIMEDOUT;
-	}
-
-	mutex_lock(&logical_ch[id].lc_lock);
-	if (!logical_ch[id].is_remote_open) {
-		pr_err("%s: Remote ch%d not opened\n", __func__, id);
-		mutex_unlock(&logical_ch[id].lc_lock);
-		return -EINVAL;
-	}
-	if (logical_ch[id].is_local_open) {
-		mutex_unlock(&logical_ch[id].lc_lock);
-		return 0;
-	}
-	logical_ch[id].is_local_open = 1;
-	logical_ch[id].priv = priv;
-	logical_ch[id].write_done = write_done;
-	logical_ch[id].status_callback = status_callback;
-	mutex_lock(&logical_ch[id].rx_cb_lock);
-	logical_ch[id].receive_cb = receive_cb;
-	if (logical_ch[id].receive_cb) {
-		mutex_lock(&temp_rx_lock);
-		list_for_each_entry_safe(list_elem, list_elem_tmp,
-					 &temp_rx_list, list) {
-			if ((int)list_elem->cmux_pkt.hdr->lc_id == id) {
-				logical_ch[id].receive_cb(
-					list_elem->cmux_pkt.data,
-					(int)list_elem->cmux_pkt.hdr->pkt_len,
-					logical_ch[id].priv);
-				list_del(&list_elem->list);
-				kfree(list_elem->cmux_pkt.hdr);
-				kfree(list_elem);
-			}
-		}
-		mutex_unlock(&temp_rx_lock);
-	}
-	mutex_unlock(&logical_ch[id].rx_cb_lock);
-	mutex_unlock(&logical_ch[id].lc_lock);
-	sdio_cmux_write_cmd(id, OPEN);
-	return 0;
-}
-EXPORT_SYMBOL(sdio_cmux_open);
-
-int sdio_cmux_close(int id)
-{
-	struct sdio_cmux_ch *ch;
-
-	if (!sdio_cmux_inited)
-		return -ENODEV;
-	if (id < 0 || id >= SDIO_CMUX_NUM_CHANNELS) {
-		pr_err("%s: Invalid channel close\n", __func__);
-		return -EINVAL;
-	}
-
-	ch = &logical_ch[id];
-	mutex_lock(&ch->lc_lock);
-	mutex_lock(&logical_ch[id].rx_cb_lock);
-	ch->receive_cb = NULL;
-	mutex_unlock(&logical_ch[id].rx_cb_lock);
-	mutex_lock(&ch->tx_lock);
-	ch->write_done = NULL;
-	mutex_unlock(&ch->tx_lock);
-	ch->is_local_open = 0;
-	ch->priv = NULL;
-	mutex_unlock(&ch->lc_lock);
-	sdio_cmux_write_cmd(ch->lc_id, CLOSE);
-	return 0;
-}
-EXPORT_SYMBOL(sdio_cmux_close);
-
-int sdio_cmux_write_avail(int id)
-{
-	int write_avail;
-
-	mutex_lock(&logical_ch[id].lc_lock);
-	if (logical_ch[id].is_channel_reset) {
-		mutex_unlock(&logical_ch[id].lc_lock);
-		return -ENETRESET;
-	}
-	mutex_unlock(&logical_ch[id].lc_lock);
-	write_avail = sdio_write_avail(sdio_qmi_chl);
-	return write_avail - bytes_to_write;
-}
-EXPORT_SYMBOL(sdio_cmux_write_avail);
-
-int sdio_cmux_write(int id, void *data, int len)
-{
-	struct sdio_cmux_list_elem *list_elem;
-	uint32_t write_size;
-	void *write_data = NULL;
-	struct sdio_cmux_ch *ch;
-	int ret;
-
-	if (!sdio_cmux_inited)
-		return -ENODEV;
-	if (id < 0 || id >= SDIO_CMUX_NUM_CHANNELS) {
-		pr_err("%s: Invalid channel id %d\n", __func__, id);
-		return -ENODEV;
-	}
-
-	ch = &logical_ch[id];
-	if (len <= 0) {
-		pr_err("%s: Invalid len %d bytes to write\n",
-			__func__, len);
-		return -EINVAL;
-	}
-
-	write_size = sizeof(struct sdio_cmux_hdr) + len;
-	list_elem = kmalloc(sizeof(struct sdio_cmux_list_elem), GFP_KERNEL);
-	if (!list_elem) {
-		pr_err("%s: list_elem alloc failed\n", __func__);
-		return -ENOMEM;
-	}
-
-	write_data = kmalloc(write_size, GFP_KERNEL);
-	if (!write_data) {
-		pr_err("%s: write_data alloc failed\n", __func__);
-		kfree(list_elem);
-		return -ENOMEM;
-	}
-
-	list_elem->cmux_pkt.hdr = (struct sdio_cmux_hdr *)write_data;
-	list_elem->cmux_pkt.data = (void *)((char *)write_data +
-						sizeof(struct sdio_cmux_hdr));
-	memcpy(list_elem->cmux_pkt.data, data, len);
-
-	list_elem->cmux_pkt.hdr->lc_id = (uint8_t)ch->lc_id;
-	list_elem->cmux_pkt.hdr->pkt_len = (uint16_t)len;
-	list_elem->cmux_pkt.hdr->cmd = (uint8_t)DATA;
-	list_elem->cmux_pkt.hdr->status = (uint8_t)0;
-	list_elem->cmux_pkt.hdr->pad_bytes = (uint8_t)0;
-	list_elem->cmux_pkt.hdr->magic_no = (uint16_t)MAGIC_NO_V1;
-
-	mutex_lock(&ch->lc_lock);
-	if (!ch->is_remote_open || !ch->is_local_open) {
-		pr_err("%s: Local ch%d sending data before sending/receiving"
-		       " OPEN command\n", __func__, ch->lc_id);
-		if (ch->is_channel_reset)
-			ret = -ENETRESET;
-		else
-			ret = -ENODEV;
-		mutex_unlock(&ch->lc_lock);
-		kfree(write_data);
-		kfree(list_elem);
-		return ret;
-	}
-	mutex_lock(&ch->tx_lock);
-	list_add_tail(&list_elem->list, &ch->tx_list);
-	mutex_unlock(&ch->tx_lock);
-	mutex_unlock(&ch->lc_lock);
-
-	mutex_lock(&write_lock);
-	bytes_to_write += write_size;
-	mutex_unlock(&write_lock);
-	queue_work(sdio_cmux_wq, &sdio_cmux_work);
-
-	return len;
-}
-EXPORT_SYMBOL(sdio_cmux_write);
-
-int is_remote_open(int id)
-{
-	if (id < 0 || id >= SDIO_CMUX_NUM_CHANNELS)
-		return -ENODEV;
-
-	return logical_ch_is_remote_open(id);
-}
-EXPORT_SYMBOL(is_remote_open);
-
-int sdio_cmux_is_channel_reset(int id)
-{
-	int ret;
-	if (id < 0 || id >= SDIO_CMUX_NUM_CHANNELS)
-		return -ENODEV;
-
-	mutex_lock(&logical_ch[id].lc_lock);
-	ret = logical_ch[id].is_channel_reset;
-	mutex_unlock(&logical_ch[id].lc_lock);
-	return ret;
-}
-EXPORT_SYMBOL(sdio_cmux_is_channel_reset);
-
-int sdio_cmux_tiocmget(int id)
-{
-	int ret =  (logical_ch[id].remote_status & DSR_POS ? TIOCM_DSR : 0) |
-		(logical_ch[id].remote_status & CTS_POS ? TIOCM_CTS : 0) |
-		(logical_ch[id].remote_status & CD_POS ? TIOCM_CD : 0) |
-		(logical_ch[id].remote_status & RI_POS ? TIOCM_RI : 0) |
-		(logical_ch[id].local_status & CTS_POS ? TIOCM_RTS : 0) |
-		(logical_ch[id].local_status & DSR_POS ? TIOCM_DTR : 0);
-	return ret;
-}
-EXPORT_SYMBOL(sdio_cmux_tiocmget);
-
-int sdio_cmux_tiocmset(int id, unsigned int set, unsigned int clear)
-{
-	if (set & TIOCM_DTR)
-		logical_ch[id].local_status |= DSR_POS;
-
-	if (set & TIOCM_RTS)
-		logical_ch[id].local_status |= CTS_POS;
-
-	if (clear & TIOCM_DTR)
-		logical_ch[id].local_status &= ~DSR_POS;
-
-	if (clear & TIOCM_RTS)
-		logical_ch[id].local_status &= ~CTS_POS;
-
-	sdio_cmux_write_cmd(id, STATUS);
-	return 0;
-}
-EXPORT_SYMBOL(sdio_cmux_tiocmset);
-
-static int copy_packet(void *pkt, int size)
-{
-	struct sdio_cmux_list_elem *list_elem = NULL;
-	void *temp_pkt = NULL;
-
-	list_elem = kmalloc(sizeof(struct sdio_cmux_list_elem), GFP_KERNEL);
-	if (!list_elem) {
-		pr_err("%s: list_elem alloc failed\n", __func__);
-		return -ENOMEM;
-	}
-	temp_pkt = kmalloc(size, GFP_KERNEL);
-	if (!temp_pkt) {
-		pr_err("%s: temp_pkt alloc failed\n", __func__);
-		kfree(list_elem);
-		return -ENOMEM;
-	}
-
-	memcpy(temp_pkt, pkt, size);
-	list_elem->cmux_pkt.hdr = temp_pkt;
-	list_elem->cmux_pkt.data = (void *)((char *)temp_pkt +
-					    sizeof(struct sdio_cmux_hdr));
-	mutex_lock(&temp_rx_lock);
-	list_add_tail(&list_elem->list, &temp_rx_list);
-	mutex_unlock(&temp_rx_lock);
-	return 0;
-}
-
-static int process_cmux_pkt(void *pkt, int size)
-{
-	struct sdio_cmux_hdr *mux_hdr;
-	uint32_t id, data_size;
-	void *data;
-	char *dump_buf = (char *)pkt;
-
-	D_DUMP_BUFFER("process_cmux_pkt:", size, dump_buf);
-	mux_hdr = (struct sdio_cmux_hdr *)pkt;
-	switch (mux_hdr->cmd) {
-	case OPEN:
-		id = (uint32_t)(mux_hdr->lc_id);
-		D("%s: Received OPEN command for ch%d\n", __func__, id);
-		mutex_lock(&logical_ch[id].lc_lock);
-		logical_ch[id].is_remote_open = 1;
-		if (logical_ch[id].is_channel_reset) {
-			sdio_cmux_write_cmd(id, OPEN);
-			logical_ch[id].is_channel_reset = 0;
-		}
-		mutex_unlock(&logical_ch[id].lc_lock);
-		wake_up(&logical_ch[id].open_wait_queue);
-		break;
-
-	case CLOSE:
-		id = (uint32_t)(mux_hdr->lc_id);
-		D("%s: Received CLOSE command for ch%d\n", __func__, id);
-		sdio_cmux_ch_clear_and_signal(id);
-		break;
-
-	case DATA:
-		id = (uint32_t)(mux_hdr->lc_id);
-		D("%s: Received DATA for ch%d\n", __func__, id);
-		/*Channel is not locally open & if single packet received
-		  then drop it*/
-		mutex_lock(&logical_ch[id].lc_lock);
-		if (!logical_ch[id].is_remote_open) {
-			mutex_unlock(&logical_ch[id].lc_lock);
-			pr_err("%s: Remote Ch%d sent data before sending/"
-			       "receiving OPEN command\n", __func__, id);
-			return -ENODEV;
-		}
-
-		data = (void *)((char *)pkt + sizeof(struct sdio_cmux_hdr));
-		data_size = (int)(((struct sdio_cmux_hdr *)pkt)->pkt_len);
-		mutex_unlock(&logical_ch[id].lc_lock);
-		/*
-		 * The lc_lock is released before the call to receive_cb
-		 * to avoid a dead lock where in the receive_cb would call a
-		 * function that tries to acquire a rx_lock which is already
-		 * acquired by a Thread that is waiting on lc_lock.
-		 */
-		mutex_lock(&logical_ch[id].rx_cb_lock);
-		if (logical_ch[id].receive_cb)
-			logical_ch[id].receive_cb(data, data_size,
-						logical_ch[id].priv);
-		else
-			copy_packet(pkt, size);
-		mutex_unlock(&logical_ch[id].rx_cb_lock);
-		break;
-
-	case STATUS:
-		id = (uint32_t)(mux_hdr->lc_id);
-		D("%s: Received STATUS command for ch%d\n", __func__, id);
-		if (logical_ch[id].remote_status != mux_hdr->status) {
-			mutex_lock(&logical_ch[id].lc_lock);
-			logical_ch[id].remote_status = mux_hdr->status;
-			mutex_unlock(&logical_ch[id].lc_lock);
-			if (logical_ch[id].status_callback)
-				logical_ch[id].status_callback(
-							sdio_cmux_tiocmget(id),
-							logical_ch[id].priv);
-		}
-		break;
-	}
-	return 0;
-}
-
-static void parse_cmux_data(void *data, int size)
-{
-	int data_parsed = 0, pkt_size;
-	char *temp_ptr;
-
-	D("Entered %s\n", __func__);
-	temp_ptr = (char *)data;
-	while (data_parsed < size) {
-		pkt_size = sizeof(struct sdio_cmux_hdr) +
-			   (int)(((struct sdio_cmux_hdr *)temp_ptr)->pkt_len);
-		D("Parsed %d bytes, Current Pkt Size %d bytes,"
-		  " Total size %d bytes\n", data_parsed, pkt_size, size);
-		process_cmux_pkt((void *)temp_ptr, pkt_size);
-		data_parsed += pkt_size;
-		temp_ptr += pkt_size;
-	}
-
-	kfree(data);
-}
-
-static void sdio_cdemux_fn(struct work_struct *work)
-{
-	int r = 0, read_avail = 0;
-	void *cmux_data;
-
-	while (1) {
-		read_avail = sdio_read_avail(sdio_qmi_chl);
-		if (read_avail < 0) {
-			pr_err("%s: sdio_read_avail failed with rc %d\n",
-				__func__, read_avail);
-			return;
-		}
-
-		if (read_avail == 0) {
-			D("%s: Nothing to read\n", __func__);
-			return;
-		}
-
-		D("%s: kmalloc %d bytes\n", __func__, read_avail);
-		cmux_data = kmalloc(read_avail, GFP_KERNEL);
-		if (!cmux_data) {
-			pr_err("%s: kmalloc Failed\n", __func__);
-			return;
-		}
-
-		D("%s: sdio_read %d bytes\n", __func__, read_avail);
-		r = sdio_read(sdio_qmi_chl, cmux_data, read_avail);
-		if (r < 0) {
-			pr_err("%s: sdio_read failed with rc %d\n",
-				__func__, r);
-			kfree(cmux_data);
-			return;
-		}
-
-		parse_cmux_data(cmux_data, read_avail);
-	}
-	return;
-}
-
-static void sdio_cmux_fn(struct work_struct *work)
-{
-	int i, r = 0;
-	void *write_data;
-	uint32_t write_size, write_avail, write_retry = 0;
-	int bytes_written;
-	struct sdio_cmux_list_elem *list_elem = NULL;
-	struct sdio_cmux_ch *ch;
-
-	for (i = 0; i < SDIO_CMUX_NUM_CHANNELS; ++i) {
-		ch = &logical_ch[i];
-		bytes_written = 0;
-		mutex_lock(&ch->tx_lock);
-		while (!list_empty(&ch->tx_list)) {
-			list_elem = list_first_entry(&ch->tx_list,
-					     struct sdio_cmux_list_elem,
-					     list);
-			list_del(&list_elem->list);
-			mutex_unlock(&ch->tx_lock);
-
-			write_data = (void *)list_elem->cmux_pkt.hdr;
-			write_size = sizeof(struct sdio_cmux_hdr) +
-				(uint32_t)list_elem->cmux_pkt.hdr->pkt_len;
-
-			mutex_lock(&modem_reset_lock);
-			while (!(abort_tx) &&
-				((write_avail = sdio_write_avail(sdio_qmi_chl))
-						< write_size)) {
-				mutex_unlock(&modem_reset_lock);
-				pr_err("%s: sdio_write_avail %d bytes, "
-				       "write size %d bytes. Waiting...\n",
-					__func__, write_avail, write_size);
-				msleep(250);
-				mutex_lock(&modem_reset_lock);
-			}
-			while (!(abort_tx) &&
-				((r = sdio_write(sdio_qmi_chl,
-						write_data, write_size)) < 0)
-				&& (r != -ENODEV)
-				&& (write_retry++ < MAX_WRITE_RETRY)) {
-				mutex_unlock(&modem_reset_lock);
-				pr_err("%s: sdio_write failed with rc %d."
-				       "Retrying...", __func__, r);
-				msleep(250);
-				mutex_lock(&modem_reset_lock);
-			}
-			if (!r && !abort_tx) {
-				D("%s: sdio_write_completed %dbytes\n",
-				  __func__, write_size);
-				bytes_written += write_size;
-			} else if (r == -ENODEV) {
-				pr_err("%s: aborting_tx because sdio_write"
-				       " returned %d\n", __func__, r);
-				r = 0;
-				abort_tx = 1;
-			}
-			mutex_unlock(&modem_reset_lock);
-			kfree(list_elem->cmux_pkt.hdr);
-			kfree(list_elem);
-			mutex_lock(&write_lock);
-			bytes_to_write -= write_size;
-			mutex_unlock(&write_lock);
-			mutex_lock(&ch->tx_lock);
-		}
-		if (ch->write_done)
-			ch->write_done(NULL, bytes_written, ch->priv);
-		mutex_unlock(&ch->tx_lock);
-	}
-	return;
-}
-
-static void sdio_qmi_chl_notify(void *priv, unsigned event)
-{
-	if (event == SDIO_EVENT_DATA_READ_AVAIL) {
-		D("%s: Received SDIO_EVENT_DATA_READ_AVAIL\n", __func__);
-		queue_work(sdio_cdemux_wq, &sdio_cdemux_work);
-	}
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-static int debug_tbl(char *buf, int max)
-{
-	int i = 0;
-	int j;
-
-	for (j = 0; j < SDIO_CMUX_NUM_CHANNELS; ++j) {
-		i += scnprintf(buf + i, max - i,
-			"ch%02d  local open=%s  remote open=%s\n",
-			j, logical_ch_is_local_open(j) ? "Y" : "N",
-			logical_ch_is_remote_open(j) ? "Y" : "N");
-	}
-
-	return i;
-}
-
-#define DEBUG_BUFMAX 4096
-static char debug_buffer[DEBUG_BUFMAX];
-
-static ssize_t debug_read(struct file *file, char __user *buf,
-				size_t count, loff_t *ppos)
-{
-	int (*fill)(char *buf, int max) = file->private_data;
-	int bsize = fill(debug_buffer, DEBUG_BUFMAX);
-	return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize);
-}
-
-static int debug_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return 0;
-}
-
-
-static const struct file_operations debug_ops = {
-	.read = debug_read,
-	.open = debug_open,
-};
-
-static void debug_create(const char *name, mode_t mode,
-				struct dentry *dent,
-				int (*fill)(char *buf, int max))
-{
-	debugfs_create_file(name, mode, dent, fill, &debug_ops);
-}
-
-#endif
-
-static int sdio_cmux_probe(struct platform_device *pdev)
-{
-	int i, r;
-
-	mutex_lock(&probe_lock);
-	D("%s Begins\n", __func__);
-	if (sdio_cmux_inited) {
-		mutex_lock(&modem_reset_lock);
-		r =  sdio_open("SDIO_QMI", &sdio_qmi_chl, NULL,
-				sdio_qmi_chl_notify);
-		if (r < 0) {
-			mutex_unlock(&modem_reset_lock);
-			pr_err("%s: sdio_open() failed\n", __func__);
-			goto error0;
-		}
-		abort_tx = 0;
-		mutex_unlock(&modem_reset_lock);
-		mutex_unlock(&probe_lock);
-		return 0;
-	}
-
-	for (i = 0; i < SDIO_CMUX_NUM_CHANNELS; ++i)
-		sdio_cmux_ch_alloc(i);
-	INIT_LIST_HEAD(&temp_rx_list);
-
-	sdio_cmux_wq = create_singlethread_workqueue("sdio_cmux");
-	if (IS_ERR(sdio_cmux_wq)) {
-		pr_err("%s: create_singlethread_workqueue() ENOMEM\n",
-			__func__);
-		r = -ENOMEM;
-		goto error0;
-	}
-
-	sdio_cdemux_wq = create_singlethread_workqueue("sdio_cdemux");
-	if (IS_ERR(sdio_cdemux_wq)) {
-		pr_err("%s: create_singlethread_workqueue() ENOMEM\n",
-			__func__);
-		r = -ENOMEM;
-		goto error1;
-	}
-
-	r = sdio_open("SDIO_QMI", &sdio_qmi_chl, NULL, sdio_qmi_chl_notify);
-	if (r < 0) {
-		pr_err("%s: sdio_open() failed\n", __func__);
-		goto error2;
-	}
-
-	platform_device_register(&sdio_ctl_dev);
-	sdio_cmux_inited = 1;
-	D("SDIO Control MUX Driver Initialized.\n");
-	mutex_unlock(&probe_lock);
-	return 0;
-
-error2:
-	destroy_workqueue(sdio_cdemux_wq);
-error1:
-	destroy_workqueue(sdio_cmux_wq);
-error0:
-	mutex_unlock(&probe_lock);
-	return r;
-}
-
-static int sdio_cmux_remove(struct platform_device *pdev)
-{
-	int i;
-
-	mutex_lock(&modem_reset_lock);
-	abort_tx = 1;
-
-	for (i = 0; i < SDIO_CMUX_NUM_CHANNELS; ++i) {
-		mutex_lock(&logical_ch[i].lc_lock);
-		logical_ch[i].is_channel_reset = 1;
-		mutex_unlock(&logical_ch[i].lc_lock);
-		sdio_cmux_ch_clear_and_signal(i);
-	}
-	sdio_qmi_chl = NULL;
-	mutex_unlock(&modem_reset_lock);
-
-	return 0;
-}
-
-static struct platform_driver sdio_cmux_driver = {
-	.probe          = sdio_cmux_probe,
-	.remove         = sdio_cmux_remove,
-	.driver         = {
-			.name   = "SDIO_QMI",
-			.owner  = THIS_MODULE,
-	},
-};
-
-static int __init sdio_cmux_init(void)
-{
-#ifdef CONFIG_DEBUG_FS
-	struct dentry *dent;
-
-	dent = debugfs_create_dir("sdio_cmux", 0);
-	if (!IS_ERR(dent))
-		debug_create("tbl", 0444, dent, debug_tbl);
-#endif
-
-	msm_sdio_cmux_debug_mask = 0;
-	return platform_driver_register(&sdio_cmux_driver);
-}
-
-module_init(sdio_cmux_init);
-MODULE_DESCRIPTION("MSM SDIO Control MUX");
-MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/sdio_ctl.c b/arch/arm/mach-msm/sdio_ctl.c
deleted file mode 100644
index cacdce9..0000000
--- a/arch/arm/mach-msm/sdio_ctl.c
+++ /dev/null
@@ -1,575 +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.
- */
-
-/*
- * SDIO Control Driver -- Provides a binary SDIO muxed control port
- *                       interface.
- */
-
-#include <linux/cdev.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
-#include <linux/uaccess.h>
-#include <linux/workqueue.h>
-#include <linux/poll.h>
-#include <asm/ioctls.h>
-#include <linux/platform_device.h>
-#include <mach/msm_smd.h>
-#include <mach/sdio_al.h>
-#include <mach/sdio_cmux.h>
-#include "modem_notifier.h"
-#include <linux/slab.h>
-
-#define MAX_WRITE_RETRY 5
-#define MAGIC_NO_V1 0x33FC
-#define NUM_SDIO_CTL_PORTS 10
-#define DEVICE_NAME "sdioctl"
-#define MAX_BUF_SIZE 2048
-#define DEBUG
-
-static int msm_sdio_ctl_debug_mask;
-module_param_named(debug_mask, msm_sdio_ctl_debug_mask,
-		   int, S_IRUGO | S_IWUSR | S_IWGRP);
-
-struct sdio_ctl_dev {
-	int id;
-	char name[9];
-	struct cdev cdev;
-	struct device *devicep;
-	struct mutex dev_lock;
-	int ref_count;
-
-	struct mutex rx_lock;
-	uint32_t read_avail;
-	struct list_head rx_list;
-
-	wait_queue_head_t read_wait_queue;
-	wait_queue_head_t write_wait_queue;
-} *sdio_ctl_devp[NUM_SDIO_CTL_PORTS];
-
-struct sdio_ctl_pkt {
-	int data_size;
-	void *data;
-};
-
-struct sdio_ctl_list_elem {
-	struct list_head list;
-	struct sdio_ctl_pkt ctl_pkt;
-};
-
-struct class *sdio_ctl_classp;
-static dev_t sdio_ctl_number;
-static uint32_t sdio_ctl_inited;
-
-enum {
-	MSM_SDIO_CTL_DEBUG = 1U << 0,
-	MSM_SDIO_CTL_DUMP_BUFFER = 1U << 1,
-};
-
-#if defined(DEBUG)
-#define D_DUMP_BUFFER(prestr, cnt, buf) \
-do { \
-	if (msm_sdio_ctl_debug_mask & MSM_SDIO_CTL_DUMP_BUFFER) { \
-		int i; \
-		pr_info("%s", prestr); \
-		for (i = 0; i < cnt; i++) \
-			pr_info("%.2x", buf[i]); \
-		pr_info("\n"); \
-	} \
-} while (0)
-
-#define D(x...) \
-do { \
-	if (msm_sdio_ctl_debug_mask & MSM_SDIO_CTL_DEBUG) \
-		pr_info(x); \
-} while (0)
-
-#else
-#define D_DUMP_BUFFER(prestr, cnt, buf) do {} while (0)
-#define D(x...) do {} while (0)
-#endif
-
-static uint32_t cmux_ch_id[] = {
-	SDIO_CMUX_DATA_CTL_0,
-	SDIO_CMUX_DATA_CTL_1,
-	SDIO_CMUX_DATA_CTL_2,
-	SDIO_CMUX_DATA_CTL_3,
-	SDIO_CMUX_DATA_CTL_4,
-	SDIO_CMUX_DATA_CTL_5,
-	SDIO_CMUX_DATA_CTL_6,
-	SDIO_CMUX_DATA_CTL_7,
-	SDIO_CMUX_USB_CTL_0,
-	SDIO_CMUX_CSVT_CTL_0
-};
-
-static int get_ctl_dev_index(int id)
-{
-	int dev_index;
-	for (dev_index = 0; dev_index < NUM_SDIO_CTL_PORTS; dev_index++) {
-		if (cmux_ch_id[dev_index] == id)
-			return dev_index;
-	}
-	return -ENODEV;
-}
-
-static void sdio_ctl_receive_cb(void *data, int size, void *priv)
-{
-	struct sdio_ctl_list_elem *list_elem = NULL;
-	int id = ((struct sdio_ctl_dev *)(priv))->id;
-	int dev_index;
-
-	if (id < 0 || id > cmux_ch_id[NUM_SDIO_CTL_PORTS - 1])
-		return;
-	dev_index = get_ctl_dev_index(id);
-	if (dev_index < 0) {
-		pr_err("%s: Ch%d is not exported to user-space\n",
-			__func__, id);
-		return;
-	}
-
-	if (!data || size <= 0) {
-		wake_up(&sdio_ctl_devp[dev_index]->read_wait_queue);
-		return;
-	}
-
-	list_elem = kmalloc(sizeof(struct sdio_ctl_list_elem), GFP_KERNEL);
-	if (!list_elem) {
-		pr_err("%s: list_elem alloc failed\n", __func__);
-		return;
-	}
-
-	list_elem->ctl_pkt.data = kmalloc(size, GFP_KERNEL);
-	if (!list_elem->ctl_pkt.data) {
-		pr_err("%s: list_elem->data alloc failed\n", __func__);
-		kfree(list_elem);
-		return;
-	}
-	memcpy(list_elem->ctl_pkt.data, data, size);
-	list_elem->ctl_pkt.data_size = size;
-	mutex_lock(&sdio_ctl_devp[dev_index]->rx_lock);
-	list_add_tail(&list_elem->list, &sdio_ctl_devp[dev_index]->rx_list);
-	sdio_ctl_devp[dev_index]->read_avail += size;
-	mutex_unlock(&sdio_ctl_devp[dev_index]->rx_lock);
-	wake_up(&sdio_ctl_devp[dev_index]->read_wait_queue);
-}
-
-static void sdio_ctl_write_done(void *data, int size, void *priv)
-{
-	int id = ((struct sdio_ctl_dev *)(priv))->id;
-	int dev_index;
-	if (id < 0 || id > cmux_ch_id[NUM_SDIO_CTL_PORTS - 1])
-		return;
-
-	dev_index = get_ctl_dev_index(id);
-	if (dev_index < 0) {
-		pr_err("%s: Ch%d is not exported to user-space\n",
-			__func__, id);
-		return;
-	}
-	wake_up(&sdio_ctl_devp[dev_index]->write_wait_queue);
-}
-
-static long sdio_ctl_ioctl(struct file *file, unsigned int cmd,
-					      unsigned long arg)
-{
-	int ret;
-	struct sdio_ctl_dev *sdio_ctl_devp;
-
-	sdio_ctl_devp = file->private_data;
-	if (!sdio_ctl_devp)
-		return -ENODEV;
-
-	switch (cmd) {
-	case TIOCMGET:
-		ret = sdio_cmux_tiocmget(sdio_ctl_devp->id);
-		break;
-	case TIOCMSET:
-		ret = sdio_cmux_tiocmset(sdio_ctl_devp->id, arg, ~arg);
-		break;
-	default:
-		ret = -EINVAL;
-	}
-
-	return ret;
-}
-
-static unsigned int sdio_ctl_poll(struct file *file, poll_table *wait)
-{
-	struct sdio_ctl_dev *sdio_ctl_devp;
-	unsigned int mask = 0;
-
-	sdio_ctl_devp = file->private_data;
-	if (!sdio_ctl_devp) {
-		pr_err("%s: on a NULL device\n", __func__);
-		return POLLERR;
-	}
-
-	poll_wait(file, &sdio_ctl_devp->read_wait_queue, wait);
-	mutex_lock(&sdio_ctl_devp->rx_lock);
-	if (sdio_cmux_is_channel_reset(sdio_ctl_devp->id)) {
-		mutex_unlock(&sdio_ctl_devp->rx_lock);
-		pr_err("%s notifying reset for sdio_ctl_dev id:%d\n",
-			__func__, sdio_ctl_devp->id);
-		return POLLERR;
-	}
-
-	if (sdio_ctl_devp->read_avail > 0)
-		mask |= POLLIN | POLLRDNORM;
-
-	mutex_unlock(&sdio_ctl_devp->rx_lock);
-
-	return mask;
-}
-
-ssize_t sdio_ctl_read(struct file *file,
-		      char __user *buf,
-		      size_t count,
-		      loff_t *ppos)
-{
-	int r = 0, id, bytes_to_read;
-	struct sdio_ctl_dev *sdio_ctl_devp;
-	struct sdio_ctl_list_elem *list_elem = NULL;
-
-	sdio_ctl_devp = file->private_data;
-
-	if (!sdio_ctl_devp)
-		return -ENODEV;
-
-	D("%s: read from ch%d\n", __func__, sdio_ctl_devp->id);
-
-	id = sdio_ctl_devp->id;
-	mutex_lock(&sdio_ctl_devp->rx_lock);
-	while (sdio_ctl_devp->read_avail <= 0) {
-		mutex_unlock(&sdio_ctl_devp->rx_lock);
-		r = wait_event_interruptible(sdio_ctl_devp->read_wait_queue,
-					     sdio_ctl_devp->read_avail > 0 ||
-					     !is_remote_open(id));
-		if (sdio_cmux_is_channel_reset(id))
-			return -ENETRESET;
-
-		if (!is_remote_open(id))
-			return -ENODEV;
-
-		if (r < 0) {
-			/* qualify error message */
-			/* we get this anytime a signal comes in */
-			if (r != -ERESTARTSYS)
-				pr_err("ERROR:%s: wait_event_interruptible "
-				       "ret %i\n", __func__, r);
-			return r;
-		}
-		mutex_lock(&sdio_ctl_devp->rx_lock);
-	}
-
-	if (list_empty(&sdio_ctl_devp->rx_list)) {
-		mutex_unlock(&sdio_ctl_devp->rx_lock);
-		D("%s: Nothing in ch%d's rx_list\n", __func__,
-		  sdio_ctl_devp->id);
-		return -EAGAIN;
-	}
-
-	list_elem = list_first_entry(&sdio_ctl_devp->rx_list,
-				     struct sdio_ctl_list_elem, list);
-	bytes_to_read = (uint32_t)(list_elem->ctl_pkt.data_size);
-	if (bytes_to_read > count) {
-		mutex_unlock(&sdio_ctl_devp->rx_lock);
-		pr_err("%s: Packet size %d > buf size %d\n", __func__,
-			bytes_to_read, count);
-		return -ENOMEM;
-	}
-
-	if (copy_to_user(buf, list_elem->ctl_pkt.data, bytes_to_read)) {
-		mutex_unlock(&sdio_ctl_devp->rx_lock);
-		pr_err("%s: copy_to_user failed for ch%d\n", __func__,
-			sdio_ctl_devp->id);
-		return -EFAULT;
-	}
-	sdio_ctl_devp->read_avail -= bytes_to_read;
-	list_del(&list_elem->list);
-	kfree(list_elem->ctl_pkt.data);
-	kfree(list_elem);
-	mutex_unlock(&sdio_ctl_devp->rx_lock);
-	D("%s: Returning %d bytes to ch%d\n", __func__,
-			bytes_to_read, sdio_ctl_devp->id);
-	return bytes_to_read;
-}
-
-
-ssize_t sdio_ctl_write(struct file *file,
-		       const char __user *buf,
-		       size_t count,
-		       loff_t *ppos)
-{
-	int r = 0, id;
-	char *temp_buf;
-	struct sdio_ctl_dev *sdio_ctl_devp;
-
-	if (count <= 0)
-		return -EINVAL;
-
-	sdio_ctl_devp = file->private_data;
-	if (!sdio_ctl_devp)
-		return -ENODEV;
-
-	D("%s: writing %i bytes on ch%d\n",
-	  __func__, count, sdio_ctl_devp->id);
-	id = sdio_ctl_devp->id;
-	mutex_lock(&sdio_ctl_devp->dev_lock);
-	while (sdio_cmux_write_avail(id) < count) {
-		mutex_unlock(&sdio_ctl_devp->dev_lock);
-		r = wait_event_interruptible(sdio_ctl_devp->write_wait_queue,
-					     sdio_cmux_write_avail(id) >= count
-					     || !is_remote_open(id));
-
-		if (sdio_cmux_is_channel_reset(id))
-			return -ENETRESET;
-
-		if (!is_remote_open(id))
-			return -ENODEV;
-
-		if (r < 0) {
-			/* qualify error message */
-			/* we get this anytime a signal comes in */
-			if (r != -ERESTARTSYS)
-				pr_err("ERROR:%s: wait_event_interruptible "
-				       "ret %i\n", __func__, r);
-			return r;
-		}
-		mutex_lock(&sdio_ctl_devp->dev_lock);
-	}
-
-	temp_buf = kmalloc(count, GFP_KERNEL);
-	if (!temp_buf) {
-		mutex_unlock(&sdio_ctl_devp->dev_lock);
-		pr_err("%s: temp_buf alloc failed\n", __func__);
-		return -ENOMEM;
-	}
-
-	if (copy_from_user(temp_buf, buf, count)) {
-		mutex_unlock(&sdio_ctl_devp->dev_lock);
-		pr_err("%s: copy_from_user failed\n", __func__);
-		kfree(temp_buf);
-		return -EFAULT;
-	}
-
-	r = sdio_cmux_write(id, (void *)temp_buf, count);
-	kfree(temp_buf);
-	mutex_unlock(&sdio_ctl_devp->dev_lock);
-	return r;
-}
-
-
-int sdio_ctl_open(struct inode *inode, struct file *file)
-{
-	int r = 0;
-	struct sdio_ctl_dev *sdio_ctl_devp;
-
-	if (!sdio_ctl_inited)
-		return -EIO;
-
-	sdio_ctl_devp = container_of(inode->i_cdev, struct sdio_ctl_dev, cdev);
-
-	if (!sdio_ctl_devp)
-		return -ENODEV;
-
-	D("%s called on sdioctl%d device\n", __func__, sdio_ctl_devp->id);
-	r = sdio_cmux_open(sdio_ctl_devp->id, sdio_ctl_receive_cb,
-			   sdio_ctl_write_done, NULL,
-			   sdio_ctl_devp);
-	if (r < 0) {
-		pr_err("ERROR %s: sdio_cmux_open failed with rc %d\n",
-			__func__, r);
-		return r;
-	}
-
-	mutex_lock(&sdio_ctl_devp->dev_lock);
-	sdio_ctl_devp->ref_count++;
-	mutex_unlock(&sdio_ctl_devp->dev_lock);
-
-	file->private_data = sdio_ctl_devp;
-	return 0;
-}
-
-int sdio_ctl_release(struct inode *inode, struct file *file)
-{
-	struct sdio_ctl_dev *sdio_ctl_devp;
-	struct sdio_ctl_list_elem *list_elem = NULL;
-
-	sdio_ctl_devp = file->private_data;
-	if (!sdio_ctl_devp)
-		return -EINVAL;
-
-	D("%s called on sdioctl%d device\n", __func__, sdio_ctl_devp->id);
-
-	mutex_lock(&sdio_ctl_devp->dev_lock);
-	if (sdio_ctl_devp->ref_count > 0) {
-		sdio_ctl_devp->ref_count--;
-		if (!sdio_ctl_devp->ref_count) {
-			mutex_lock(&sdio_ctl_devp->rx_lock);
-			while (!list_empty(&sdio_ctl_devp->rx_list)) {
-				list_elem = list_first_entry(
-						&sdio_ctl_devp->rx_list,
-						struct sdio_ctl_list_elem,
-						list);
-				list_del(&list_elem->list);
-				kfree(list_elem->ctl_pkt.data);
-				kfree(list_elem);
-			}
-			sdio_ctl_devp->read_avail = 0;
-			mutex_unlock(&sdio_ctl_devp->rx_lock);
-			sdio_cmux_close(sdio_ctl_devp->id);
-		}
-	}
-	mutex_unlock(&sdio_ctl_devp->dev_lock);
-
-	file->private_data = NULL;
-	return 0;
-}
-
-static const struct file_operations sdio_ctl_fops = {
-	.owner = THIS_MODULE,
-	.open = sdio_ctl_open,
-	.release = sdio_ctl_release,
-	.read = sdio_ctl_read,
-	.write = sdio_ctl_write,
-	.poll = sdio_ctl_poll,
-	.unlocked_ioctl = sdio_ctl_ioctl,
-};
-
-static int sdio_ctl_probe(struct platform_device *pdev)
-{
-	int i;
-	int r;
-
-	pr_info("%s Begins\n", __func__);
-	for (i = 0; i < NUM_SDIO_CTL_PORTS; ++i) {
-		sdio_ctl_devp[i] = kzalloc(sizeof(struct sdio_ctl_dev),
-					GFP_KERNEL);
-		if (IS_ERR(sdio_ctl_devp[i])) {
-			pr_err("ERROR:%s kmalloc() ENOMEM\n", __func__);
-			r = -ENOMEM;
-			goto error0;
-		}
-
-		sdio_ctl_devp[i]->id = cmux_ch_id[i];
-		sdio_ctl_devp[i]->ref_count = 0;
-
-		mutex_init(&sdio_ctl_devp[i]->dev_lock);
-		init_waitqueue_head(&sdio_ctl_devp[i]->read_wait_queue);
-		init_waitqueue_head(&sdio_ctl_devp[i]->write_wait_queue);
-		mutex_init(&sdio_ctl_devp[i]->rx_lock);
-		INIT_LIST_HEAD(&sdio_ctl_devp[i]->rx_list);
-		sdio_ctl_devp[i]->read_avail = 0;
-	}
-
-	r = alloc_chrdev_region(&sdio_ctl_number, 0, NUM_SDIO_CTL_PORTS,
-				DEVICE_NAME);
-	if (IS_ERR_VALUE(r)) {
-		pr_err("ERROR:%s: alloc_chrdev_region() ret %i.\n",
-		       __func__, r);
-		goto error0;
-	}
-
-	sdio_ctl_classp = class_create(THIS_MODULE, DEVICE_NAME);
-	if (IS_ERR(sdio_ctl_classp)) {
-		pr_err("ERROR:%s: class_create() ENOMEM\n", __func__);
-		r = -ENOMEM;
-		goto error1;
-	}
-
-	for (i = 0; i < NUM_SDIO_CTL_PORTS; ++i) {
-		cdev_init(&sdio_ctl_devp[i]->cdev, &sdio_ctl_fops);
-		sdio_ctl_devp[i]->cdev.owner = THIS_MODULE;
-
-		r = cdev_add(&sdio_ctl_devp[i]->cdev, (sdio_ctl_number + i),
-			     1);
-
-		if (IS_ERR_VALUE(r)) {
-			pr_err("%s: cdev_add() ret %i\n", __func__, r);
-			kfree(sdio_ctl_devp[i]);
-			goto error2;
-		}
-
-		sdio_ctl_devp[i]->devicep =
-				device_create(sdio_ctl_classp, NULL,
-				      (sdio_ctl_number + i), NULL,
-				      DEVICE_NAME "%d", cmux_ch_id[i]);
-
-		if (IS_ERR(sdio_ctl_devp[i]->devicep)) {
-			pr_err("%s: device_create() ENOMEM\n", __func__);
-			r = -ENOMEM;
-			cdev_del(&sdio_ctl_devp[i]->cdev);
-			kfree(sdio_ctl_devp[i]);
-			goto error2;
-		}
-	}
-
-	sdio_ctl_inited = 1;
-	D("SDIO Control Port Driver Initialized.\n");
-	return 0;
-
-error2:
-	while (--i >= 0) {
-		cdev_del(&sdio_ctl_devp[i]->cdev);
-		device_destroy(sdio_ctl_classp,
-			       MKDEV(MAJOR(sdio_ctl_number), i));
-	}
-
-	class_destroy(sdio_ctl_classp);
-	i = NUM_SDIO_CTL_PORTS;
-error1:
-	unregister_chrdev_region(MAJOR(sdio_ctl_number), NUM_SDIO_CTL_PORTS);
-error0:
-	while (--i >= 0)
-		kfree(sdio_ctl_devp[i]);
-	return r;
-}
-
-static int sdio_ctl_remove(struct platform_device *pdev)
-{
-	int i;
-
-	for (i = 0; i < NUM_SDIO_CTL_PORTS; ++i) {
-		cdev_del(&sdio_ctl_devp[i]->cdev);
-		kfree(sdio_ctl_devp[i]);
-		device_destroy(sdio_ctl_classp,
-			       MKDEV(MAJOR(sdio_ctl_number), i));
-	}
-	class_destroy(sdio_ctl_classp);
-	unregister_chrdev_region(MAJOR(sdio_ctl_number), NUM_SDIO_CTL_PORTS);
-
-	return 0;
-}
-
-static struct platform_driver sdio_ctl_driver = {
-	.probe		= sdio_ctl_probe,
-	.remove		= sdio_ctl_remove,
-	.driver		= {
-			.name	= "SDIO_CTL",
-			.owner	= THIS_MODULE,
-	},
-};
-
-static int __init sdio_ctl_init(void)
-{
-	msm_sdio_ctl_debug_mask = 0;
-	return platform_driver_register(&sdio_ctl_driver);
-}
-
-module_init(sdio_ctl_init);
-MODULE_DESCRIPTION("MSM SDIO Control Port");
-MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/sdio_dmux.c b/arch/arm/mach-msm/sdio_dmux.c
deleted file mode 100644
index c6d665d..0000000
--- a/arch/arm/mach-msm/sdio_dmux.c
+++ /dev/null
@@ -1,925 +0,0 @@
-/* Copyright (c) 2010-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.
- *
- */
-
-/*
- *  SDIO DMUX module.
- */
-
-#define DEBUG
-
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/skbuff.h>
-#include <linux/wakelock.h>
-#include <linux/debugfs.h>
-#include <linux/smp.h>
-#include <linux/cpumask.h>
-
-#include <mach/sdio_al.h>
-#include <mach/sdio_dmux.h>
-
-#define SDIO_CH_LOCAL_OPEN       0x1
-#define SDIO_CH_REMOTE_OPEN      0x2
-#define SDIO_CH_IN_RESET         0x4
-
-#define SDIO_MUX_HDR_MAGIC_NO    0x33fc
-
-#define SDIO_MUX_HDR_CMD_DATA    0
-#define SDIO_MUX_HDR_CMD_OPEN    1
-#define SDIO_MUX_HDR_CMD_CLOSE   2
-
-#define LOW_WATERMARK            2
-#define HIGH_WATERMARK           4
-
-static int msm_sdio_dmux_debug_enable;
-module_param_named(debug_enable, msm_sdio_dmux_debug_enable,
-		   int, S_IRUGO | S_IWUSR | S_IWGRP);
-
-#if defined(DEBUG)
-static uint32_t sdio_dmux_read_cnt;
-static uint32_t sdio_dmux_write_cnt;
-static uint32_t sdio_dmux_write_cpy_cnt;
-static uint32_t sdio_dmux_write_cpy_bytes;
-
-#define DBG(x...) do {		                 \
-		if (msm_sdio_dmux_debug_enable)  \
-			pr_debug(x);	         \
-	} while (0)
-
-#define DBG_INC_READ_CNT(x) do {	                               \
-		sdio_dmux_read_cnt += (x);                             \
-		if (msm_sdio_dmux_debug_enable)                        \
-			pr_debug("%s: total read bytes %u\n",          \
-				 __func__, sdio_dmux_read_cnt);        \
-	} while (0)
-
-#define DBG_INC_WRITE_CNT(x)  do {	                               \
-		sdio_dmux_write_cnt += (x);                            \
-		if (msm_sdio_dmux_debug_enable)                        \
-			pr_debug("%s: total written bytes %u\n",       \
-				 __func__, sdio_dmux_write_cnt);       \
-	} while (0)
-
-#define DBG_INC_WRITE_CPY(x)  do {	                                     \
-		sdio_dmux_write_cpy_bytes += (x);                            \
-		sdio_dmux_write_cpy_cnt++;                                   \
-		if (msm_sdio_dmux_debug_enable)                              \
-			pr_debug("%s: total write copy cnt %u, bytes %u\n",  \
-				 __func__, sdio_dmux_write_cpy_cnt,          \
-				 sdio_dmux_write_cpy_bytes);                 \
-	} while (0)
-#else
-#define DBG(x...) do { } while (0)
-#define DBG_INC_READ_CNT(x...) do { } while (0)
-#define DBG_INC_WRITE_CNT(x...) do { } while (0)
-#define DBG_INC_WRITE_CPY(x...) do { } while (0)
-#endif
-
-struct sdio_ch_info {
-	uint32_t status;
-	void (*receive_cb)(void *, struct sk_buff *);
-	void (*write_done)(void *, struct sk_buff *);
-	void *priv;
-	spinlock_t lock;
-	int num_tx_pkts;
-	int use_wm;
-};
-
-static struct sk_buff_head sdio_mux_write_pool;
-static spinlock_t sdio_mux_write_lock;
-
-static struct sdio_channel *sdio_mux_ch;
-static struct sdio_ch_info sdio_ch[SDIO_DMUX_NUM_CHANNELS];
-struct wake_lock sdio_mux_ch_wakelock;
-static int sdio_mux_initialized;
-static int fatal_error;
-
-struct sdio_mux_hdr {
-	uint16_t magic_num;
-	uint8_t reserved;
-	uint8_t cmd;
-	uint8_t pad_len;
-	uint8_t ch_id;
-	uint16_t pkt_len;
-};
-
-struct sdio_partial_pkt_info {
-	uint32_t valid;
-	struct sk_buff *skb;
-	struct sdio_mux_hdr *hdr;
-};
-
-static void sdio_mux_read_data(struct work_struct *work);
-static void sdio_mux_write_data(struct work_struct *work);
-static void sdio_mux_send_open_cmd(uint32_t id);
-
-static DEFINE_MUTEX(sdio_mux_lock);
-static DECLARE_WORK(work_sdio_mux_read, sdio_mux_read_data);
-static DECLARE_WORK(work_sdio_mux_write, sdio_mux_write_data);
-static DECLARE_DELAYED_WORK(delayed_work_sdio_mux_write, sdio_mux_write_data);
-
-static struct workqueue_struct *sdio_mux_workqueue;
-static struct sdio_partial_pkt_info sdio_partial_pkt;
-
-#define sdio_ch_is_open(x)						\
-	(sdio_ch[(x)].status == (SDIO_CH_LOCAL_OPEN | SDIO_CH_REMOTE_OPEN))
-
-#define sdio_ch_is_local_open(x)			\
-	(sdio_ch[(x)].status & SDIO_CH_LOCAL_OPEN)
-
-#define sdio_ch_is_remote_open(x)			\
-	(sdio_ch[(x)].status & SDIO_CH_REMOTE_OPEN)
-
-#define sdio_ch_is_in_reset(x)			\
-	(sdio_ch[(x)].status & SDIO_CH_IN_RESET)
-
-static inline void skb_set_data(struct sk_buff *skb,
-				unsigned char *data,
-				unsigned int len)
-{
-	/* panic if tail > end */
-	skb->data = data;
-	skb->tail = skb->data + len;
-	skb->len  = len;
-	skb->truesize = len + sizeof(struct sk_buff);
-}
-
-static void sdio_mux_save_partial_pkt(struct sdio_mux_hdr *hdr,
-				      struct sk_buff *skb_mux)
-{
-	struct sk_buff *skb;
-
-	/* i think we can avoid cloning here */
-	skb =  skb_clone(skb_mux, GFP_KERNEL);
-	if (!skb) {
-		pr_err("%s: cannot clone skb\n", __func__);
-		return;
-	}
-
-	/* protect? */
-	skb_set_data(skb, (unsigned char *)hdr,
-		     skb->tail - (unsigned char *)hdr);
-	sdio_partial_pkt.skb = skb;
-	sdio_partial_pkt.valid = 1;
-	DBG("%s: head %p data %p tail %p end %p len %d\n", __func__,
-	    skb->head, skb->data, skb->tail, skb->end, skb->len);
-	return;
-}
-
-static void *handle_sdio_mux_data(struct sdio_mux_hdr *hdr,
-				  struct sk_buff *skb_mux)
-{
-	struct sk_buff *skb;
-	void *rp = (void *)hdr;
-	unsigned long flags;
-
-	/* protect? */
-	rp += sizeof(*hdr);
-	if (rp < (void *)skb_mux->tail)
-		rp += (hdr->pkt_len + hdr->pad_len);
-
-	if (rp > (void *)skb_mux->tail) {
-		/* partial packet */
-		sdio_mux_save_partial_pkt(hdr, skb_mux);
-		goto packet_done;
-	}
-
-	DBG("%s: hdr %p next %p tail %p pkt_size %d\n",
-	    __func__, hdr, rp, skb_mux->tail, hdr->pkt_len + hdr->pad_len);
-
-	skb =  skb_clone(skb_mux, GFP_KERNEL);
-	if (!skb) {
-		pr_err("%s: cannot clone skb\n", __func__);
-		goto packet_done;
-	}
-
-	skb_set_data(skb, (unsigned char *)(hdr + 1), hdr->pkt_len);
-	DBG("%s: head %p data %p tail %p end %p len %d\n",
-	    __func__, skb->head, skb->data, skb->tail, skb->end, skb->len);
-
-	/* probably we should check channel status */
-	/* discard packet early if local side not open */
-	spin_lock_irqsave(&sdio_ch[hdr->ch_id].lock, flags);
-	if (sdio_ch[hdr->ch_id].receive_cb)
-		sdio_ch[hdr->ch_id].receive_cb(sdio_ch[hdr->ch_id].priv, skb);
-	else
-		dev_kfree_skb_any(skb);
-	spin_unlock_irqrestore(&sdio_ch[hdr->ch_id].lock, flags);
-
-packet_done:
-	return rp;
-}
-
-static void *handle_sdio_mux_command(struct sdio_mux_hdr *hdr,
-				     struct sk_buff *skb_mux)
-{
-	void *rp;
-	unsigned long flags;
-	int send_open = 0;
-
-	DBG("%s: cmd %d ch %d\n", __func__, hdr->cmd, hdr->ch_id);
-	switch (hdr->cmd) {
-	case SDIO_MUX_HDR_CMD_DATA:
-		rp = handle_sdio_mux_data(hdr, skb_mux);
-		break;
-	case SDIO_MUX_HDR_CMD_OPEN:
-		spin_lock_irqsave(&sdio_ch[hdr->ch_id].lock, flags);
-		sdio_ch[hdr->ch_id].status |= SDIO_CH_REMOTE_OPEN;
-		sdio_ch[hdr->ch_id].num_tx_pkts = 0;
-
-		if (sdio_ch_is_in_reset(hdr->ch_id)) {
-			DBG("%s: in reset - sending open cmd\n", __func__);
-			sdio_ch[hdr->ch_id].status &= ~SDIO_CH_IN_RESET;
-			send_open = 1;
-		}
-
-		/* notify client so it can update its status */
-		if (sdio_ch[hdr->ch_id].receive_cb)
-			sdio_ch[hdr->ch_id].receive_cb(
-					sdio_ch[hdr->ch_id].priv, NULL);
-
-		if (sdio_ch[hdr->ch_id].write_done)
-			sdio_ch[hdr->ch_id].write_done(
-					sdio_ch[hdr->ch_id].priv, NULL);
-		spin_unlock_irqrestore(&sdio_ch[hdr->ch_id].lock, flags);
-		rp = hdr + 1;
-		if (send_open)
-			sdio_mux_send_open_cmd(hdr->ch_id);
-
-		break;
-	case SDIO_MUX_HDR_CMD_CLOSE:
-		/* probably should drop pending write */
-		spin_lock_irqsave(&sdio_ch[hdr->ch_id].lock, flags);
-		sdio_ch[hdr->ch_id].status &= ~SDIO_CH_REMOTE_OPEN;
-		spin_unlock_irqrestore(&sdio_ch[hdr->ch_id].lock, flags);
-		rp = hdr + 1;
-		break;
-	default:
-		rp = hdr + 1;
-	}
-
-	return rp;
-}
-
-static void *handle_sdio_partial_pkt(struct sk_buff *skb_mux)
-{
-	struct sk_buff *p_skb;
-	struct sdio_mux_hdr *p_hdr;
-	void *ptr, *rp = skb_mux->data;
-
-	/* protoect? */
-	if (sdio_partial_pkt.valid) {
-		p_skb = sdio_partial_pkt.skb;
-
-		ptr = skb_push(skb_mux, p_skb->len);
-		memcpy(ptr, p_skb->data, p_skb->len);
-		sdio_partial_pkt.skb = NULL;
-		sdio_partial_pkt.valid = 0;
-		dev_kfree_skb_any(p_skb);
-
-		DBG("%s: head %p data %p tail %p end %p len %d\n", __func__,
-		    skb_mux->head, skb_mux->data, skb_mux->tail,
-		    skb_mux->end, skb_mux->len);
-
-		p_hdr = (struct sdio_mux_hdr *)skb_mux->data;
-		rp = handle_sdio_mux_command(p_hdr, skb_mux);
-	}
-	return rp;
-}
-
-static void sdio_mux_read_data(struct work_struct *work)
-{
-	struct sk_buff *skb_mux;
-	void *ptr = 0;
-	int sz, rc, len = 0;
-	struct sdio_mux_hdr *hdr;
-	static int workqueue_pinned;
-
-	if (!workqueue_pinned) {
-		struct cpumask cpus;
-
-		cpumask_clear(&cpus);
-		cpumask_set_cpu(0, &cpus);
-
-		if (sched_setaffinity(current->pid, &cpus))
-			pr_err("%s: sdio_dmux set CPU affinity failed\n",
-					__func__);
-		workqueue_pinned = 1;
-	}
-
-	DBG("%s: reading\n", __func__);
-	/* should probably have a separate read lock */
-	mutex_lock(&sdio_mux_lock);
-	sz = sdio_read_avail(sdio_mux_ch);
-	DBG("%s: read avail %d\n", __func__, sz);
-	if (sz <= 0) {
-		if (sz)
-			pr_err("%s: read avail failed %d\n", __func__, sz);
-		mutex_unlock(&sdio_mux_lock);
-		return;
-	}
-
-	/* net_ip_aling is probably not required */
-	if (sdio_partial_pkt.valid)
-		len = sdio_partial_pkt.skb->len;
-
-	/* If allocation fails attempt to get a smaller chunk of mem */
-	do {
-		skb_mux = __dev_alloc_skb(sz + NET_IP_ALIGN + len, GFP_KERNEL);
-		if (skb_mux)
-			break;
-
-		pr_err("%s: cannot allocate skb of size:%d + "
-			"%d (NET_SKB_PAD)\n", __func__,
-			sz + NET_IP_ALIGN + len, NET_SKB_PAD);
-		/* the skb structure adds NET_SKB_PAD bytes to the memory
-		 * request, which may push the actual request above PAGE_SIZE
-		 * in that case, we need to iterate one more time to make sure
-		 * we get the memory request under PAGE_SIZE
-		 */
-		if (sz + NET_IP_ALIGN + len + NET_SKB_PAD <= PAGE_SIZE) {
-			pr_err("%s: allocation failed\n", __func__);
-			mutex_unlock(&sdio_mux_lock);
-			return;
-		}
-		sz /= 2;
-	} while (1);
-
-	skb_reserve(skb_mux, NET_IP_ALIGN + len);
-	ptr = skb_put(skb_mux, sz);
-
-	/* half second wakelock is fine? */
-	wake_lock_timeout(&sdio_mux_ch_wakelock, HZ / 2);
-	rc = sdio_read(sdio_mux_ch, ptr, sz);
-	DBG("%s: read %d\n", __func__, rc);
-	if (rc) {
-		pr_err("%s: sdio read failed %d\n", __func__, rc);
-		dev_kfree_skb_any(skb_mux);
-		mutex_unlock(&sdio_mux_lock);
-		queue_work(sdio_mux_workqueue, &work_sdio_mux_read);
-		return;
-	}
-	mutex_unlock(&sdio_mux_lock);
-
-	DBG_INC_READ_CNT(sz);
-	DBG("%s: head %p data %p tail %p end %p len %d\n", __func__,
-	    skb_mux->head, skb_mux->data, skb_mux->tail,
-	    skb_mux->end, skb_mux->len);
-
-	/* move to a separate function */
-	/* probably do skb_pull instead of pointer adjustment */
-	hdr = handle_sdio_partial_pkt(skb_mux);
-	while ((void *)hdr < (void *)skb_mux->tail) {
-
-		if (((void *)hdr + sizeof(*hdr)) > (void *)skb_mux->tail) {
-			/* handle partial header */
-			sdio_mux_save_partial_pkt(hdr, skb_mux);
-			break;
-		}
-
-		if (hdr->magic_num != SDIO_MUX_HDR_MAGIC_NO) {
-			pr_err("%s: packet error\n", __func__);
-			break;
-		}
-
-		hdr = handle_sdio_mux_command(hdr, skb_mux);
-	}
-	dev_kfree_skb_any(skb_mux);
-
-	DBG("%s: read done\n", __func__);
-	queue_work(sdio_mux_workqueue, &work_sdio_mux_read);
-}
-
-static int sdio_mux_write(struct sk_buff *skb)
-{
-	int rc, sz;
-
-	mutex_lock(&sdio_mux_lock);
-	sz = sdio_write_avail(sdio_mux_ch);
-	DBG("%s: avail %d len %d\n", __func__, sz, skb->len);
-	if (skb->len <= sz) {
-		rc = sdio_write(sdio_mux_ch, skb->data, skb->len);
-		DBG("%s: write returned %d\n", __func__, rc);
-		if (rc == 0)
-			DBG_INC_WRITE_CNT(skb->len);
-	} else
-		rc = -ENOMEM;
-
-	mutex_unlock(&sdio_mux_lock);
-	return rc;
-}
-
-static int sdio_mux_write_cmd(void *data, uint32_t len)
-{
-	int avail, rc;
-	for (;;) {
-		mutex_lock(&sdio_mux_lock);
-		avail = sdio_write_avail(sdio_mux_ch);
-		DBG("%s: avail %d len %d\n", __func__, avail, len);
-		if (avail >= len) {
-			rc = sdio_write(sdio_mux_ch, data, len);
-			DBG("%s: write returned %d\n", __func__, rc);
-			if (!rc) {
-				DBG_INC_WRITE_CNT(len);
-				break;
-			}
-		}
-		mutex_unlock(&sdio_mux_lock);
-		msleep(250);
-	}
-	mutex_unlock(&sdio_mux_lock);
-	return 0;
-}
-
-static void sdio_mux_send_open_cmd(uint32_t id)
-{
-	struct sdio_mux_hdr hdr = {
-		.magic_num = SDIO_MUX_HDR_MAGIC_NO,
-		.cmd = SDIO_MUX_HDR_CMD_OPEN,
-		.reserved = 0,
-		.ch_id = id,
-		.pkt_len = 0,
-		.pad_len = 0
-	};
-
-	sdio_mux_write_cmd((void *)&hdr, sizeof(hdr));
-}
-
-static void sdio_mux_write_data(struct work_struct *work)
-{
-	int rc, reschedule = 0;
-	int notify = 0;
-	struct sk_buff *skb;
-	unsigned long flags;
-	int avail;
-	int ch_id;
-
-	spin_lock_irqsave(&sdio_mux_write_lock, flags);
-	while ((skb = __skb_dequeue(&sdio_mux_write_pool))) {
-		ch_id = ((struct sdio_mux_hdr *)skb->data)->ch_id;
-
-		avail = sdio_write_avail(sdio_mux_ch);
-		if (avail < skb->len) {
-			/* we may have to wait for write avail
-			 * notification from sdio al
-			 */
-			DBG("%s: sdio_write_avail(%d) < skb->len(%d)\n",
-					__func__, avail, skb->len);
-
-			reschedule = 1;
-			break;
-		}
-		spin_unlock_irqrestore(&sdio_mux_write_lock, flags);
-		rc = sdio_mux_write(skb);
-		spin_lock_irqsave(&sdio_mux_write_lock, flags);
-		if (rc == 0) {
-
-			spin_lock(&sdio_ch[ch_id].lock);
-			sdio_ch[ch_id].num_tx_pkts--;
-			spin_unlock(&sdio_ch[ch_id].lock);
-
-			if (sdio_ch[ch_id].write_done)
-				sdio_ch[ch_id].write_done(
-						sdio_ch[ch_id].priv, skb);
-			else
-				dev_kfree_skb_any(skb);
-		} else if (rc == -EAGAIN || rc == -ENOMEM) {
-			/* recoverable error - retry again later */
-			reschedule = 1;
-			break;
-		} else if (rc == -ENODEV) {
-			/*
-			 * sdio_al suffered some kind of fatal error
-			 * prevent future writes and clean up pending ones
-			 */
-			fatal_error = 1;
-			do {
-				ch_id = ((struct sdio_mux_hdr *)
-						skb->data)->ch_id;
-				spin_lock(&sdio_ch[ch_id].lock);
-				sdio_ch[ch_id].num_tx_pkts--;
-				spin_unlock(&sdio_ch[ch_id].lock);
-				dev_kfree_skb_any(skb);
-			} while ((skb = __skb_dequeue(&sdio_mux_write_pool)));
-			spin_unlock_irqrestore(&sdio_mux_write_lock, flags);
-			return;
-		} else {
-			/* unknown error condition - drop the
-			 * skb and reschedule for the
-			 * other skb's
-			 */
-			pr_err("%s: sdio_mux_write error %d"
-				   " for ch %d, skb=%p\n",
-				__func__, rc, ch_id, skb);
-			notify = 1;
-			break;
-		}
-	}
-
-	if (reschedule) {
-		if (sdio_ch_is_in_reset(ch_id)) {
-			notify = 1;
-		} else {
-			__skb_queue_head(&sdio_mux_write_pool, skb);
-			queue_delayed_work(sdio_mux_workqueue,
-					&delayed_work_sdio_mux_write,
-					msecs_to_jiffies(250)
-					);
-		}
-	}
-
-	if (notify) {
-		spin_lock(&sdio_ch[ch_id].lock);
-		sdio_ch[ch_id].num_tx_pkts--;
-		spin_unlock(&sdio_ch[ch_id].lock);
-
-		if (sdio_ch[ch_id].write_done)
-			sdio_ch[ch_id].write_done(
-				sdio_ch[ch_id].priv, skb);
-		else
-			dev_kfree_skb_any(skb);
-	}
-	spin_unlock_irqrestore(&sdio_mux_write_lock, flags);
-}
-
-int msm_sdio_is_channel_in_reset(uint32_t id)
-{
-	int rc = 0;
-
-	if (id >= SDIO_DMUX_NUM_CHANNELS)
-		return -EINVAL;
-
-	if (sdio_ch_is_in_reset(id))
-		rc = 1;
-
-	return rc;
-}
-
-int msm_sdio_dmux_write(uint32_t id, struct sk_buff *skb)
-{
-	int rc = 0;
-	struct sdio_mux_hdr *hdr;
-	unsigned long flags;
-	struct sk_buff *new_skb;
-
-	if (id >= SDIO_DMUX_NUM_CHANNELS)
-		return -EINVAL;
-	if (!skb)
-		return -EINVAL;
-	if (!sdio_mux_initialized)
-		return -ENODEV;
-	if (fatal_error)
-		return -ENODEV;
-
-	DBG("%s: writing to ch %d len %d\n", __func__, id, skb->len);
-	spin_lock_irqsave(&sdio_ch[id].lock, flags);
-	if (sdio_ch_is_in_reset(id)) {
-		spin_unlock_irqrestore(&sdio_ch[id].lock, flags);
-		pr_err("%s: port is in reset: %d\n", __func__,
-				sdio_ch[id].status);
-		return -ENETRESET;
-	}
-	if (!sdio_ch_is_local_open(id)) {
-		spin_unlock_irqrestore(&sdio_ch[id].lock, flags);
-		pr_err("%s: port not open: %d\n", __func__, sdio_ch[id].status);
-		return -ENODEV;
-	}
-	if (sdio_ch[id].use_wm &&
-			(sdio_ch[id].num_tx_pkts >= HIGH_WATERMARK)) {
-		spin_unlock_irqrestore(&sdio_ch[id].lock, flags);
-		pr_err("%s: watermark exceeded: %d\n", __func__, id);
-		return -EAGAIN;
-	}
-	spin_unlock_irqrestore(&sdio_ch[id].lock, flags);
-
-	spin_lock_irqsave(&sdio_mux_write_lock, flags);
-	/* if skb do not have any tailroom for padding,
-	   copy the skb into a new expanded skb */
-	if ((skb->len & 0x3) && (skb_tailroom(skb) < (4 - (skb->len & 0x3)))) {
-		/* revisit, probably dev_alloc_skb and memcpy is effecient */
-		new_skb = skb_copy_expand(skb, skb_headroom(skb),
-					  4 - (skb->len & 0x3), GFP_ATOMIC);
-		if (new_skb == NULL) {
-			pr_err("%s: cannot allocate skb\n", __func__);
-			rc = -ENOMEM;
-			goto write_done;
-		}
-		dev_kfree_skb_any(skb);
-		skb = new_skb;
-		DBG_INC_WRITE_CPY(skb->len);
-	}
-
-	hdr = (struct sdio_mux_hdr *)skb_push(skb, sizeof(struct sdio_mux_hdr));
-
-	/* caller should allocate for hdr and padding
-	   hdr is fine, padding is tricky */
-	hdr->magic_num = SDIO_MUX_HDR_MAGIC_NO;
-	hdr->cmd = SDIO_MUX_HDR_CMD_DATA;
-	hdr->reserved = 0;
-	hdr->ch_id = id;
-	hdr->pkt_len = skb->len - sizeof(struct sdio_mux_hdr);
-	if (skb->len & 0x3)
-		skb_put(skb, 4 - (skb->len & 0x3));
-
-	hdr->pad_len = skb->len - (sizeof(struct sdio_mux_hdr) + hdr->pkt_len);
-
-	DBG("%s: data %p, tail %p skb len %d pkt len %d pad len %d\n",
-	    __func__, skb->data, skb->tail, skb->len,
-	    hdr->pkt_len, hdr->pad_len);
-	__skb_queue_tail(&sdio_mux_write_pool, skb);
-
-	spin_lock(&sdio_ch[id].lock);
-	sdio_ch[id].num_tx_pkts++;
-	spin_unlock(&sdio_ch[id].lock);
-
-	queue_work(sdio_mux_workqueue, &work_sdio_mux_write);
-
-write_done:
-	spin_unlock_irqrestore(&sdio_mux_write_lock, flags);
-	return rc;
-}
-
-int msm_sdio_dmux_open(uint32_t id, void *priv,
-			void (*receive_cb)(void *, struct sk_buff *),
-			void (*write_done)(void *, struct sk_buff *))
-{
-	unsigned long flags;
-
-	DBG("%s: opening ch %d\n", __func__, id);
-	if (!sdio_mux_initialized)
-		return -ENODEV;
-	if (id >= SDIO_DMUX_NUM_CHANNELS)
-		return -EINVAL;
-
-	spin_lock_irqsave(&sdio_ch[id].lock, flags);
-	if (sdio_ch_is_local_open(id)) {
-		pr_info("%s: Already opened %d\n", __func__, id);
-		spin_unlock_irqrestore(&sdio_ch[id].lock, flags);
-		goto open_done;
-	}
-
-	sdio_ch[id].receive_cb = receive_cb;
-	sdio_ch[id].write_done = write_done;
-	sdio_ch[id].priv = priv;
-	sdio_ch[id].status |= SDIO_CH_LOCAL_OPEN;
-	sdio_ch[id].num_tx_pkts = 0;
-	sdio_ch[id].use_wm = 0;
-	spin_unlock_irqrestore(&sdio_ch[id].lock, flags);
-
-	sdio_mux_send_open_cmd(id);
-
-open_done:
-	pr_info("%s: opened ch %d\n", __func__, id);
-	return 0;
-}
-
-int msm_sdio_dmux_close(uint32_t id)
-{
-	struct sdio_mux_hdr hdr;
-	unsigned long flags;
-
-	if (id >= SDIO_DMUX_NUM_CHANNELS)
-		return -EINVAL;
-	DBG("%s: closing ch %d\n", __func__, id);
-	if (!sdio_mux_initialized)
-		return -ENODEV;
-	spin_lock_irqsave(&sdio_ch[id].lock, flags);
-
-	sdio_ch[id].receive_cb = NULL;
-	sdio_ch[id].priv = NULL;
-	sdio_ch[id].status &= ~SDIO_CH_LOCAL_OPEN;
-	sdio_ch[id].status &= ~SDIO_CH_IN_RESET;
-	spin_unlock_irqrestore(&sdio_ch[id].lock, flags);
-
-	hdr.magic_num = SDIO_MUX_HDR_MAGIC_NO;
-	hdr.cmd = SDIO_MUX_HDR_CMD_CLOSE;
-	hdr.reserved = 0;
-	hdr.ch_id = id;
-	hdr.pkt_len = 0;
-	hdr.pad_len = 0;
-
-	sdio_mux_write_cmd((void *)&hdr, sizeof(hdr));
-
-	pr_info("%s: closed ch %d\n", __func__, id);
-	return 0;
-}
-
-static void sdio_mux_notify(void *_dev, unsigned event)
-{
-	DBG("%s: event %d notified\n", __func__, event);
-
-	/* write avail may not be enouogh for a packet, but should be fine */
-	if ((event == SDIO_EVENT_DATA_WRITE_AVAIL) &&
-	    sdio_write_avail(sdio_mux_ch))
-		queue_work(sdio_mux_workqueue, &work_sdio_mux_write);
-
-	if ((event == SDIO_EVENT_DATA_READ_AVAIL) &&
-	    sdio_read_avail(sdio_mux_ch))
-		queue_work(sdio_mux_workqueue, &work_sdio_mux_read);
-}
-
-int msm_sdio_dmux_is_ch_full(uint32_t id)
-{
-	unsigned long flags;
-	int ret;
-
-	if (id >= SDIO_DMUX_NUM_CHANNELS)
-		return -EINVAL;
-
-	spin_lock_irqsave(&sdio_ch[id].lock, flags);
-	sdio_ch[id].use_wm = 1;
-	ret = sdio_ch[id].num_tx_pkts >= HIGH_WATERMARK;
-	DBG("%s: ch %d num tx pkts=%d, HWM=%d\n", __func__,
-			id, sdio_ch[id].num_tx_pkts, ret);
-	if (!sdio_ch_is_local_open(id)) {
-		ret = -ENODEV;
-		pr_err("%s: port not open: %d\n", __func__, sdio_ch[id].status);
-	}
-	spin_unlock_irqrestore(&sdio_ch[id].lock, flags);
-
-	return ret;
-}
-
-int msm_sdio_dmux_is_ch_low(uint32_t id)
-{
-	int ret;
-
-	if (id >= SDIO_DMUX_NUM_CHANNELS)
-		return -EINVAL;
-
-	sdio_ch[id].use_wm = 1;
-	ret = sdio_ch[id].num_tx_pkts <= LOW_WATERMARK;
-	DBG("%s: ch %d num tx pkts=%d, LWM=%d\n", __func__,
-			id, sdio_ch[id].num_tx_pkts, ret);
-	if (!sdio_ch_is_local_open(id)) {
-		ret = -ENODEV;
-		pr_err("%s: port not open: %d\n", __func__, sdio_ch[id].status);
-	}
-
-	return ret;
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-static int debug_tbl(char *buf, int max)
-{
-	int i = 0;
-	int j;
-
-	for (j = 0; j < SDIO_DMUX_NUM_CHANNELS; ++j) {
-		i += scnprintf(buf + i, max - i,
-			"ch%02d  local open=%s  remote open=%s\n",
-			j, sdio_ch_is_local_open(j) ? "Y" : "N",
-			sdio_ch_is_remote_open(j) ? "Y" : "N");
-	}
-
-	return i;
-}
-
-#define DEBUG_BUFMAX 4096
-static char debug_buffer[DEBUG_BUFMAX];
-
-static ssize_t debug_read(struct file *file, char __user *buf,
-				size_t count, loff_t *ppos)
-{
-	int (*fill)(char *buf, int max) = file->private_data;
-	int bsize = fill(debug_buffer, DEBUG_BUFMAX);
-	return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize);
-}
-
-static int debug_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return 0;
-}
-
-
-static const struct file_operations debug_ops = {
-	.read = debug_read,
-	.open = debug_open,
-};
-
-static void debug_create(const char *name, mode_t mode,
-				struct dentry *dent,
-				int (*fill)(char *buf, int max))
-{
-	debugfs_create_file(name, mode, dent, fill, &debug_ops);
-}
-
-#endif
-
-static int sdio_dmux_probe(struct platform_device *pdev)
-{
-	int rc;
-
-	DBG("%s probe called\n", __func__);
-
-	if (!sdio_mux_initialized) {
-		sdio_mux_workqueue = create_singlethread_workqueue("sdio_dmux");
-		if (!sdio_mux_workqueue)
-			return -ENOMEM;
-
-		skb_queue_head_init(&sdio_mux_write_pool);
-		spin_lock_init(&sdio_mux_write_lock);
-
-		for (rc = 0; rc < SDIO_DMUX_NUM_CHANNELS; ++rc)
-			spin_lock_init(&sdio_ch[rc].lock);
-
-
-		wake_lock_init(&sdio_mux_ch_wakelock, WAKE_LOCK_SUSPEND,
-				   "sdio_dmux");
-	}
-
-	rc = sdio_open("SDIO_RMNT", &sdio_mux_ch, NULL, sdio_mux_notify);
-	if (rc < 0) {
-		pr_err("%s: sido open failed %d\n", __func__, rc);
-		wake_lock_destroy(&sdio_mux_ch_wakelock);
-		destroy_workqueue(sdio_mux_workqueue);
-		sdio_mux_initialized = 0;
-		return rc;
-	}
-
-	fatal_error = 0;
-	sdio_mux_initialized = 1;
-	return 0;
-}
-
-static int sdio_dmux_remove(struct platform_device *pdev)
-{
-	int i;
-	unsigned long ch_lock_flags;
-	unsigned long write_lock_flags;
-	struct sk_buff *skb;
-
-	DBG("%s remove called\n", __func__);
-	if (!sdio_mux_initialized)
-		return 0;
-
-	/* set reset state for any open channels */
-	for (i = 0; i < SDIO_DMUX_NUM_CHANNELS; ++i) {
-		spin_lock_irqsave(&sdio_ch[i].lock, ch_lock_flags);
-		if (sdio_ch_is_open(i)) {
-			sdio_ch[i].status |= SDIO_CH_IN_RESET;
-			sdio_ch[i].status &= ~SDIO_CH_REMOTE_OPEN;
-
-			/* notify client so it can update its status */
-			if (sdio_ch[i].receive_cb)
-				sdio_ch[i].receive_cb(
-						sdio_ch[i].priv, NULL);
-		}
-		spin_unlock_irqrestore(&sdio_ch[i].lock, ch_lock_flags);
-	}
-
-	/* cancel any pending writes */
-	spin_lock_irqsave(&sdio_mux_write_lock, write_lock_flags);
-	while ((skb = __skb_dequeue(&sdio_mux_write_pool))) {
-		i = ((struct sdio_mux_hdr *)skb->data)->ch_id;
-		if (sdio_ch[i].write_done)
-			sdio_ch[i].write_done(
-					sdio_ch[i].priv, skb);
-		else
-			dev_kfree_skb_any(skb);
-	}
-	spin_unlock_irqrestore(&sdio_mux_write_lock,
-			write_lock_flags);
-
-	return 0;
-}
-
-static struct platform_driver sdio_dmux_driver = {
-	.probe		= sdio_dmux_probe,
-	.remove   = sdio_dmux_remove,
-	.driver		= {
-		.name	= "SDIO_RMNT",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static int __init sdio_dmux_init(void)
-{
-#ifdef CONFIG_DEBUG_FS
-	struct dentry *dent;
-
-	dent = debugfs_create_dir("sdio_dmux", 0);
-	if (!IS_ERR(dent))
-		debug_create("tbl", 0444, dent, debug_tbl);
-#endif
-	return platform_driver_register(&sdio_dmux_driver);
-}
-
-module_init(sdio_dmux_init);
-MODULE_DESCRIPTION("MSM SDIO DMUX");
-MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/sdio_smem.c b/arch/arm/mach-msm/sdio_smem.c
deleted file mode 100644
index edc0d23..0000000
--- a/arch/arm/mach-msm/sdio_smem.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/* Copyright (c) 2010-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/sched.h>
-#include <linux/wait.h>
-#include <linux/workqueue.h>
-#include <linux/module.h>
-#include <mach/sdio_al.h>
-#include <mach/sdio_smem.h>
-
-static void sdio_smem_read(struct work_struct *work);
-
-static struct sdio_channel *channel;
-static struct workqueue_struct *workq;
-static DECLARE_WORK(work_read, sdio_smem_read);
-static DECLARE_WAIT_QUEUE_HEAD(waitq);
-static int bytes_avail;
-static int sdio_ch_opened;
-
-static void sdio_smem_release(struct device *dev)
-{
-	pr_debug("sdio smem released\n");
-}
-
-static struct sdio_smem_client client;
-
-static void sdio_smem_read(struct work_struct *work)
-{
-	int err;
-	int read_avail;
-	char *data = client.buf;
-
-	if (!sdio_ch_opened)
-		return;
-
-	read_avail = sdio_read_avail(channel);
-	if (read_avail > bytes_avail ||
-		read_avail < 0) {
-		pr_err("Error: read_avail=%d bytes_avail=%d\n",
-			read_avail, bytes_avail);
-		goto read_err;
-	}
-
-	if (read_avail == 0)
-		return;
-
-	err = sdio_read(channel,
-			&data[client.size - bytes_avail],
-			read_avail);
-	if (err) {
-		pr_err("sdio_read error (%d)", err);
-		goto read_err;
-	}
-
-	bytes_avail -= read_avail;
-	pr_debug("read %d bytes (bytes_avail = %d)\n",
-			read_avail, bytes_avail);
-
-	if (!bytes_avail) {
-		bytes_avail = client.size;
-		err = client.cb_func(SDIO_SMEM_EVENT_READ_DONE);
-	}
-	if (err)
-		pr_err("error (%d) on callback\n", err);
-
-	return;
-
-read_err:
-	if (sdio_ch_opened)
-		client.cb_func(SDIO_SMEM_EVENT_READ_ERR);
-	return;
-}
-
-static void sdio_smem_notify(void *priv, unsigned event)
-{
-	pr_debug("%d event received\n", event);
-
-	if (event == SDIO_EVENT_DATA_READ_AVAIL ||
-	    event == SDIO_EVENT_DATA_WRITE_AVAIL)
-		queue_work(workq, &work_read);
-}
-
-int sdio_smem_register_client(void)
-{
-	int err = 0;
-
-	if (!client.buf || !client.size || !client.cb_func)
-		return -EINVAL;
-
-	pr_debug("buf = %p\n", client.buf);
-	pr_debug("size = 0x%x\n", client.size);
-
-	bytes_avail = client.size;
-	workq = create_singlethread_workqueue("sdio_smem");
-	if (!workq)
-		return -ENOMEM;
-
-	sdio_ch_opened = 1;
-	err = sdio_open("SDIO_SMEM", &channel, NULL, sdio_smem_notify);
-	if (err) {
-		sdio_ch_opened = 0;
-		pr_err("sdio_open error (%d)\n", err);
-		destroy_workqueue(workq);
-		return err;
-	}
-	pr_debug("SDIO SMEM channel opened\n");
-	return err;
-}
-
-int sdio_smem_unregister_client(void)
-{
-	int err = 0;
-
-	sdio_ch_opened = 0;
-	err = sdio_close(channel);
-	if (err) {
-		pr_err("sdio_close error (%d)\n", err);
-		return err;
-	}
-	pr_debug("SDIO SMEM channel closed\n");
-	flush_workqueue(workq);
-	destroy_workqueue(workq);
-	bytes_avail = 0;
-	client.buf = NULL;
-	client.cb_func = NULL;
-	client.size = 0;
-
-	return 0;
-}
-
-static int sdio_smem_probe(struct platform_device *pdev)
-{
-	client.plat_dev.name = "SDIO_SMEM_CLIENT";
-	client.plat_dev.id = -1;
-	client.plat_dev.dev.release = sdio_smem_release;
-
-	return platform_device_register(&client.plat_dev);
-}
-
-static int sdio_smem_remove(struct platform_device *pdev)
-{
-	platform_device_unregister(&client.plat_dev);
-	memset(&client, 0, sizeof(client));
-	sdio_ch_opened = 0;
-	return 0;
-}
-static struct platform_driver sdio_smem_drv = {
-	.probe		= sdio_smem_probe,
-	.remove		= sdio_smem_remove,
-	.driver		= {
-		.name	= "SDIO_SMEM",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static int __init sdio_smem_init(void)
-{
-	return platform_driver_register(&sdio_smem_drv);
-};
-
-module_init(sdio_smem_init);
-
-MODULE_DESCRIPTION("SDIO SMEM");
-MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/sdio_tty.c b/arch/arm/mach-msm/sdio_tty.c
deleted file mode 100644
index c4b7673..0000000
--- a/arch/arm/mach-msm/sdio_tty.c
+++ /dev/null
@@ -1,824 +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.
- */
-
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/workqueue.h>
-#include <linux/platform_device.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/module.h>
-#include <linux/debugfs.h>
-#include <mach/sdio_al.h>
-
-#define INPUT_SPEED			4800
-#define OUTPUT_SPEED			4800
-#define SDIO_TTY_MODULE_NAME		"sdio_tty"
-#define SDIO_TTY_MAX_PACKET_SIZE	4096
-#define MAX_SDIO_TTY_DRV		1
-#define MAX_SDIO_TTY_DEVS		2
-#define MAX_SDIO_TTY_DEV_NAME_SIZE	25
-
-/* Configurations per channel device */
-/* CSVT */
-#define SDIO_TTY_CSVT_DEV		"sdio_tty_csvt_0"
-#define SDIO_TTY_CSVT_TEST_DEV		"sdio_tty_csvt_test_0"
-#define SDIO_TTY_CH_CSVT		"SDIO_CSVT"
-
-enum sdio_tty_state {
-	TTY_INITIAL = 0,
-	TTY_REGISTERED = 1,
-	TTY_OPENED = 2,
-	TTY_CLOSED = 3,
-};
-
-enum sdio_tty_devices {
-	SDIO_CSVT,
-	SDIO_CSVT_TEST_APP,
-};
-
-static const struct platform_device_id sdio_tty_id_table[] = {
-	{ "SDIO_CSVT",		SDIO_CSVT },
-	{ "SDIO_CSVT_TEST_APP",	SDIO_CSVT_TEST_APP },
-	{ },
-};
-MODULE_DEVICE_TABLE(platform, sdio_tty_id_table);
-
-struct sdio_tty {
-	struct sdio_channel *ch;
-	char *sdio_ch_name;
-	char tty_dev_name[MAX_SDIO_TTY_DEV_NAME_SIZE];
-	int device_id;
-	struct workqueue_struct *workq;
-	struct work_struct work_read;
-	wait_queue_head_t   waitq;
-	struct tty_driver *tty_drv;
-	struct tty_struct *tty_str;
-	int debug_msg_on;
-	char *read_buf;
-	enum sdio_tty_state sdio_tty_state;
-	int is_sdio_open;
-	int tty_open_count;
-	int total_rx;
-	int total_tx;
-};
-
-static struct sdio_tty *sdio_tty[MAX_SDIO_TTY_DEVS];
-
-#ifdef CONFIG_DEBUG_FS
-struct dentry *sdio_tty_debug_root;
-struct dentry *sdio_tty_debug_info;
-#endif
-
-#define DEBUG_MSG(sdio_tty_drv, x...) if (sdio_tty_drv->debug_msg_on) pr_info(x)
-
-/*
- * Enable sdio_tty debug messages
- * By default the sdio_tty debug messages are turned off
- */
-static int csvt_debug_msg_on;
-module_param(csvt_debug_msg_on, int, 0);
-
-static void sdio_tty_read(struct work_struct *work)
-{
-	int ret = 0;
-	int read_avail = 0;
-	int left = 0;
-	int total_push = 0;
-	int num_push = 0;
-	struct sdio_tty *sdio_tty_drv = NULL;
-
-	sdio_tty_drv = container_of(work, struct sdio_tty, work_read);
-
-	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty", __func__);
-		return ;
-	}
-
-	if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_state = %d",
-			__func__, sdio_tty_drv->sdio_tty_state);
-		return;
-	}
-
-	if (!sdio_tty_drv->read_buf) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL read_buf for dev %s",
-			__func__, sdio_tty_drv->tty_dev_name);
-		return;
-	}
-
-	/* Read the data from the SDIO channel as long as there is available
-	   data */
-	while (1) {
-		if (test_bit(TTY_THROTTLED, &sdio_tty_drv->tty_str->flags)) {
-			DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME
-					": %s: TTY_THROTTLED bit is set for "
-					"dev %s, exit", __func__,
-					sdio_tty_drv->tty_dev_name);
-			return;
-		}
-
-		total_push = 0;
-		read_avail = sdio_read_avail(sdio_tty_drv->ch);
-
-		DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME
-				": %s: read_avail is %d for dev %s", __func__,
-				read_avail, sdio_tty_drv->tty_dev_name);
-
-		if (read_avail == 0) {
-			DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME
-					": %s: read_avail is 0 for dev %s",
-					__func__, sdio_tty_drv->tty_dev_name);
-			return;
-		}
-
-		if (read_avail > SDIO_TTY_MAX_PACKET_SIZE) {
-			pr_err(SDIO_TTY_MODULE_NAME ": %s: read_avail(%d) is "
-				"bigger than SDIO_TTY_MAX_PACKET_SIZE(%d) "
-				"for dev %s", __func__, read_avail,
-				SDIO_TTY_MAX_PACKET_SIZE,
-				sdio_tty_drv->tty_dev_name);
-			return;
-		}
-
-		ret = sdio_read(sdio_tty_drv->ch,
-				sdio_tty_drv->read_buf,
-				read_avail);
-		if (ret < 0) {
-			pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_read error(%d) "
-				"for dev %s", __func__, ret,
-				sdio_tty_drv->tty_dev_name);
-			return;
-		}
-
-		left = read_avail;
-		do {
-			num_push = tty_insert_flip_string(
-				sdio_tty_drv->tty_str,
-				sdio_tty_drv->read_buf+total_push,
-				left);
-			total_push += num_push;
-			left -= num_push;
-			tty_flip_buffer_push(sdio_tty_drv->tty_str);
-		} while (left != 0);
-
-		if (total_push != read_avail) {
-			pr_err(SDIO_TTY_MODULE_NAME ": %s: failed, total_push"
-				"(%d) != read_avail(%d) for dev %s\n",
-				__func__, total_push, read_avail,
-				sdio_tty_drv->tty_dev_name);
-		}
-
-		tty_flip_buffer_push(sdio_tty_drv->tty_str);
-		sdio_tty_drv->total_rx += read_avail;
-
-		DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: Rx: %d, "
-				"Total Rx = %d bytes for dev %s", __func__,
-				read_avail, sdio_tty_drv->total_rx,
-				sdio_tty_drv->tty_dev_name);
-	}
-}
-
-/**
-  * sdio_tty_write_room
-  *
-  * This is the write_room function of the tty driver.
-  *
-  * @tty: pointer to tty struct.
-  * @return free bytes for write.
-  *
-  */
-static int sdio_tty_write_room(struct tty_struct *tty)
-{
-	int write_avail = 0;
-	struct sdio_tty *sdio_tty_drv = NULL;
-
-	if (!tty) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
-		return -ENODEV;
-	}
-	sdio_tty_drv = tty->driver_data;
-	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-			__func__);
-		return -ENODEV;
-	}
-
-	if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_state = %d",
-			__func__, sdio_tty_drv->sdio_tty_state);
-		return -EPERM;
-	}
-
-	write_avail = sdio_write_avail(sdio_tty_drv->ch);
-	DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: write_avail=%d "
-			"for dev %s", __func__, write_avail,
-			sdio_tty_drv->tty_dev_name);
-
-	return write_avail;
-}
-
-/**
-  * sdio_tty_write_callback
-  * this is the write callback of the tty driver.
-  *
-  * @tty: pointer to tty struct.
-  * @buf: buffer to write from.
-  * @count: number of bytes to write.
-  * @return bytes written or negative value on error.
-  *
-  * if destination buffer has not enough room for the incoming
-  * data, writes the possible amount of bytes .
-  */
-static int sdio_tty_write_callback(struct tty_struct *tty,
-				   const unsigned char *buf, int count)
-{
-	int write_avail = 0;
-	int len = count;
-	int ret = 0;
-	struct sdio_tty *sdio_tty_drv = NULL;
-
-	if (!tty) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
-		return -ENODEV;
-	}
-	sdio_tty_drv = tty->driver_data;
-	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-			__func__);
-		return -ENODEV;
-	}
-
-	if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_state = %d",
-			__func__, sdio_tty_drv->sdio_tty_state);
-		return -EPERM;
-	}
-
-	DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: Write Callback "
-			"called with %d bytes for dev %s\n", __func__, count,
-			sdio_tty_drv->tty_dev_name);
-	write_avail = sdio_write_avail(sdio_tty_drv->ch);
-	if (write_avail == 0) {
-		DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: "
-				"write_avail is 0 for dev %s\n",
-				__func__, sdio_tty_drv->tty_dev_name);
-		return 0;
-	}
-	if (write_avail > SDIO_TTY_MAX_PACKET_SIZE) {
-		DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: "
-				"write_avail(%d) is bigger than max packet "
-				"size(%d) for dev %s, setting to "
-				"max_packet_size\n", __func__, write_avail,
-				SDIO_TTY_MAX_PACKET_SIZE,
-				sdio_tty_drv->tty_dev_name);
-		write_avail = SDIO_TTY_MAX_PACKET_SIZE;
-	}
-	if (write_avail < count) {
-		DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: "
-				"write_avail(%d) is smaller than required(%d) "
-				"for dev %s, writing only %d bytes\n",
-				__func__, write_avail, count,
-				sdio_tty_drv->tty_dev_name, write_avail);
-		len = write_avail;
-	}
-	ret = sdio_write(sdio_tty_drv->ch, buf, len);
-	if (ret) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_write failed for "
-			"dev %s, ret=%d\n", __func__,
-			sdio_tty_drv->tty_dev_name, ret);
-		return 0;
-	}
-
-	sdio_tty_drv->total_tx += len;
-
-	DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: Tx: %d, "
-			"Total Tx = %d for dev %s", __func__, len,
-			sdio_tty_drv->total_tx, sdio_tty_drv->tty_dev_name);
-	return len;
-}
-
-static void sdio_tty_notify(void *priv, unsigned event)
-{
-	struct sdio_tty *sdio_tty_drv = priv;
-
-	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-			__func__);
-	}
-
-	if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_state = %d",
-			__func__, sdio_tty_drv->sdio_tty_state);
-		return;
-	}
-
-	DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: event %d "
-			"received for dev %s\n", __func__, event,
-			sdio_tty_drv->tty_dev_name);
-
-	if (event == SDIO_EVENT_DATA_READ_AVAIL)
-		queue_work(sdio_tty_drv->workq, &sdio_tty_drv->work_read);
-}
-
-/**
-  * sdio_tty_open
-  * This is the open callback of the tty driver. it opens
-  * the sdio channel, and creates the workqueue.
-  *
-  * @tty: a pointer to the tty struct.
-  * @file: file descriptor.
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_tty_open(struct tty_struct *tty, struct file *file)
-{
-	int ret = 0;
-	int i = 0;
-	struct sdio_tty *sdio_tty_drv = NULL;
-
-	if (!tty) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
-		return -ENODEV;
-	}
-
-	for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
-		if (sdio_tty[i] == NULL)
-			continue;
-		if (!strncmp(sdio_tty[i]->tty_dev_name, tty->name,
-				MAX_SDIO_TTY_DEV_NAME_SIZE)) {
-			sdio_tty_drv = sdio_tty[i];
-			break;
-		}
-	}
-
-	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-		       __func__);
-		return -ENODEV;
-	}
-
-	sdio_tty_drv->tty_open_count++;
-	if (sdio_tty_drv->sdio_tty_state == TTY_OPENED) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: tty dev(%s) is already open",
-			__func__, sdio_tty_drv->tty_dev_name);
-		return -EBUSY;
-	}
-
-	tty->driver_data = sdio_tty_drv;
-
-	sdio_tty_drv->tty_str = tty;
-	sdio_tty_drv->tty_str->low_latency = 1;
-	sdio_tty_drv->tty_str->icanon = 0;
-	set_bit(TTY_NO_WRITE_SPLIT, &sdio_tty_drv->tty_str->flags);
-
-	sdio_tty_drv->read_buf = kzalloc(SDIO_TTY_MAX_PACKET_SIZE, GFP_KERNEL);
-	if (sdio_tty_drv->read_buf == NULL) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: failed to allocate read_buf "
-			"for dev %s", __func__, sdio_tty_drv->tty_dev_name);
-		return -ENOMEM;
-	}
-
-	sdio_tty_drv->workq = create_singlethread_workqueue("sdio_tty_read");
-	if (!sdio_tty_drv->workq) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: failed to create workq "
-			"for dev %s", __func__, sdio_tty_drv->tty_dev_name);
-		return -ENOMEM;
-	}
-
-	if (!sdio_tty_drv->is_sdio_open) {
-		ret = sdio_open(sdio_tty_drv->sdio_ch_name, &sdio_tty_drv->ch,
-				sdio_tty_drv, sdio_tty_notify);
-		if (ret < 0) {
-			pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_open err=%d "
-				"for dev %s\n", __func__, ret,
-				sdio_tty_drv->tty_dev_name);
-			destroy_workqueue(sdio_tty_drv->workq);
-			return ret;
-		}
-
-		pr_info(SDIO_TTY_MODULE_NAME ": %s: SDIO_TTY channel(%s) "
-			"opened\n", __func__, sdio_tty_drv->sdio_ch_name);
-
-		sdio_tty_drv->is_sdio_open = 1;
-	} else {
-		/* If SDIO channel is already open try to read the data
-		 * from the modem
-		 */
-		queue_work(sdio_tty_drv->workq, &sdio_tty_drv->work_read);
-
-	}
-
-	sdio_tty_drv->sdio_tty_state = TTY_OPENED;
-
-	pr_info(SDIO_TTY_MODULE_NAME ": %s: TTY device(%s) opened\n",
-		__func__, sdio_tty_drv->tty_dev_name);
-
-	return ret;
-}
-
-/**
-  * sdio_tty_close
-  * This is the close callback of the tty driver. it requests
-  * the main thread to exit, and waits for notification of it.
-  * it also de-allocates the buffers, and unregisters the tty
-  * driver and device.
-  *
-  * @tty: a pointer to the tty struct.
-  * @file: file descriptor.
-  * @return None.
-  */
-static void sdio_tty_close(struct tty_struct *tty, struct file *file)
-{
-	struct sdio_tty *sdio_tty_drv = NULL;
-
-	if (!tty) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
-		return;
-	}
-	sdio_tty_drv = tty->driver_data;
-	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-		       __func__);
-		return;
-	}
-	if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: trying to close a "
-			"TTY device that was not opened\n", __func__);
-		return;
-	}
-	if (--sdio_tty_drv->tty_open_count != 0)
-		return;
-
-	flush_workqueue(sdio_tty_drv->workq);
-	destroy_workqueue(sdio_tty_drv->workq);
-
-	kfree(sdio_tty_drv->read_buf);
-	sdio_tty_drv->read_buf = NULL;
-
-	sdio_tty_drv->sdio_tty_state = TTY_CLOSED;
-
-	pr_info(SDIO_TTY_MODULE_NAME ": %s: SDIO_TTY device(%s) closed\n",
-		__func__, sdio_tty_drv->tty_dev_name);
-}
-
-static void sdio_tty_unthrottle(struct tty_struct *tty)
-{
-	struct sdio_tty *sdio_tty_drv = NULL;
-
-	if (!tty) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
-		return;
-	}
-	sdio_tty_drv = tty->driver_data;
-	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-		       __func__);
-		return;
-	}
-
-	if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_state = %d",
-		       __func__, sdio_tty_drv->sdio_tty_state);
-		return;
-	}
-
-	queue_work(sdio_tty_drv->workq, &sdio_tty_drv->work_read);
-	return;
-}
-
-static const struct tty_operations sdio_tty_ops = {
-	.open = sdio_tty_open,
-	.close = sdio_tty_close,
-	.write = sdio_tty_write_callback,
-	.write_room = sdio_tty_write_room,
-	.unthrottle = sdio_tty_unthrottle,
-};
-
-int sdio_tty_init_tty(char *tty_name, char *sdio_ch_name,
-			enum sdio_tty_devices device_id, int debug_msg_on)
-{
-	int ret = 0;
-	int i = 0;
-	struct device *tty_dev = NULL;
-	struct sdio_tty *sdio_tty_drv = NULL;
-
-	sdio_tty_drv = kzalloc(sizeof(struct sdio_tty), GFP_KERNEL);
-	if (sdio_tty_drv == NULL) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: failed to allocate sdio_tty "
-			"for dev %s", __func__, tty_name);
-		return -ENOMEM;
-	}
-
-	for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
-		if (sdio_tty[i] == NULL) {
-			sdio_tty[i] = sdio_tty_drv;
-			break;
-		}
-	}
-
-	if (i == MAX_SDIO_TTY_DEVS) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: tty dev(%s) creation failed,"
-			" max limit(%d) reached.", __func__, tty_name,
-			MAX_SDIO_TTY_DEVS);
-		kfree(sdio_tty_drv);
-		return -ENODEV;
-	}
-
-	snprintf(sdio_tty_drv->tty_dev_name, MAX_SDIO_TTY_DEV_NAME_SIZE,
-			"%s%d", tty_name, 0);
-	sdio_tty_drv->sdio_ch_name = sdio_ch_name;
-	sdio_tty_drv->device_id = device_id;
-	pr_info(SDIO_TTY_MODULE_NAME ": %s: dev=%s, id=%d, channel=%s\n",
-		__func__, sdio_tty_drv->tty_dev_name, sdio_tty_drv->device_id,
-		sdio_tty_drv->sdio_ch_name);
-
-	INIT_WORK(&sdio_tty_drv->work_read, sdio_tty_read);
-
-	sdio_tty_drv->tty_drv = alloc_tty_driver(MAX_SDIO_TTY_DRV);
-
-	if (!sdio_tty_drv->tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s - tty_drv is NULL for dev %s",
-			__func__, sdio_tty_drv->tty_dev_name);
-		kfree(sdio_tty_drv);
-		return -ENODEV;
-	}
-
-	sdio_tty_drv->tty_drv->name = tty_name;
-	sdio_tty_drv->tty_drv->owner = THIS_MODULE;
-	sdio_tty_drv->tty_drv->driver_name = "SDIO_tty";
-	/* uses dynamically assigned dev_t values */
-	sdio_tty_drv->tty_drv->type = TTY_DRIVER_TYPE_SERIAL;
-	sdio_tty_drv->tty_drv->subtype = SERIAL_TYPE_NORMAL;
-	sdio_tty_drv->tty_drv->flags = TTY_DRIVER_REAL_RAW
-		| TTY_DRIVER_DYNAMIC_DEV
-		| TTY_DRIVER_RESET_TERMIOS;
-
-	/* initializing the tty driver */
-	sdio_tty_drv->tty_drv->init_termios = tty_std_termios;
-	sdio_tty_drv->tty_drv->init_termios.c_cflag =
-		B4800 | CS8 | CREAD | HUPCL | CLOCAL;
-	sdio_tty_drv->tty_drv->init_termios.c_ispeed = INPUT_SPEED;
-	sdio_tty_drv->tty_drv->init_termios.c_ospeed = OUTPUT_SPEED;
-
-	tty_set_operations(sdio_tty_drv->tty_drv, &sdio_tty_ops);
-
-	ret = tty_register_driver(sdio_tty_drv->tty_drv);
-	if (ret) {
-		put_tty_driver(sdio_tty_drv->tty_drv);
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: tty_register_driver() "
-			"failed for dev %s\n", __func__,
-			sdio_tty_drv->tty_dev_name);
-
-		sdio_tty_drv->tty_drv = NULL;
-		kfree(sdio_tty_drv);
-		return -ENODEV;
-	}
-
-	tty_dev = tty_register_device(sdio_tty_drv->tty_drv, 0, NULL);
-	if (IS_ERR(tty_dev)) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: tty_register_device() "
-			"failed for dev %s\n", __func__,
-			sdio_tty_drv->tty_dev_name);
-		tty_unregister_driver(sdio_tty_drv->tty_drv);
-		put_tty_driver(sdio_tty_drv->tty_drv);
-		kfree(sdio_tty_drv);
-		return -ENODEV;
-	}
-
-	sdio_tty_drv->sdio_tty_state = TTY_REGISTERED;
-	if (debug_msg_on) {
-		pr_info(SDIO_TTY_MODULE_NAME ": %s: turn on debug msg for %s",
-			__func__, sdio_tty_drv->tty_dev_name);
-		sdio_tty_drv->debug_msg_on = debug_msg_on;
-	}
-	return 0;
-}
-
-int sdio_tty_uninit_tty(void *sdio_tty_handle)
-{
-	int ret = 0;
-	int i = 0;
-	struct sdio_tty *sdio_tty_drv = sdio_tty_handle;
-
-	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-		       __func__);
-		return -ENODEV;
-	}
-	if (sdio_tty_drv->sdio_tty_state == TTY_OPENED) {
-		flush_workqueue(sdio_tty_drv->workq);
-		destroy_workqueue(sdio_tty_drv->workq);
-
-		kfree(sdio_tty_drv->read_buf);
-		sdio_tty_drv->read_buf = NULL;
-	}
-
-	if (sdio_tty_drv->sdio_tty_state != TTY_INITIAL) {
-		tty_unregister_device(sdio_tty_drv->tty_drv, 0);
-
-		ret = tty_unregister_driver(sdio_tty_drv->tty_drv);
-		if (ret) {
-			pr_err(SDIO_TTY_MODULE_NAME ": %s: "
-				"tty_unregister_driver() failed for dev %s\n",
-				__func__, sdio_tty_drv->tty_dev_name);
-		}
-		put_tty_driver(sdio_tty_drv->tty_drv);
-		sdio_tty_drv->sdio_tty_state = TTY_INITIAL;
-		sdio_tty_drv->tty_drv = NULL;
-	}
-
-	for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
-		if (sdio_tty[i] == NULL)
-			continue;
-		if (sdio_tty[i]->device_id == sdio_tty_drv->device_id) {
-			sdio_tty[i] = NULL;
-			break;
-		}
-	}
-
-	DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: Freeing sdio_tty "
-			"structure, dev=%s", __func__,
-			sdio_tty_drv->tty_dev_name);
-	kfree(sdio_tty_drv);
-
-	return 0;
-}
-
-static int sdio_tty_probe(struct platform_device *pdev)
-{
-	const struct platform_device_id *id = platform_get_device_id(pdev);
-	enum sdio_tty_devices device_id = id->driver_data;
-	char *device_name = NULL;
-	char *channel_name = NULL;
-	int debug_msg_on = 0;
-	int ret = 0;
-
-	pr_debug(SDIO_TTY_MODULE_NAME ": %s for %s", __func__, pdev->name);
-
-	switch (device_id) {
-	case SDIO_CSVT:
-		device_name = SDIO_TTY_CSVT_DEV;
-		channel_name = SDIO_TTY_CH_CSVT;
-		debug_msg_on = csvt_debug_msg_on;
-		break;
-	case SDIO_CSVT_TEST_APP:
-		device_name = SDIO_TTY_CSVT_TEST_DEV;
-		channel_name = SDIO_TTY_CH_CSVT;
-		debug_msg_on = csvt_debug_msg_on;
-		break;
-	default:
-		pr_err(SDIO_TTY_MODULE_NAME ": %s Invalid device:%s, id:%d",
-			__func__, pdev->name, device_id);
-		ret = -ENODEV;
-		break;
-	}
-
-	if (device_name) {
-		ret = sdio_tty_init_tty(device_name, channel_name,
-					device_id, debug_msg_on);
-		if (ret) {
-			pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_init_tty "
-				"failed for dev:%s", __func__, device_name);
-		}
-	}
-	return ret;
-}
-
-static int sdio_tty_remove(struct platform_device *pdev)
-{
-	const struct platform_device_id *id = platform_get_device_id(pdev);
-	enum sdio_tty_devices device_id = id->driver_data;
-	struct sdio_tty *sdio_tty_drv = NULL;
-	int i = 0;
-	int ret = 0;
-
-	pr_debug(SDIO_TTY_MODULE_NAME ": %s for %s", __func__, pdev->name);
-
-	for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
-		if (sdio_tty[i] == NULL)
-			continue;
-		if (sdio_tty[i]->device_id == device_id) {
-			sdio_tty_drv = sdio_tty[i];
-			break;
-		}
-	}
-
-	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-		       __func__);
-		return -ENODEV;
-	}
-
-	ret = sdio_tty_uninit_tty(sdio_tty_drv);
-	if (ret) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_uninit_tty "
-			"failed for %s", __func__, pdev->name);
-	}
-	return ret;
-}
-
-static struct platform_driver sdio_tty_pdrv = {
-	.probe		= sdio_tty_probe,
-	.remove		= sdio_tty_remove,
-	.id_table	= sdio_tty_id_table,
-	.driver		= {
-		.name	= "SDIO_TTY",
-		.owner	= THIS_MODULE,
-	},
-};
-
-#ifdef CONFIG_DEBUG_FS
-void sdio_tty_print_info(void)
-{
-	int i = 0;
-
-	for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
-		if (sdio_tty[i] == NULL)
-			continue;
-		pr_info(SDIO_TTY_MODULE_NAME ": %s: Total Rx=%d, Tx = %d "
-			"for dev %s", __func__, sdio_tty[i]->total_rx,
-			sdio_tty[i]->total_tx, sdio_tty[i]->tty_dev_name);
-	}
-}
-
-static int tty_debug_info_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return 0;
-}
-
-static ssize_t tty_debug_info_write(struct file *file,
-		const char __user *buf, size_t count, loff_t *ppos)
-{
-	sdio_tty_print_info();
-	return count;
-}
-
-const struct file_operations tty_debug_info_ops = {
-	.open = tty_debug_info_open,
-	.write = tty_debug_info_write,
-};
-#endif
-
-/*
- *  Module Init.
- *
- *  Register SDIO TTY driver.
- *
- */
-static int __init sdio_tty_init(void)
-{
-	int ret = 0;
-
-	ret = platform_driver_register(&sdio_tty_pdrv);
-	if (ret) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: platform_driver_register "
-					    "failed", __func__);
-	}
-#ifdef CONFIG_DEBUG_FS
-	else {
-		sdio_tty_debug_root = debugfs_create_dir("sdio_tty", NULL);
-		if (sdio_tty_debug_root) {
-			sdio_tty_debug_info = debugfs_create_file(
-							"sdio_tty_debug",
-							S_IRUGO | S_IWUGO,
-							sdio_tty_debug_root,
-							NULL,
-							&tty_debug_info_ops);
-		}
-	}
-#endif
-	return ret;
-};
-
-/*
- *  Module Exit.
- *
- *  Unregister SDIO TTY driver.
- *
- */
-static void __exit sdio_tty_exit(void)
-{
-#ifdef CONFIG_DEBUG_FS
-	debugfs_remove(sdio_tty_debug_info);
-	debugfs_remove(sdio_tty_debug_root);
-#endif
-	platform_driver_unregister(&sdio_tty_pdrv);
-}
-
-module_init(sdio_tty_init);
-module_exit(sdio_tty_exit);
-
-MODULE_DESCRIPTION("SDIO TTY");
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Maya Erez <merez@codeaurora.org>");
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index 09b3113..1241e44 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -2285,7 +2285,7 @@
 				edge_to_pids[ch->type].subsys_name);
 		irq_chip->irq_mask(irq_data);
 		if (cpumask)
-			irq_chip->irq_set_affinity(irq_data, cpumask, true);
+			irq_set_affinity(int_cfg->irq_id, cpumask);
 	} else {
 		SMD_POWER_INFO("SMD Unmasking interrupts from %s\n",
 				edge_to_pids[ch->type].subsys_name);
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index a1a2e51..669b10e 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1500,7 +1500,9 @@
 		vm->flags = VM_LOWMEM | VM_ARM_STATIC_MAPPING;
 		vm->flags |= VM_ARM_MTYPE(type);
 		vm->caller = map_lowmem;
-		vm_area_add_early(vm++);
+		vm_area_add_early(vm);
+		mark_vmalloc_reserved_area(vm->addr, vm->size);
+		vm++;
 	}
 }
 
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 b6fbb3c2..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;
 }
 
@@ -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 2dbb2f5..414207f 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -216,7 +216,11 @@
 	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;
-
+	if (write_len <= 0) {
+		pr_err("diag: Invalid length in %s, write_len: %d",
+					__func__, write_len);
+		return;
+	}
 	pr_debug("diag: len = %d\n", write_len);
 	tag = (int *)(buf + (4 + cmd_code_len)); /* Retrieve the Tag field */
 	req_entry = diag_dci_get_request_entry(*tag);
@@ -383,17 +387,23 @@
 
 void extract_dci_log(unsigned char *buf)
 {
-	uint16_t log_code, item_num;
+	uint16_t log_code, item_num, log_length;
 	uint8_t equip_id, *log_mask_ptr, byte_mask;
 	unsigned int i, byte_index, byte_offset = 0;
 	struct diag_dci_client_tbl *entry;
 
+	log_length = *(uint16_t *)(buf + 2);
 	log_code = *(uint16_t *)(buf + 6);
 	equip_id = LOG_GET_EQUIP_ID(log_code);
 	item_num = LOG_GET_ITEM_NUM(log_code);
 	byte_index = item_num/8 + 2;
 	byte_mask = 0x01 << (item_num % 8);
 
+	if (log_length > USHRT_MAX - 4) {
+		pr_err("diag: Integer overflow in %s, log_len:%d",
+				__func__, log_length);
+		return;
+	}
 	byte_offset = (equip_id * 514) + byte_index;
 	if (byte_offset >=  DCI_LOG_MASK_SIZE) {
 		pr_err("diag: Invalid byte_offset %d in dci log\n",
@@ -430,8 +440,8 @@
 				*(int *)(entry->dci_data+entry->data_len) =
 								DCI_LOG_TYPE;
 				memcpy(entry->dci_data + entry->data_len + 4,
-					    buf + 4, *(uint16_t *)(buf + 2));
-				entry->data_len += 4 + *(uint16_t *)(buf + 2);
+					    buf + 4, log_length);
+				entry->data_len += 4 + log_length;
 			}
 			mutex_unlock(&entry->data_mutex);
 			mutex_unlock(&dci_health_mutex);
diff --git a/drivers/char/diag/diag_dci.h b/drivers/char/diag/diag_dci.h
index 03304dc..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
 
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 6ead0ad..002bd0c 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -1117,7 +1117,7 @@
 	case DIAG_IOCTL_VOTE_REAL_TIME:
 		if (copy_from_user(&rt_vote, (void *)ioarg, sizeof(struct
 							real_time_vote_t)))
-			result = -EFAULT;
+			return -EFAULT;
 		driver->real_time_update_busy++;
 		if (rt_vote.proc == DIAG_PROC_DCI) {
 			diag_dci_set_real_time(current->tgid,
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 22448a1..45a41eb 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -124,11 +124,14 @@
 static bool io_is_busy;
 
 /*
- * If the max load among the other CPUs is higher than sync_freq_load_threshold
- * then do not let the frequency to drop below sync_freq
+ * If the max load among other CPUs is higher than up_threshold_any_cpu_load
+ * and if the highest frequency among the other CPUs is higher than
+ * up_threshold_any_cpu_freq then do not let the frequency to drop below
+ * sync_freq
  */
-static unsigned int sync_freq_load_threshold;
+static unsigned int up_threshold_any_cpu_load;
 static unsigned int sync_freq;
+static unsigned int up_threshold_any_cpu_freq;
 
 static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
 		unsigned int event);
@@ -393,8 +396,9 @@
 	unsigned long flags;
 	bool boosted;
 	unsigned long mod_min_sample_time;
-	int i, max_load_other_cpu;
-	unsigned int max_freq_other_cpu;
+	int i, max_load;
+	unsigned int max_freq;
+	struct cpufreq_interactive_cpuinfo *picpu;
 
 	if (!down_read_trylock(&pcpu->enable_sem))
 		return;
@@ -416,20 +420,6 @@
 	pcpu->prev_load = cpu_load;
 	boosted = boost_val || now < boostpulse_endtime;
 
-	max_load_other_cpu = 0;
-	max_freq_other_cpu = 0;
-	for_each_online_cpu(i) {
-		struct cpufreq_interactive_cpuinfo *picpu =
-						&per_cpu(cpuinfo, i);
-		if (i == data)
-			continue;
-		if (max_load_other_cpu < picpu->prev_load)
-			max_load_other_cpu = picpu->prev_load;
-
-		if (picpu->policy->cur > max_freq_other_cpu)
-			max_freq_other_cpu = picpu->policy->cur;
-	}
-
 	if (cpu_load >= go_hispeed_load || boosted) {
 		if (pcpu->target_freq < hispeed_freq) {
 			new_freq = hispeed_freq;
@@ -441,10 +431,27 @@
 		}
 	} else {
 		new_freq = choose_freq(pcpu, loadadjfreq);
-		if (sync_freq && (max_freq_other_cpu > sync_freq) &&
-			(max_load_other_cpu > sync_freq_load_threshold) &&
-				(new_freq < sync_freq))
-			new_freq = sync_freq;
+
+		if (sync_freq && new_freq < sync_freq) {
+
+			max_load = 0;
+			max_freq = 0;
+
+			for_each_online_cpu(i) {
+				picpu = &per_cpu(cpuinfo, i);
+
+				if (i == data || picpu->prev_load <
+						up_threshold_any_cpu_load)
+					continue;
+
+				max_load = max(max_load, picpu->prev_load);
+				max_freq = max(max_freq, picpu->policy->cur);
+			}
+
+			if (max_freq > up_threshold_any_cpu_freq &&
+				max_load >= up_threshold_any_cpu_load)
+				new_freq = sync_freq;
+		}
 	}
 
 	if (pcpu->target_freq >= hispeed_freq &&
@@ -470,11 +477,10 @@
 	 * Do not scale below floor_freq unless we have been at or above the
 	 * floor frequency for the minimum sample time since last validated.
 	 */
-	if (pcpu->policy->cur == pcpu->policy->max) {
+	if (sampling_down_factor && pcpu->policy->cur == pcpu->policy->max)
 		mod_min_sample_time = sampling_down_factor;
-	} else {
+	else
 		mod_min_sample_time = min_sample_time;
-	}
 
 	if (new_freq < pcpu->floor_freq) {
 		if (now - pcpu->floor_validate_time < mod_min_sample_time) {
@@ -1121,13 +1127,13 @@
 static struct global_attr sync_freq_attr = __ATTR(sync_freq, 0644,
 		show_sync_freq, store_sync_freq);
 
-static ssize_t show_sync_freq_load_threshold(struct kobject *kobj,
+static ssize_t show_up_threshold_any_cpu_load(struct kobject *kobj,
 			struct attribute *attr, char *buf)
 {
-	return sprintf(buf, "%u\n", sync_freq_load_threshold);
+	return snprintf(buf, PAGE_SIZE, "%u\n", up_threshold_any_cpu_load);
 }
 
-static ssize_t store_sync_freq_load_threshold(struct kobject *kobj,
+static ssize_t store_up_threshold_any_cpu_load(struct kobject *kobj,
 			struct attribute *attr, const char *buf, size_t count)
 {
 	int ret;
@@ -1136,14 +1142,38 @@
 	ret = kstrtoul(buf, 0, &val);
 	if (ret < 0)
 		return ret;
-	sync_freq_load_threshold = val;
+	up_threshold_any_cpu_load = val;
 	return count;
 }
 
-static struct global_attr sync_freq_load_threshold_attr =
-		__ATTR(sync_freq_load_threshold, 0644,
-		show_sync_freq_load_threshold, store_sync_freq_load_threshold);
+static struct global_attr up_threshold_any_cpu_load_attr =
+		__ATTR(up_threshold_any_cpu_load, 0644,
+		show_up_threshold_any_cpu_load,
+				store_up_threshold_any_cpu_load);
 
+static ssize_t show_up_threshold_any_cpu_freq(struct kobject *kobj,
+			struct attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n", up_threshold_any_cpu_freq);
+}
+
+static ssize_t store_up_threshold_any_cpu_freq(struct kobject *kobj,
+			struct attribute *attr, const char *buf, size_t count)
+{
+	int ret;
+	unsigned long val;
+
+	ret = kstrtoul(buf, 0, &val);
+	if (ret < 0)
+		return ret;
+	up_threshold_any_cpu_freq = val;
+	return count;
+}
+
+static struct global_attr up_threshold_any_cpu_freq_attr =
+		__ATTR(up_threshold_any_cpu_freq, 0644,
+		show_up_threshold_any_cpu_freq,
+				store_up_threshold_any_cpu_freq);
 
 static struct attribute *interactive_attributes[] = {
 	&target_loads_attr.attr,
@@ -1159,7 +1189,8 @@
 	&io_is_busy_attr.attr,
 	&sampling_down_factor_attr.attr,
 	&sync_freq_attr.attr,
-	&sync_freq_load_threshold_attr.attr,
+	&up_threshold_any_cpu_load_attr.attr,
+	&up_threshold_any_cpu_freq_attr.attr,
 	NULL,
 };
 
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 4f5893c..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)
 {
@@ -695,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);
@@ -710,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/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 17bbe19..ba38e23 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -71,6 +71,14 @@
 	  Sets the frequency using a "on-demand" algorithm.
 	  This governor is unlikely to be useful for other devices.
 
+config DEVFREQ_GOV_MSM_CPUFREQ
+	bool "MSM CPUfreq"
+	depends on CPU_FREQ_MSM
+	help
+	  MSM CPUfreq based governor for CPU bandwidth voting.  Sets the CPU
+	  to DDR BW vote based on the current CPU frequency.  This governor
+	  is unlikely to be useful for non-MSM devices.
+
 comment "DEVFREQ Drivers"
 
 config ARM_EXYNOS4_BUS_DEVFREQ
diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 29b48ff..3a960a4 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -4,6 +4,7 @@
 obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE)	+= governor_powersave.o
 obj-$(CONFIG_DEVFREQ_GOV_USERSPACE)	+= governor_userspace.o
 obj-$(CONFIG_DEVFREQ_GOV_MSM_ADRENO_TZ)	+= governor_msm_adreno_tz.o
+obj-$(CONFIG_DEVFREQ_GOV_MSM_CPUFREQ)	+= governor_msm_cpufreq.o
 
 # DEVFREQ Drivers
 obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ)	+= exynos4_bus.o
diff --git a/drivers/devfreq/governor_msm_cpufreq.c b/drivers/devfreq/governor_msm_cpufreq.c
new file mode 100644
index 0000000..9b13e26
--- /dev/null
+++ b/drivers/devfreq/governor_msm_cpufreq.c
@@ -0,0 +1,85 @@
+/*
+ * 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/devfreq.h>
+#include <mach/cpufreq.h>
+#include "governor.h"
+
+DEFINE_MUTEX(df_lock);
+static struct devfreq *df;
+
+static int devfreq_msm_cpufreq_get_freq(struct devfreq *df,
+					unsigned long *freq,
+					u32 *flag)
+{
+	*freq = msm_cpufreq_get_bw();
+	return 0;
+}
+
+int devfreq_msm_cpufreq_update_bw(void)
+{
+	int ret = 0;
+
+	mutex_lock(&df_lock);
+	if (df) {
+		mutex_lock(&df->lock);
+		ret = update_devfreq(df);
+		mutex_unlock(&df->lock);
+	}
+	mutex_unlock(&df_lock);
+	return ret;
+}
+
+static int devfreq_msm_cpufreq_ev_handler(struct devfreq *devfreq,
+					unsigned int event, void *data)
+{
+	int ret;
+
+	switch (event) {
+	case DEVFREQ_GOV_START:
+		mutex_lock(&df_lock);
+		df = devfreq;
+		mutex_unlock(&df_lock);
+
+		ret = devfreq_msm_cpufreq_update_bw();
+		if (ret) {
+			pr_err("Unable to update BW! Gov start failed!\n");
+			return ret;
+		}
+
+		devfreq_monitor_stop(df);
+		pr_debug("Enabled MSM CPUfreq governor\n");
+		break;
+
+	case DEVFREQ_GOV_STOP:
+		mutex_lock(&df_lock);
+		df = NULL;
+		mutex_unlock(&df_lock);
+
+		pr_debug("Disabled MSM CPUfreq governor\n");
+		break;
+	}
+
+	return 0;
+}
+
+static struct devfreq_governor devfreq_msm_cpufreq = {
+	.name = "msm_cpufreq",
+	.get_target_freq = devfreq_msm_cpufreq_get_freq,
+	.event_handler = devfreq_msm_cpufreq_ev_handler,
+};
+
+int register_devfreq_msm_cpufreq(void)
+{
+	return devfreq_add_governor(&devfreq_msm_cpufreq);
+}
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..a6fc3d5 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.c b/drivers/gpu/msm/adreno.c
index 070b5ac..eba60ea 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -2051,6 +2051,8 @@
 
 	device->reset_counter++;
 
+	set_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv);
+
 	return 0;
 
 error_rb_stop:
@@ -2088,7 +2090,25 @@
 	set_user_nice(current, _wake_nice);
 
 	mutex_lock(&device->mutex);
-	_status = _adreno_start(adreno_dev);
+	/*
+	 *  If adreno start is already called, no need to call it again
+	 *  it can lead to unpredictable behavior if we try to start
+	 *  the device that is already started.
+	 *  Below is the sequence of events that can go bad without the check
+	 *  1) thread 1 calls adreno_start to be scheduled on high priority wq
+	 *  2) thread 2 calls adreno_start with normal priority
+	 *  3) thread 1 after checking the device to be in slumber state gives
+	 *     up mutex to be scheduled on high priority wq
+	 *  4) thread 2 after checking the device to be in slumber state gets
+	 *     the mutex and finishes adreno_start before thread 1 is scheduled
+	 *     on high priority wq.
+	 *  5) thread 1 gets scheduled on high priority wq and executes
+	 *     adreno_start again. This leads to unpredictable behavior.
+	 */
+	if (!test_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv))
+		_status = _adreno_start(adreno_dev);
+	else
+		_status = 0;
 	mutex_unlock(&device->mutex);
 }
 
@@ -2149,6 +2169,8 @@
 
 	kgsl_cffdump_close(device);
 
+	clear_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 1b538a7..800caf1 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -216,6 +216,7 @@
 	ADRENO_DEVICE_PWRON = 0,
 	ADRENO_DEVICE_PWRON_FIXUP = 1,
 	ADRENO_DEVICE_INITIALIZED = 2,
+	ADRENO_DEVICE_STARTED = 3,
 };
 
 #define PERFCOUNTER_FLAG_NONE 0x0
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/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c
index 2da36b6..a39ceef 100644
--- a/drivers/gpu/msm/adreno_dispatch.c
+++ b/drivers/gpu/msm/adreno_dispatch.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014, 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
@@ -1515,8 +1515,14 @@
  */
 void adreno_dispatcher_start(struct kgsl_device *device)
 {
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
 	complete_all(&device->cmdbatch_gate);
 
+	/* a305b & a305c GPUs are slower than a330 and needs a larger timer */
+	if (adreno_is_a305b(adreno_dev) || adreno_is_a305c(adreno_dev))
+		_fault_timer_interval = 200;
+
 	/* Schedule the work loop to get things going */
 	adreno_dispatcher_schedule(device);
 }
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/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 3e15580..96ff1b8 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -132,6 +132,9 @@
 	int buslevel = 0;
 	if (!pwr->pcl)
 		return;
+	/* the bus should be ON to update the active frequency */
+	if (on && !(test_bit(KGSL_PWRFLAGS_AXI_ON, &pwr->power_flags)))
+		return;
 	/*
 	 * If the bus should remain on calculate our request and submit it,
 	 * otherwise request bus level 0, off.
@@ -175,11 +178,10 @@
 	pwr->bus_mod = 0;
 	pwrlevel = &pwr->pwrlevels[pwr->active_pwrlevel];
 
-	if (test_bit(KGSL_PWRFLAGS_AXI_ON, &pwr->power_flags)) {
-		kgsl_pwrctrl_buslevel_update(device, true);
+	kgsl_pwrctrl_buslevel_update(device, true);
+	if (test_bit(KGSL_PWRFLAGS_AXI_ON, &pwr->power_flags))
 		if (pwr->ebi1_clk)
 			clk_set_rate(pwr->ebi1_clk, pwrlevel->bus_freq);
-	}
 
 	if (test_bit(KGSL_PWRFLAGS_CLK_ON, &pwr->power_flags) ||
 		(device->state == KGSL_STATE_NAP)) {
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index d031d5e..d3adf84 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -591,7 +591,6 @@
 
 	sglen_alloc = PAGE_ALIGN(size) >> PAGE_SHIFT;
 
-	memdesc->size = size;
 	memdesc->pagetable = pagetable;
 	memdesc->ops = &kgsl_page_alloc_ops;
 
@@ -654,6 +653,14 @@
 				continue;
 			}
 
+			/*
+			 * Update sglen and memdesc size,as requested allocation
+			 * not served fully. So that they can be correctly freed
+			 * in kgsl_sharedmem_free().
+			 */
+			memdesc->sglen = sglen;
+			memdesc->size = (size - len);
+
 			KGSL_CORE_ERR(
 				"Out of memory: only allocated %dKB of %dKB requested\n",
 				(size - len) >> 10, size >> 10);
@@ -670,6 +677,7 @@
 	}
 
 	memdesc->sglen = sglen;
+	memdesc->size = size;
 
 	/*
 	 * All memory that goes to the user has to be zeroed out before it gets
@@ -716,15 +724,15 @@
 	outer_cache_range_op_sg(memdesc->sg, memdesc->sglen,
 				KGSL_CACHE_OP_FLUSH);
 
-	KGSL_STATS_ADD(size, kgsl_driver.stats.page_alloc,
-		kgsl_driver.stats.page_alloc_max);
-
 	order = get_order(size);
 
 	if (order < 16)
 		kgsl_driver.stats.histogram[order]++;
 
 done:
+	KGSL_STATS_ADD(memdesc->size, kgsl_driver.stats.page_alloc,
+		kgsl_driver.stats.page_alloc_max);
+
 	if ((memdesc->sglen_alloc * sizeof(struct page *)) > PAGE_SIZE)
 		vfree(pages);
 	else
diff --git a/drivers/gpu/msm/kgsl_sharedmem.h b/drivers/gpu/msm/kgsl_sharedmem.h
index 505be69..f0114ad 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.h
+++ b/drivers/gpu/msm/kgsl_sharedmem.h
@@ -141,7 +141,7 @@
 
 static inline void *kgsl_sg_alloc(unsigned int sglen)
 {
-	if (sglen >= ULONG_MAX / sizeof(struct scatterlist))
+	if ((sglen == 0) || (sglen >= ULONG_MAX / sizeof(struct scatterlist)))
 		return NULL;
 
 	if ((sglen * sizeof(struct scatterlist)) <  PAGE_SIZE)
diff --git a/drivers/hwmon/epm_adc.c b/drivers/hwmon/epm_adc.c
index f7cf2df..2f5ed9d 100644
--- a/drivers/hwmon/epm_adc.c
+++ b/drivers/hwmon/epm_adc.c
@@ -888,6 +888,12 @@
 	init_resp->num_dev		= rx_buf[6];
 	init_resp->num_channel		= rx_buf[7];
 
+	pr_debug("EPM PSOC response for hello command: resp_cmd:0x%x\n",
+							rx_buf[0]);
+	pr_debug("EPM PSOC version:0x%x\n", rx_buf[1]);
+	pr_debug("EPM PSOC firmware version:0x%x\n",
+			rx_buf[6] | rx_buf[5] | rx_buf[4] | rx_buf[3]);
+
 	return rc;
 }
 
diff --git a/drivers/hwmon/qpnp-adc-common.c b/drivers/hwmon/qpnp-adc-common.c
index 9e0be59..6a52aa3 100644
--- a/drivers/hwmon/qpnp-adc-common.c
+++ b/drivers/hwmon/qpnp-adc-common.c
@@ -238,6 +238,60 @@
 	{800,	549},
 };
 
+static const struct qpnp_vadc_map_pt adcmap_qrd_skug_btm_threshold[] = {
+	{-200,	1338},
+	{-180,	1307},
+	{-160,	1276},
+	{-140,	1244},
+	{-120,	1213},
+	{-100,	1182},
+	{-80,	1151},
+	{-60,	1121},
+	{-40,	1092},
+	{-20,	1063},
+	{0,	1035},
+	{20,	1008},
+	{40,	982},
+	{60,	957},
+	{80,	933},
+	{100,	910},
+	{120,	889},
+	{140,	868},
+	{160,	848},
+	{180,	830},
+	{200,	812},
+	{220,	795},
+	{240,	780},
+	{260,	765},
+	{280,	751},
+	{300,	738},
+	{320,	726},
+	{340,	714},
+	{360,	704},
+	{380,	694},
+	{400,	684},
+	{420,	675},
+	{440,	667},
+	{460,	659},
+	{480,	652},
+	{500,	645},
+	{520,	639},
+	{540,	633},
+	{560,	627},
+	{580,	622},
+	{600,	617},
+	{620,	613},
+	{640,	608},
+	{660,	604},
+	{680,	600},
+	{700,	597},
+	{720,	593},
+	{740,	590},
+	{760,	587},
+	{780,	585},
+	{800,	582},
+};
+
 /* Voltage to temperature */
 static const struct qpnp_vadc_map_pt adcmap_100k_104ef_104fb[] = {
 	{1758,	-40},
@@ -612,6 +666,24 @@
 }
 EXPORT_SYMBOL(qpnp_adc_scale_qrd_skuaa_batt_therm);
 
+int32_t qpnp_adc_scale_qrd_skug_batt_therm(struct qpnp_vadc_chip *chip,
+		int32_t adc_code,
+		const struct qpnp_adc_properties *adc_properties,
+		const struct qpnp_vadc_chan_properties *chan_properties,
+		struct qpnp_vadc_result *adc_chan_result)
+{
+	int64_t bat_voltage = 0;
+
+	bat_voltage = qpnp_adc_scale_ratiometric_calib(adc_code,
+			adc_properties, chan_properties);
+
+	return qpnp_adc_map_temp_voltage(
+			adcmap_qrd_skug_btm_threshold,
+			ARRAY_SIZE(adcmap_qrd_skug_btm_threshold),
+			bat_voltage,
+			&adc_chan_result->physical);
+}
+EXPORT_SYMBOL(qpnp_adc_scale_qrd_skug_batt_therm);
 int32_t qpnp_adc_scale_therm_pu1(struct qpnp_vadc_chip *chip,
 		int32_t adc_code,
 		const struct qpnp_adc_properties *adc_properties,
diff --git a/drivers/hwmon/qpnp-adc-voltage.c b/drivers/hwmon/qpnp-adc-voltage.c
index b2b846a..fb882b3 100644
--- a/drivers/hwmon/qpnp-adc-voltage.c
+++ b/drivers/hwmon/qpnp-adc-voltage.c
@@ -129,6 +129,7 @@
 	[SCALE_THERM_150K_PULLUP] = {qpnp_adc_scale_therm_pu1},
 	[SCALE_QRD_BATT_THERM] = {qpnp_adc_scale_qrd_batt_therm},
 	[SCALE_QRD_SKUAA_BATT_THERM] = {qpnp_adc_scale_qrd_skuaa_batt_therm},
+	[SCALE_QRD_SKUG_BATT_THERM] = {qpnp_adc_scale_qrd_skug_batt_therm},
 };
 
 static int32_t qpnp_vadc_read_reg(struct qpnp_vadc_chip *vadc, int16_t reg,
diff --git a/drivers/input/misc/bmp18x-core.c b/drivers/input/misc/bmp18x-core.c
index 001a804..ae98469 100644
--- a/drivers/input/misc/bmp18x-core.c
+++ b/drivers/input/misc/bmp18x-core.c
@@ -88,6 +88,7 @@
 	struct	device *dev;
 	struct	mutex lock;
 	struct	bmp18x_calibration_data calibration;
+	struct  sensors_classdev cdev;
 	u8	oversampling_setting;
 	u8	sw_oversampling_setting;
 	u32	raw_temperature;
@@ -113,9 +114,13 @@
 	.max_range = "1100.0",
 	.resolution = "0.01",
 	.sensor_power = "0.67",
-	.min_delay = 20000,
+	.min_delay = 20000,	/* microsecond */
 	.fifo_reserved_event_count = 0,
 	.fifo_max_event_count = 0,
+	.enabled = 0,
+	.delay_msec = 200,	/* millisecond */
+	.sensors_enable = NULL,
+	.sensors_poll_delay = NULL,
 };
 
 #ifdef CONFIG_HAS_EARLYSUSPEND
@@ -403,6 +408,19 @@
 static DEVICE_ATTR(sw_oversampling, S_IWUSR | S_IRUGO,
 				show_sw_oversampling, set_sw_oversampling);
 
+static ssize_t bmp18x_poll_delay_set(struct sensors_classdev *sensors_cdev,
+						unsigned int delay_msec)
+{
+	struct bmp18x_data *data = container_of(sensors_cdev,
+					struct bmp18x_data, cdev);
+	mutex_lock(&data->lock);
+	data->delay = delay_msec;
+	mutex_unlock(&data->lock);
+
+	return 0;
+}
+
+
 static ssize_t show_delay(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
@@ -416,17 +434,43 @@
 {
 	struct bmp18x_data *data = dev_get_drvdata(dev);
 	unsigned long delay;
-	int success = kstrtoul(buf, 10, &delay);
-	if (success == 0) {
-		mutex_lock(&data->lock);
-		data->delay = delay;
-		mutex_unlock(&data->lock);
-	}
-	return success;
+	int err = kstrtoul(buf, 10, &delay);
+	if (err < 0)
+		return err;
+
+	err = bmp18x_poll_delay_set(&data->cdev, delay);
+	if (err < 0)
+		return err;
+
+	return count;
 }
-static DEVICE_ATTR(delay, S_IWUSR | S_IRUGO,
+
+static DEVICE_ATTR(poll_delay, S_IWUSR | S_IRUGO,
 				show_delay, set_delay);
 
+static ssize_t bmp18x_enable_set(struct sensors_classdev *sensors_cdev,
+						unsigned int enabled)
+{
+	struct bmp18x_data *data = container_of(sensors_cdev,
+					struct bmp18x_data, cdev);
+	struct device *dev = data->dev;
+
+	mutex_lock(&data->lock);
+	data->enable = enabled ? 1 : 0;
+
+	if (data->enable) {
+		bmp18x_enable(dev);
+		schedule_delayed_work(&data->work,
+					msecs_to_jiffies(data->delay));
+	} else {
+		cancel_delayed_work_sync(&data->work);
+		bmp18x_disable(dev);
+	}
+	mutex_unlock(&data->lock);
+
+	return 0;
+}
+
 static ssize_t show_enable(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
@@ -440,24 +484,17 @@
 {
 	struct bmp18x_data *data = dev_get_drvdata(dev);
 	unsigned long enable;
-	int success = kstrtoul(buf, 10, &enable);
-	if (success == 0) {
-		mutex_lock(&data->lock);
-		data->enable = enable ? 1 : 0;
+	int err = kstrtoul(buf, 10, &enable);
+	if (err < 0)
+		return err;
 
-		if (data->enable) {
-			bmp18x_enable(dev);
-			schedule_delayed_work(&data->work,
-						msecs_to_jiffies(data->delay));
-		} else {
-			cancel_delayed_work_sync(&data->work);
-			bmp18x_disable(dev);
-		}
-		mutex_unlock(&data->lock);
+	err = bmp18x_enable_set(&data->cdev, enable);
+	if (err < 0)
+		return err;
 
-	}
 	return count;
 }
+
 static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
 				show_enable, set_enable);
 
@@ -499,7 +536,7 @@
 	&dev_attr_pressure0_input.attr,
 	&dev_attr_oversampling.attr,
 	&dev_attr_sw_oversampling.attr,
-	&dev_attr_delay.attr,
+	&dev_attr_poll_delay.attr,
 	&dev_attr_enable.attr,
 	NULL
 };
@@ -628,7 +665,10 @@
 	if (err)
 		goto error_sysfs;
 
-	err = sensors_classdev_register(&data->input->dev, &sensors_cdev);
+	data->cdev = sensors_cdev;
+	data->cdev.sensors_enable = bmp18x_enable_set;
+	data->cdev.sensors_poll_delay = bmp18x_poll_delay_set;
+	err = sensors_classdev_register(&data->input->dev, &data->cdev);
 	if (err) {
 		pr_err("class device create failed: %d\n", err);
 		goto error_class_sysfs;
diff --git a/drivers/input/misc/cm36283.c b/drivers/input/misc/cm36283.c
index ceeb67b..5f08da4 100644
--- a/drivers/input/misc/cm36283.c
+++ b/drivers/input/misc/cm36283.c
@@ -17,7 +17,6 @@
  */
 
 #include <linux/delay.h>
-#include <linux/earlysuspend.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
 #include <linux/sensors.h>
@@ -118,7 +117,6 @@
 	struct input_dev *ls_input_dev;
 	struct input_dev *ps_input_dev;
 
-	struct early_suspend early_suspend;
 	struct i2c_client *i2c_client;
 	struct workqueue_struct *lp_wq;
 
@@ -642,12 +640,6 @@
 	.unlocked_ioctl = psensor_ioctl
 };
 
-struct miscdevice psensor_misc = {
-	.minor = MISC_DYNAMIC_MINOR,
-	.name = "proximity",
-	.fops = &psensor_fops
-};
-
 void lightsensor_set_kvalue(struct cm36283_info *lpi)
 {
 	if (!lpi) {
@@ -795,13 +787,6 @@
 	.unlocked_ioctl = lightsensor_ioctl
 };
 
-static struct miscdevice lightsensor_misc = {
-	.minor = MISC_DYNAMIC_MINOR,
-	.name = "lightsensor",
-	.fops = &lightsensor_fops
-};
-
-
 static ssize_t ps_adc_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
@@ -846,7 +831,6 @@
 	return count;
 }
 
-static DEVICE_ATTR(ps_adc, 0664, ps_adc_show, ps_enable_store);
 
 static ssize_t ps_parameters_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
@@ -890,10 +874,6 @@
 	return count;
 }
 
-static DEVICE_ATTR(ps_parameters, 0664,
-	ps_parameters_show, ps_parameters_store);
-
-
 static ssize_t ps_conf_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
@@ -919,7 +899,6 @@
 
 	return count;
 }
-static DEVICE_ATTR(ps_conf, 0664, ps_conf_show, ps_conf_store);
 
 static ssize_t ps_thd_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
@@ -948,7 +927,6 @@
 
 	return count;
 }
-static DEVICE_ATTR(ps_thd, 0664, ps_thd_show, ps_thd_store);
 
 static ssize_t ps_hw_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
@@ -971,7 +949,6 @@
 
 	return count;
 }
-static DEVICE_ATTR(ps_hw, 0664, ps_hw_show, ps_hw_store);
 
 static ssize_t ls_adc_show(struct device *dev,
 				  struct device_attribute *attr, char *buf)
@@ -985,8 +962,6 @@
 	return ret;
 }
 
-static DEVICE_ATTR(ls_adc, 0664, ls_adc_show, NULL);
-
 static ssize_t ls_enable_show(struct device *dev,
 				  struct device_attribute *attr, char *buf)
 {
@@ -1035,8 +1010,6 @@
 	return count;
 }
 
-static DEVICE_ATTR(ls_auto, 0664,
-	ls_enable_show, ls_enable_store);
 
 static ssize_t ls_kadc_show(struct device *dev,
 				  struct device_attribute *attr, char *buf)
@@ -1079,7 +1052,6 @@
 	return count;
 }
 
-static DEVICE_ATTR(ls_kadc, 0664, ls_kadc_show, ls_kadc_store);
 
 static ssize_t ls_gadc_show(struct device *dev,
 				  struct device_attribute *attr, char *buf)
@@ -1119,7 +1091,6 @@
 	return count;
 }
 
-static DEVICE_ATTR(ls_gadc, 0664, ls_gadc_show, ls_gadc_store);
 
 static ssize_t ls_adc_table_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
@@ -1170,9 +1141,6 @@
 	return count;
 }
 
-static DEVICE_ATTR(ls_adc_table, 0664,
-	ls_adc_table_show, ls_adc_table_store);
-
 static ssize_t ls_conf_show(struct device *dev,
 				  struct device_attribute *attr, char *buf)
 {
@@ -1194,7 +1162,6 @@
 	_cm36283_I2C_Write_Word(lpi->slave_addr, ALS_CONF, lpi->ls_cmd);
 	return count;
 }
-static DEVICE_ATTR(ls_conf, 0664, ls_conf_show, ls_conf_store);
 
 static ssize_t ls_poll_delay_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
@@ -1221,9 +1188,6 @@
 	return count;
 }
 
-static DEVICE_ATTR(ls_poll_delay, 0664, ls_poll_delay_show,
-		ls_poll_delay_store);
-
 static ssize_t ps_poll_delay_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
@@ -1249,9 +1213,6 @@
 	return count;
 }
 
-static DEVICE_ATTR(ps_poll_delay, 0664, ps_poll_delay_show,
-		ps_poll_delay_store);
-
 static ssize_t ls_fLevel_show(struct device *dev,
 				  struct device_attribute *attr, char *buf)
 {
@@ -1273,7 +1234,6 @@
 	fLevel=-1;
 	return count;
 }
-static DEVICE_ATTR(ls_flevel, 0664, ls_fLevel_show, ls_fLevel_store);
 
 static int lightsensor_setup(struct cm36283_info *lpi)
 {
@@ -1288,6 +1248,7 @@
 		return -ENOMEM;
 	}
 	lpi->ls_input_dev->name = "cm36283-ls";
+	lpi->ls_input_dev->id.bustype = BUS_I2C;
 	set_bit(EV_ABS, lpi->ls_input_dev->evbit);
 
 	range = get_als_range();
@@ -1300,17 +1261,8 @@
 		goto err_free_ls_input_device;
 	}
 
-	ret = misc_register(&lightsensor_misc);
-	if (ret < 0) {
-		pr_err("[LS][CM36283 error]%s: can not register ls misc device\n",
-				__func__);
-		goto err_unregister_ls_input_device;
-	}
-
 	return ret;
 
-err_unregister_ls_input_device:
-	input_unregister_device(lpi->ls_input_dev);
 err_free_ls_input_device:
 	input_free_device(lpi->ls_input_dev);
 	return ret;
@@ -1328,6 +1280,7 @@
 		return -ENOMEM;
 	}
 	lpi->ps_input_dev->name = "cm36283-ps";
+	lpi->ps_input_dev->id.bustype = BUS_I2C;
 	set_bit(EV_ABS, lpi->ps_input_dev->evbit);
 	input_set_abs_params(lpi->ps_input_dev, ABS_DISTANCE, 0, 1, 0, 0);
 
@@ -1339,18 +1292,8 @@
 		goto err_free_ps_input_device;
 	}
 
-	ret = misc_register(&psensor_misc);
-	if (ret < 0) {
-		pr_err(
-			"[PS][CM36283 error]%s: could not register ps misc device\n",
-			__func__);
-		goto err_unregister_ps_input_device;
-	}
-
 	return ret;
 
-err_unregister_ps_input_device:
-	input_unregister_device(lpi->ps_input_dev);
 err_free_ps_input_device:
 	input_free_device(lpi->ps_input_dev);
 	return ret;
@@ -1426,29 +1369,6 @@
 	return ret;
 }
 
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static void cm36283_early_suspend(struct early_suspend *h)
-{
-	struct cm36283_info *lpi = lp_info;
-
-	D("[LS][CM36283] %s\n", __func__);
-
-	if (lpi->als_enable)
-		lightsensor_disable(lpi);
-
-}
-
-static void cm36283_late_resume(struct early_suspend *h)
-{
-	struct cm36283_info *lpi = lp_info;
-
-	D("[LS][CM36283] %s\n", __func__);
-
-	if (!lpi->als_enable)
-		lightsensor_enable(lpi);
-}
-#endif
-
 static int cm36283_parse_dt(struct device *dev,
 				struct cm36283_platform_data *pdata)
 {
@@ -1521,6 +1441,59 @@
 	return 0;
 }
 
+static int create_sysfs_interfaces(struct device *dev,
+		struct device_attribute *attributes, int len)
+{
+	int i;
+	int err;
+	for (i = 0; i < len; i++) {
+		err = device_create_file(dev, attributes + i);
+		if (err)
+			goto error;
+	}
+	return 0;
+
+error:
+	for (; i >= 0; i--)
+		device_remove_file(dev, attributes + i);
+	dev_err(dev, "%s:Unable to create interface\n", __func__);
+	return err;
+}
+
+static int remove_sysfs_interfaces(struct device *dev,
+		struct device_attribute *attributes, int len)
+{
+	int i;
+	for (i = 0; i < len; i++)
+		device_remove_file(dev, attributes + i);
+	return 0;
+}
+
+static struct device_attribute light_attr[] = {
+	__ATTR(ls_adc, 0664, ls_adc_show, NULL),
+	__ATTR(ls_kadc, 0664, ls_kadc_show, ls_kadc_store),
+	__ATTR(ls_gadc, 0664, ls_gadc_show, ls_gadc_store),
+	__ATTR(ls_conf, 0664, ls_conf_show, ls_conf_store),
+	__ATTR(ls_adc_table, 0664,
+			ls_adc_table_show, ls_adc_table_store),
+	__ATTR(poll_delay, 0664, ls_poll_delay_show,
+			ls_poll_delay_store),
+	__ATTR(enable, 0664,
+			ls_enable_show, ls_enable_store),
+};
+
+static struct device_attribute proximity_attr[] = {
+	__ATTR(enable, 0664, ps_adc_show, ps_enable_store),
+	__ATTR(ps_parameters, 0664,
+			ps_parameters_show, ps_parameters_store),
+	__ATTR(ps_conf, 0664, ps_conf_show, ps_conf_store),
+	__ATTR(ps_hw, 0664, ps_hw_show, ps_hw_store),
+	__ATTR(ps_thd, 0664, ps_thd_show, ps_thd_store),
+	__ATTR(poll_delay, 0664, ps_poll_delay_show,
+			ps_poll_delay_store),
+	__ATTR(ls_flevel, 0664, ls_fLevel_show, ls_fLevel_store),
+};
+
 static int cm36283_probe(struct i2c_client *client,
 	const struct i2c_device_id *id)
 {
@@ -1658,102 +1631,24 @@
 		goto err_psensor_setup;
 	}
 
-	lpi->cm36283_class = class_create(THIS_MODULE, "optical_sensors");
-	if (IS_ERR(lpi->cm36283_class)) {
-		ret = PTR_ERR(lpi->cm36283_class);
-		lpi->cm36283_class = NULL;
-		goto err_create_class;
+	ret = create_sysfs_interfaces(&lpi->ls_input_dev->dev, light_attr,
+			ARRAY_SIZE(light_attr));
+	if (ret < 0) {
+		dev_err(&client->dev, "failed to create sysfs\n");
+		goto err_input_cleanup;
 	}
 
-	lpi->ls_dev = device_create(lpi->cm36283_class,
-				NULL, 0, "%s", "lightsensor");
-	if (unlikely(IS_ERR(lpi->ls_dev))) {
-		ret = PTR_ERR(lpi->ls_dev);
-		lpi->ls_dev = NULL;
-		goto err_create_ls_device;
+	ret = create_sysfs_interfaces(&lpi->ps_input_dev->dev, proximity_attr,
+			ARRAY_SIZE(proximity_attr));
+	if (ret < 0) {
+		dev_err(&client->dev, "failed to create sysfs\n");
+		goto err_light_sysfs_cleanup;
 	}
 
-	/* register the attributes */
-	ret = device_create_file(lpi->ls_dev, &dev_attr_ls_adc);
-	if (ret)
-		goto err_create_ls_device_file;
 
-	/* register the attributes */
-	ret = device_create_file(lpi->ls_dev, &dev_attr_ls_auto);
-	if (ret)
-		goto err_create_ls_device_file;
-
-	/* register the attributes */
-	ret = device_create_file(lpi->ls_dev, &dev_attr_ls_kadc);
-	if (ret)
-		goto err_create_ls_device_file;
-
-	ret = device_create_file(lpi->ls_dev, &dev_attr_ls_gadc);
-	if (ret)
-		goto err_create_ls_device_file;
-
-	ret = device_create_file(lpi->ls_dev, &dev_attr_ls_adc_table);
-	if (ret)
-		goto err_create_ls_device_file;
-
-	ret = device_create_file(lpi->ls_dev, &dev_attr_ls_conf);
-	if (ret)
-		goto err_create_ls_device_file;
-
-	ret = device_create_file(lpi->ls_dev, &dev_attr_ls_flevel);
-	if (ret)
-		goto err_create_ls_device_file;
-
-	ret = device_create_file(lpi->ls_dev, &dev_attr_ls_poll_delay);
-	if (ret)
-		goto err_create_ls_device_file;
-
-	lpi->ps_dev = device_create(lpi->cm36283_class,
-				NULL, 0, "%s", "proximity");
-	if (unlikely(IS_ERR(lpi->ps_dev))) {
-		ret = PTR_ERR(lpi->ps_dev);
-		lpi->ps_dev = NULL;
-		goto err_create_ps_device;
-	}
-
-	/* register the attributes */
-	ret = device_create_file(lpi->ps_dev, &dev_attr_ps_adc);
-	if (ret)
-		goto err_create_ps_device_file;
-
-	ret = device_create_file(lpi->ps_dev,
-		&dev_attr_ps_parameters);
-	if (ret)
-		goto err_create_ps_device_file;
-
-	/* register the attributes */
-	ret = device_create_file(lpi->ps_dev, &dev_attr_ps_conf);
-	if (ret)
-		goto err_create_ps_device_file;
-
-	/* register the attributes */
-	ret = device_create_file(lpi->ps_dev, &dev_attr_ps_thd);
-	if (ret)
-		goto err_create_ps_device_file;
-
-	ret = device_create_file(lpi->ps_dev, &dev_attr_ps_hw);
-	if (ret)
-		goto err_create_ps_device_file;
-
-	ret = device_create_file(lpi->ps_dev, &dev_attr_ps_poll_delay);
-	if (ret)
-		goto err_create_ps_device_file;
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
-	lpi->early_suspend.level =
-			EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
-	lpi->early_suspend.suspend = cm36283_early_suspend;
-	lpi->early_suspend.resume = cm36283_late_resume;
-	register_early_suspend(&lpi->early_suspend);
-#endif
 	ret = sensors_classdev_register(&client->dev, &sensors_light_cdev);
 	if (ret)
-		goto err_create_ps_device_file;
+		goto err_proximity_sysfs_cleanup;
 
 	ret = sensors_classdev_register(&client->dev, &sensors_proximity_cdev);
 	if (ret)
@@ -1767,19 +1662,16 @@
 	return ret;
 err_create_class_sysfs:
 	sensors_classdev_unregister(&sensors_light_cdev);
-err_create_ps_device_file:
-	device_unregister(lpi->ps_dev);
-err_create_ps_device:
-err_create_ls_device_file:
-	device_unregister(lpi->ls_dev);
-err_create_ls_device:
-	class_destroy(lpi->cm36283_class);
-err_create_class:
-	misc_deregister(&psensor_misc);
+err_proximity_sysfs_cleanup:
+	remove_sysfs_interfaces(&lpi->ps_input_dev->dev, proximity_attr,
+			ARRAY_SIZE(proximity_attr));
+err_light_sysfs_cleanup:
+	remove_sysfs_interfaces(&lpi->ls_input_dev->dev, light_attr,
+			ARRAY_SIZE(light_attr));
+err_input_cleanup:
 	input_unregister_device(lpi->ps_input_dev);
 	input_free_device(lpi->ps_input_dev);
 err_psensor_setup:
-	misc_deregister(&lightsensor_misc);
 	input_unregister_device(lpi->ls_input_dev);
 	input_free_device(lpi->ls_input_dev);
 err_lightsensor_setup:
diff --git a/drivers/input/misc/kxtj9.c b/drivers/input/misc/kxtj9.c
index f5d8441..0883ac5 100644
--- a/drivers/input/misc/kxtj9.c
+++ b/drivers/input/misc/kxtj9.c
@@ -90,9 +90,13 @@
 	.max_range = "19.6",
 	.resolution = "0.01",
 	.sensor_power = "0.2",
-	.min_delay = 2000,
+	.min_delay = 2000,	/* microsecond */
 	.fifo_reserved_event_count = 0,
 	.fifo_max_event_count = 0,
+	.enabled = 0,
+	.delay_msec = 200,	/* millisecond */
+	.sensors_enable = NULL,
+	.sensors_poll_delay = NULL,
 };
 
 static const struct {
@@ -124,6 +128,7 @@
 	bool	power_enabled;
 	struct regulator *vdd;
 	struct regulator *vio;
+	struct sensors_classdev cdev;
 };
 
 static int kxtj9_i2c_read(struct kxtj9_data *tj9, u8 addr, u8 *data, int len)
@@ -486,6 +491,36 @@
 	return 0;
 }
 
+static int kxtj9_enable_set(struct sensors_classdev *sensors_cdev,
+					unsigned int enabled)
+{
+	struct kxtj9_data *tj9 = container_of(sensors_cdev,
+					struct kxtj9_data, cdev);
+	struct input_dev *input_dev = tj9->input_dev;
+
+	mutex_lock(&input_dev->mutex);
+
+	if (enabled == 0) {
+		disable_irq(tj9->client->irq);
+		kxtj9_disable(tj9);
+		tj9->enable = false;
+	} else if (enabled == 1) {
+		if (!kxtj9_enable(tj9)) {
+			enable_irq(tj9->client->irq);
+			tj9->enable = true;
+		}
+	} else {
+		dev_err(&tj9->client->dev,
+			"Invalid value of input, input=%d\n", enabled);
+		mutex_unlock(&input_dev->mutex);
+		return -EINVAL;
+	}
+
+	mutex_unlock(&input_dev->mutex);
+
+	return 0;
+}
+
 static ssize_t kxtj9_enable_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
@@ -501,31 +536,16 @@
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct kxtj9_data *tj9 = i2c_get_clientdata(client);
-	struct input_dev *input_dev = tj9->input_dev;
 	unsigned long data;
 	int error;
 
 	error = kstrtoul(buf, 10, &data);
-	if (error)
+	if (error < 0)
 		return error;
-	mutex_lock(&input_dev->mutex);
 
-	if (data == 0) {
-		disable_irq(client->irq);
-		kxtj9_disable(tj9);
-		tj9->enable = false;
-	} else if (data == 1) {
-		if (!kxtj9_enable(tj9)) {
-			enable_irq(client->irq);
-			tj9->enable = true;
-		}
-	} else {
-		dev_err(&tj9->client->dev,
-			"Invalid value of input, input=%ld\n", data);
-	}
-
-	mutex_unlock(&input_dev->mutex);
-
+	error = kxtj9_enable_set(&tj9->cdev, data);
+	if (error < 0)
+		return error;
 	return count;
 }
 
@@ -542,6 +562,29 @@
  * will be responsible for retrieving data from the input node at the desired
  * interval.
  */
+static int kxtj9_poll_delay_set(struct sensors_classdev *sensors_cdev,
+					unsigned int delay_msec)
+{
+	struct kxtj9_data *tj9 = container_of(sensors_cdev,
+					struct kxtj9_data, cdev);
+	struct input_dev *input_dev = tj9->input_dev;
+
+	/* Lock the device to prevent races with open/close (and itself) */
+	mutex_lock(&input_dev->mutex);
+
+	if (tj9->enable)
+		disable_irq(tj9->client->irq);
+
+	tj9->last_poll_interval = max(delay_msec, tj9->pdata.min_interval);
+
+	if (tj9->enable) {
+		kxtj9_update_odr(tj9, tj9->last_poll_interval);
+		enable_irq(tj9->client->irq);
+	}
+	mutex_unlock(&input_dev->mutex);
+
+	return 0;
+}
 
 /* Returns currently selected poll interval (in ms) */
 static ssize_t kxtj9_get_poll_delay(struct device *dev,
@@ -560,7 +603,6 @@
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct kxtj9_data *tj9 = i2c_get_clientdata(client);
-	struct input_dev *input_dev = tj9->input_dev;
 	unsigned int interval;
 	int error;
 
@@ -568,24 +610,9 @@
 	if (error < 0)
 		return error;
 
-	/* Lock the device to prevent races with open/close (and itself) */
-	mutex_lock(&input_dev->mutex);
-
-	if (tj9->enable)
-		disable_irq(client->irq);
-
-	/*
-	 * Set current interval to the greater of the minimum interval or
-	 * the requested interval
-	 */
-	tj9->last_poll_interval = max(interval, tj9->pdata.min_interval);
-
-	if (tj9->enable) {
-		kxtj9_update_odr(tj9, tj9->last_poll_interval);
-		enable_irq(client->irq);
-	}
-	mutex_unlock(&input_dev->mutex);
-
+	error = kxtj9_poll_delay_set(&tj9->cdev, interval);
+	if (error < 0)
+		return error;
 	return count;
 }
 
@@ -602,7 +629,6 @@
 	.attrs = kxtj9_attributes
 };
 
-
 #ifdef CONFIG_INPUT_KXTJ9_POLLED_MODE
 static void kxtj9_poll(struct input_polled_dev *dev)
 {
@@ -858,7 +884,13 @@
 	tj9->ctrl_reg1 = tj9->pdata.res_ctl | tj9->pdata.g_range;
 	tj9->last_poll_interval = tj9->pdata.init_interval;
 
-	err = sensors_classdev_register(&client->dev, &sensors_cdev);
+	tj9->cdev = sensors_cdev;
+	/* The min_delay is used by userspace and the unit is microsecond. */
+	tj9->cdev.min_delay = tj9->pdata.min_interval * 1000;
+	tj9->cdev.delay_msec = tj9->pdata.init_interval;
+	tj9->cdev.sensors_enable = kxtj9_enable_set;
+	tj9->cdev.sensors_poll_delay = kxtj9_poll_delay_set;
+	err = sensors_classdev_register(&client->dev, &tj9->cdev);
 	if (err) {
 		dev_err(&client->dev, "class device create failed: %d\n", err);
 		goto err_power_off;
@@ -871,7 +903,7 @@
 
 		err = kxtj9_setup_input_device(tj9);
 		if (err)
-			goto err_power_off;
+			goto err_class_sysfs;
 
 		err = request_threaded_irq(client->irq, NULL, kxtj9_isr,
 					   IRQF_TRIGGER_RISING | IRQF_ONESHOT,
@@ -892,7 +924,7 @@
 	} else {
 		err = kxtj9_setup_polled_device(tj9);
 		if (err)
-			goto err_power_off;
+			goto err_class_sysfs;
 	}
 
 	dev_dbg(&client->dev, "%s: kxtj9_probe OK.\n", __func__);
@@ -903,6 +935,8 @@
 	free_irq(client->irq, tj9);
 err_destroy_input:
 	input_unregister_device(tj9->input_dev);
+err_class_sysfs:
+	sensors_classdev_unregister(&tj9->cdev);
 err_power_off:
 	kxtj9_device_power_off(tj9);
 err_power_deinit:
diff --git a/drivers/input/misc/mma8x5x.c b/drivers/input/misc/mma8x5x.c
index d5053eb..0fc5693 100644
--- a/drivers/input/misc/mma8x5x.c
+++ b/drivers/input/misc/mma8x5x.c
@@ -2,7 +2,7 @@
  *  mma8x5x.c - Linux kernel modules for 3-Axis Orientation/Motion
  *  Detection Sensor MMA8451/MMA8452/MMA8453
  *
- *  Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
+ *  Copyright (c) 2013-2014, The Linux Foundation. All Rights Reserved.
  *  Linux Foundation chooses to take subject only to the GPLv2 license
  *  terms, and distributes only under these terms.
  *  Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
@@ -38,10 +38,10 @@
 #define MMA8652_ID			0x4A
 #define MMA8653_ID			0x5A
 
-
+/* Polling delay in msecs */
 #define POLL_INTERVAL_MIN	1
-#define POLL_INTERVAL_MAX	500
-#define POLL_INTERVAL		100 /* msecs */
+#define POLL_INTERVAL_MAX	10000
+#define POLL_INTERVAL		100
 
 /* if sensor is standby ,set POLL_STOP_TIME to slow down the poll */
 #define POLL_STOP_TIME		10000
@@ -68,6 +68,10 @@
 	.min_delay = 2000,
 	.fifo_reserved_event_count = 0,
 	.fifo_max_event_count = 0,
+	.enabled = 0,
+	.delay_msec = POLL_INTERVAL,
+	.sensors_enable = NULL,
+	.sensors_poll_delay = NULL,
 };
 
 struct sensor_regulator {
@@ -162,12 +166,14 @@
 	struct i2c_client *client;
 	struct input_polled_dev *poll_dev;
 	struct mutex data_lock;
+	struct sensors_classdev cdev;
 	int active;
 	int position;
 	u8 chip_id;
 	int mode;
 	int int_pin;
 	u32 int_flags;
+	int poll_delay;
 };
 /* Addresses scanned */
 static const unsigned short normal_i2c[] = {0x1c, 0x1d, I2C_CLIENT_END};
@@ -371,7 +377,7 @@
 		goto out;
 	} else {
 		if (poll_dev->poll_interval == POLL_STOP_TIME)
-			poll_dev->poll_interval = POLL_INTERVAL;
+			poll_dev->poll_interval = pdata->poll_delay;
 	}
 	if (mma8x5x_read_data(pdata->client, &data) != 0)
 		goto out;
@@ -390,6 +396,79 @@
 	mma8x5x_report_data(pdata);
 }
 
+static int mma8x5x_enable_set(struct sensors_classdev *sensors_cdev,
+		unsigned int enable)
+{
+	struct mma8x5x_data *pdata = container_of(sensors_cdev,
+			struct mma8x5x_data, cdev);
+	struct i2c_client *client = pdata->client;
+	int ret;
+	u8 val = 0;
+
+	mutex_lock(&pdata->data_lock);
+	if (enable) {
+		if (pdata->active & MMA_SHUTTEDDOWN) {
+			ret = mma8x5x_config_regulator(client, 1);
+			if (ret)
+				goto err_failed;
+
+			ret = mma8x5x_device_start(client);
+			if (ret)
+				goto err_failed;
+
+			pdata->active &= ~MMA_SHUTTEDDOWN;
+		}
+		if (pdata->active == MMA_STANDBY) {
+			val = i2c_smbus_read_byte_data(client,
+					MMA8X5X_CTRL_REG1);
+			if (val < 0) {
+				dev_err(&client->dev, "read device state failed!");
+				ret = val;
+				goto err_failed;
+			}
+
+			ret = i2c_smbus_write_byte_data(client,
+					MMA8X5X_CTRL_REG1, val | 0x01);
+			if (ret) {
+				dev_err(&client->dev, "change device state failed!");
+				goto err_failed;
+			}
+			pdata->active = MMA_ACTIVED;
+			dev_dbg(&client->dev, "%s:mma enable setting active.\n",
+					__func__);
+		}
+	} else if (enable == 0) {
+		if (pdata->active == MMA_ACTIVED) {
+			val = i2c_smbus_read_byte_data(client,
+					MMA8X5X_CTRL_REG1);
+			if (val < 0) {
+				dev_err(&client->dev, "read device state failed!");
+				ret = val;
+				goto err_failed;
+			}
+
+			ret = i2c_smbus_write_byte_data(client,
+				MMA8X5X_CTRL_REG1, val & 0xFE);
+			if (ret) {
+				dev_err(&client->dev, "change device state failed!");
+				goto err_failed;
+			}
+
+			pdata->active = MMA_STANDBY;
+			dev_dbg(&client->dev, "%s:mma enable setting inactive.\n",
+					__func__);
+		}
+		if (!mma8x5x_config_regulator(client, 0))
+			pdata->active |= MMA_SHUTTEDDOWN;
+	}
+	mutex_unlock(&pdata->data_lock);
+	return 0;
+
+err_failed:
+	mutex_unlock(&pdata->data_lock);
+	return ret;
+}
+
 static ssize_t mma8x5x_enable_show(struct device *dev,
 				   struct device_attribute *attr, char *buf)
 {
@@ -415,77 +494,17 @@
 {
 	struct input_polled_dev *poll_dev = dev_get_drvdata(dev);
 	struct mma8x5x_data *pdata = (struct mma8x5x_data *)(poll_dev->private);
-	struct i2c_client *client = pdata->client;
 	int ret;
 	unsigned long enable;
-	u8 val = 0;
 
 	ret = kstrtoul(buf, 10, &enable);
 	if (ret)
 		return ret;
-	mutex_lock(&pdata->data_lock);
 	enable = (enable > 0) ? 1 : 0;
-	if (enable) {
-		if (pdata->active & MMA_SHUTTEDDOWN) {
-			ret = mma8x5x_config_regulator(client, 1);
-			if (ret)
-				goto err_failed;
-
-			ret = mma8x5x_device_start(client);
-			if (ret)
-				goto err_failed;
-
-			pdata->active &= ~MMA_SHUTTEDDOWN;
-		}
-		if (pdata->active == MMA_STANDBY) {
-			val = i2c_smbus_read_byte_data(client,
-					MMA8X5X_CTRL_REG1);
-			if (val < 0) {
-				dev_err(dev, "read device state failed!");
-				ret = val;
-				goto err_failed;
-			}
-
-			ret = i2c_smbus_write_byte_data(client,
-					MMA8X5X_CTRL_REG1, val | 0x01);
-			if (ret) {
-				dev_err(dev, "change device state failed!");
-				goto err_failed;
-			}
-			pdata->active = MMA_ACTIVED;
-			dev_dbg(dev, "%s:mma enable setting active.\n",
-					__func__);
-		}
-	} else if (enable == 0) {
-		if (pdata->active == MMA_ACTIVED) {
-			val = i2c_smbus_read_byte_data(client,
-					MMA8X5X_CTRL_REG1);
-			if (val < 0) {
-				dev_err(dev, "read device state failed!");
-				ret = val;
-				goto err_failed;
-			}
-
-			ret = i2c_smbus_write_byte_data(client,
-				MMA8X5X_CTRL_REG1, val & 0xFE);
-			if (ret) {
-				dev_err(dev, "change device state failed!");
-				goto err_failed;
-			}
-
-			pdata->active = MMA_STANDBY;
-			dev_dbg(dev, "%s:mma enable setting inactive.\n",
-					__func__);
-		}
-		if (!mma8x5x_config_regulator(client, 0))
-			pdata->active |= MMA_SHUTTEDDOWN;
-	}
-	mutex_unlock(&pdata->data_lock);
+	ret = mma8x5x_enable_set(&pdata->cdev, enable);
+	if (ret < 0)
+		return ret;
 	return count;
-
-err_failed:
-	mutex_unlock(&pdata->data_lock);
-	return ret;
 }
 static ssize_t mma8x5x_position_show(struct device *dev,
 				   struct device_attribute *attr, char *buf)
@@ -516,14 +535,60 @@
 	return count;
 }
 
+static int mma8x5x_poll_delay_set(struct sensors_classdev *sensors_cdev,
+		unsigned int delay_ms)
+{
+	struct mma8x5x_data *pdata = container_of(sensors_cdev,
+			struct mma8x5x_data, cdev);
+
+	mutex_lock(&pdata->data_lock);
+	pdata->poll_delay = delay_ms;
+	pdata->poll_dev->poll_interval = pdata->poll_delay;
+	mutex_unlock(&pdata->data_lock);
+
+	return 0;
+}
+
+static ssize_t mma8x5x_poll_delay_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct input_polled_dev *poll_dev = dev_get_drvdata(dev);
+	struct mma8x5x_data *pdata = (struct mma8x5x_data *)(poll_dev->private);
+	return snprintf(buf, PAGE_SIZE, "%d\n", pdata->poll_delay);
+}
+
+static ssize_t mma8x5x_poll_delay_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	struct input_polled_dev *poll_dev = dev_get_drvdata(dev);
+	struct mma8x5x_data *pdata = (struct mma8x5x_data *)(poll_dev->private);
+	int interval;
+	int ret;
+	ret = kstrtoint(buf, 10, &interval);
+	if (ret)
+		return ret;
+	if (interval <= POLL_INTERVAL_MIN)
+		interval = POLL_INTERVAL_MIN;
+	if (interval > POLL_INTERVAL_MAX)
+		interval = POLL_INTERVAL_MAX;
+
+	mma8x5x_poll_delay_set(&pdata->cdev, interval);
+
+	return count;
+}
+
 static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
 		   mma8x5x_enable_show, mma8x5x_enable_store);
 static DEVICE_ATTR(position, S_IWUSR | S_IRUGO,
 		   mma8x5x_position_show, mma8x5x_position_store);
+static DEVICE_ATTR(poll_delay, S_IWUSR | S_IRUGO,
+		   mma8x5x_poll_delay_show, mma8x5x_poll_delay_store);
 
 static struct attribute *mma8x5x_attributes[] = {
 	&dev_attr_enable.attr,
 	&dev_attr_position.attr,
+	&dev_attr_poll_delay.attr,
 	NULL
 };
 
@@ -622,6 +687,7 @@
 	pdata->client = client;
 	pdata->chip_id = chip_id;
 	pdata->mode = MODE_2G;
+	pdata->poll_delay = POLL_INTERVAL;
 
 	mutex_init(&pdata->data_lock);
 	i2c_set_clientdata(client, pdata);
@@ -659,7 +725,12 @@
 		result = -EINVAL;
 		goto err_create_sysfs;
 	}
-	result = sensors_classdev_register(&client->dev, &sensors_cdev);
+	pdata->cdev = sensors_cdev;
+	pdata->cdev.min_delay = POLL_INTERVAL_MIN * 1000;
+	pdata->cdev.delay_msec = poll_dev->poll_interval;
+	pdata->cdev.sensors_enable = mma8x5x_enable_set;
+	pdata->cdev.sensors_poll_delay = mma8x5x_poll_delay_set;
+	result = sensors_classdev_register(&client->dev, &pdata->cdev);
 	if (result) {
 		dev_err(&client->dev, "create class device file failed!\n");
 		result = -EINVAL;
diff --git a/drivers/input/misc/mpu3050.c b/drivers/input/misc/mpu3050.c
index 3b7bf5a..039e078 100644
--- a/drivers/input/misc/mpu3050.c
+++ b/drivers/input/misc/mpu3050.c
@@ -122,6 +122,7 @@
 	struct input_dev *idev;
 	struct mpu3050_gyro_platform_data *platform_data;
 	struct delayed_work input_work;
+	struct sensors_classdev cdev;
 	u32    use_poll;
 	u32    poll_interval;
 	u32    dlpf_index;
@@ -141,6 +142,10 @@
 	.min_delay = 2000,
 	.fifo_reserved_event_count = 0,
 	.fifo_max_event_count = 0,
+	.enabled = 0,
+	.delay_msec = MPU3050_DEFAULT_POLL_INTERVAL,
+	.sensors_enable = NULL,
+	.sensors_poll_delay = NULL,
 };
 
 struct sensor_regulator {
@@ -258,6 +263,40 @@
 	return rc;
 }
 
+static int mpu3050_poll_delay_set(struct sensors_classdev *sensors_cdev,
+		unsigned int delay_msec)
+{
+	struct mpu3050_sensor *sensor = container_of(sensors_cdev,
+			struct mpu3050_sensor, cdev);
+	unsigned int  dlpf_index;
+	u8  divider, reg;
+	int ret;
+
+	dlpf_index = interval_to_dlpf_cfg(delay_msec);
+	divider = delay_msec * dlpf_table[dlpf_index].sample_rate - 1;
+
+	if (sensor->dlpf_index != dlpf_index) {
+		/* Set low pass filter and full scale */
+		reg = dlpf_table[dlpf_index].cfg;
+		reg |= MPU3050_DEFAULT_FS_RANGE << 3;
+		reg |= MPU3050_EXT_SYNC_NONE << 5;
+		ret = i2c_smbus_write_byte_data(sensor->client,
+				MPU3050_DLPF_FS_SYNC, reg);
+		if (!ret)
+			sensor->dlpf_index = dlpf_index;
+	}
+
+	if (sensor->poll_interval != delay_msec) {
+		/* Output frequency divider. The poll interval */
+		ret = i2c_smbus_write_byte_data(sensor->client,
+				MPU3050_SMPLRT_DIV, divider);
+		if (!ret)
+			sensor->poll_interval = delay_msec;
+	}
+
+	return 0;
+}
+
 /**
  *	mpu3050_attr_get_polling_rate	-	get the sampling rate
  */
@@ -280,8 +319,6 @@
 {
 	struct mpu3050_sensor *sensor = dev_get_drvdata(dev);
 	unsigned long interval_ms;
-	unsigned int  dlpf_index;
-	u8  divider, reg;
 	int ret;
 
 	if (kstrtoul(buf, 10, &interval_ms))
@@ -290,29 +327,39 @@
 		(interval_ms > MPU3050_MAX_POLL_INTERVAL))
 		return -EINVAL;
 
-	dlpf_index = interval_to_dlpf_cfg(interval_ms);
-	divider = interval_ms * dlpf_table[dlpf_index].sample_rate - 1;
+	ret = mpu3050_poll_delay_set(&sensor->cdev, interval_ms);
 
-	if (sensor->dlpf_index != dlpf_index) {
-		/* Set low pass filter and full scale */
-		reg = dlpf_table[dlpf_index].cfg;
-		reg |= MPU3050_DEFAULT_FS_RANGE << 3;
-		reg |= MPU3050_EXT_SYNC_NONE << 5;
-		ret = i2c_smbus_write_byte_data(sensor->client,
-				MPU3050_DLPF_FS_SYNC, reg);
-		if (ret == 0)
-			sensor->dlpf_index = dlpf_index;
+	return ret < 0 ? ret : size;
+}
+static int mpu3050_enable_set(struct sensors_classdev *sensors_cdev,
+		unsigned int enabled)
+{
+	struct mpu3050_sensor *sensor = container_of(sensors_cdev,
+			struct mpu3050_sensor, cdev);
+
+
+	if (enabled && (!sensor->enable)) {
+		sensor->enable = enabled;
+		pm_runtime_get_sync(sensor->dev);
+		if (sensor->use_poll)
+			schedule_delayed_work(&sensor->input_work,
+				msecs_to_jiffies(sensor->poll_interval));
+		else
+			enable_irq(sensor->client->irq);
+	} else if (!enabled && sensor->enable) {
+		if (sensor->use_poll)
+			cancel_delayed_work_sync(&sensor->input_work);
+		else
+			disable_irq(sensor->client->irq);
+		pm_runtime_put_sync(sensor->dev);
+		sensor->enable = enabled;
+	} else {
+		dev_warn(&sensor->client->dev,
+				"ignore enable state change from %d to %d\n",
+				sensor->enable, enabled);
 	}
 
-	if (sensor->poll_interval != interval_ms) {
-		/* Output frequency divider. The poll interval */
-		ret = i2c_smbus_write_byte_data(sensor->client,
-				MPU3050_SMPLRT_DIV, divider);
-		if (ret == 0)
-			sensor->poll_interval = interval_ms;
-	}
-
-	return size;
+	return 0;
 }
 
 /**
@@ -325,32 +372,14 @@
 {
 	struct mpu3050_sensor *sensor = dev_get_drvdata(dev);
 	unsigned long val;
+	int err;
 
 	if (kstrtoul(buf, 10, &val))
 		return -EINVAL;
-	sensor->enable = (u32)val == 0 ? 0 : 1;
-	if (sensor->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);
-			enable_irq(sensor->client->irq);
-		}
-	} else {
-		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);
-	}
+	err = mpu3050_enable_set(&sensor->cdev, val);
+	if (err < 0)
+		return err;
+
 	return count;
 }
 
@@ -485,54 +514,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 +569,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 +599,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
@@ -723,6 +708,19 @@
 		sensor->enable_gpio = -EINVAL;
 	}
 
+	sensor->cdev = sensors_cdev;
+	sensor->cdev.min_delay = MPU3050_MIN_POLL_INTERVAL;
+	sensor->cdev.delay_msec = sensor->poll_interval;
+	sensor->cdev.sensors_enable = mpu3050_enable_set;
+	sensor->cdev.sensors_poll_delay = mpu3050_poll_delay_set;
+	ret = sensors_classdev_register(&client->dev, &sensor->cdev);
+
+	if (ret) {
+		dev_err(&client->dev, "class device create failed: %d\n", ret);
+		error = -EINVAL;
+		goto err_free_mem;
+	}
+
 	if (gpio_is_valid(sensor->enable_gpio)) {
 		ret = gpio_request(sensor->enable_gpio, "GYRO_EN_PM");
 		gpio_direction_output(sensor->enable_gpio, 1);
@@ -734,7 +732,7 @@
 	if (ret < 0) {
 		dev_err(&client->dev, "failed to detect device\n");
 		error = -ENXIO;
-		goto err_free_mem;
+		goto err_class_sysfs;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(mpu3050_chip_ids); i++)
@@ -744,15 +742,12 @@
 	if (i == ARRAY_SIZE(mpu3050_chip_ids)) {
 		dev_err(&client->dev, "unsupported chip id\n");
 		error = -ENXIO;
-		goto err_free_mem;
+		goto err_class_sysfs;
 	}
 
 	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,22 +808,19 @@
 		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");
 		goto err_free_irq;
 	}
 
-	error = sensors_classdev_register(&client->dev, &sensors_cdev);
-	if (error < 0) {
-		dev_err(&client->dev, "failed to create class device\n");
-		goto err_input_cleanup;
-	}
-
 	error = create_sysfs_interfaces(&idev->dev);
 	if (error < 0) {
 		dev_err(&client->dev, "failed to create sysfs\n");
-		goto err_class_sysfs;
+		goto err_input_cleanup;
 	}
 
 	pm_runtime_enable(&client->dev);
@@ -836,8 +828,6 @@
 
 	return 0;
 
-err_class_sysfs:
-	sensors_classdev_unregister(&sensors_cdev);
 err_input_cleanup:
 	input_unregister_device(idev);
 err_free_irq:
@@ -849,6 +839,8 @@
 		gpio_free(sensor->platform_data->gpio_int);
 err_pm_set_suspended:
 	pm_runtime_set_suspended(&client->dev);
+err_class_sysfs:
+	sensors_classdev_unregister(&sensor->cdev);
 err_free_mem:
 	input_free_device(idev);
 	kfree(sensor);
@@ -893,10 +885,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 +905,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/misc/stk3x1x.c b/drivers/input/misc/stk3x1x.c
index f1b060e..f9d3478 100644
--- a/drivers/input/misc/stk3x1x.c
+++ b/drivers/input/misc/stk3x1x.c
@@ -64,8 +64,6 @@
 #define STK_POLL_PS
 #define STK_POLL_ALS		/* ALS interrupt is valid only when STK_PS_INT_MODE = 1	or 4*/
 
-#define STK_DEBUG_PRINTF
-
 /* Define Register Map */
 #define STK_STATE_REG 			0x00
 #define STK_PSCTRL_REG 			0x01
@@ -192,9 +190,13 @@
 	.max_range = "6500",
 	.resolution = "0.0625",
 	.sensor_power = "0.09",
-	.min_delay = 0,
+	.min_delay = (MIN_ALS_POLL_DELAY_NS / 1000),	/* us */
 	.fifo_reserved_event_count = 0,
 	.fifo_max_event_count = 0,
+	.enabled = 0,
+	.delay_msec = 200,
+	.sensors_enable = NULL,
+	.sensors_poll_delay = NULL,
 };
 
 static struct sensors_classdev sensors_proximity_cdev = {
@@ -209,6 +211,10 @@
 	.min_delay = 0,
 	.fifo_reserved_event_count = 0,
 	.fifo_max_event_count = 0,
+	.enabled = 0,
+	.delay_msec = 200,
+	.sensors_enable = NULL,
+	.sensors_poll_delay = NULL,
 };
 
 struct data_filter {
@@ -221,6 +227,8 @@
 struct stk3x1x_data {
 	struct i2c_client *client;
 	struct stk3x1x_platform_data *pdata;
+	struct sensors_classdev als_cdev;
+	struct sensors_classdev ps_cdev;
 #if (!defined(STK_POLL_PS) || !defined(STK_POLL_ALS))
     int32_t irq;
     struct work_struct stk_work;
@@ -238,7 +246,7 @@
 	int32_t ps_distance_last;
 	bool ps_enabled;
 	struct wake_lock ps_wakelock;
-    struct work_struct stk_ps_work;
+	struct work_struct stk_ps_work;
 	struct workqueue_struct *stk_ps_wq;
 #ifdef STK_POLL_PS
 	struct wake_lock ps_nosuspend_wl;
@@ -321,11 +329,11 @@
     for (i=1,j=0;i<LUX_THD_TABLE_SIZE;i++,j++)
     {
         alscode = stk_lux2alscode(ps_data, lux_threshold_table[j]);
-        printk(KERN_INFO "alscode[%d]=%d\n",i,alscode);
+		dev_dbg(&ps_data->client->dev, "alscode[%d]=%d\n", i, alscode);
         code_threshold_table[i] = (uint16_t)(alscode);
     }
     code_threshold_table[i] = 0xffff;
-    printk(KERN_INFO "alscode[%d]=%d\n",i,alscode);
+	dev_dbg(&ps_data->client->dev, "alscode[%d]=%d\n", i, alscode);
 }
 
 static uint32_t stk_get_lux_interval_index(uint16_t alscode)
@@ -458,7 +466,6 @@
         printk(KERN_ERR "%s: read i2c error, err=%d\n", __func__, err2);
         return -1;
     }
-	printk(KERN_INFO "%s: PID=0x%x, RID=0x%x\n", __func__, err1, err2);
 	if(err2 == 0xC0)
 		printk(KERN_INFO "%s: RID=0xC0!!!!!!!!!!!!!\n", __func__);
 
@@ -685,7 +692,9 @@
 		input_sync(ps_data->ps_input_dev);
 		wake_lock_timeout(&ps_data->ps_wakelock, 3*HZ);
 		reading = stk3x1x_get_ps_reading(ps_data);
-		printk(KERN_INFO "%s: ps input event=%d, ps code = %d\n",__func__, near_far_state, reading);
+		dev_dbg(&ps_data->client->dev,
+			"%s: ps input event=%d, ps code = %d\n",
+			__func__, near_far_state, reading);
 #endif	/* #ifndef STK_POLL_PS */
 	}
 	else
@@ -904,6 +913,21 @@
     return scnprintf(buf, PAGE_SIZE, "%d\n", reading);
 }
 
+static ssize_t stk_als_enable_set(struct sensors_classdev *sensors_cdev,
+						unsigned int enabled)
+{
+	struct stk3x1x_data *als_data = container_of(sensors_cdev,
+						struct stk3x1x_data, als_cdev);
+	int err;
+
+	mutex_lock(&als_data->io_lock);
+	err = stk3x1x_enable_als(als_data, enabled);
+	mutex_unlock(&als_data->io_lock);
+
+	if (err < 0)
+		return err;
+	return 0;
+}
 
 static ssize_t stk_als_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -935,7 +959,7 @@
 		printk(KERN_ERR "%s, invalid value %d\n", __func__, *buf);
 		return -EINVAL;
 	}
-    printk(KERN_INFO "%s: Enable ALS : %d\n", __func__, en);
+	dev_dbg(dev, "%s: Enable ALS : %d\n", __func__, en);
     mutex_lock(&ps_data->io_lock);
     stk3x1x_enable_als(ps_data, en);
     mutex_unlock(&ps_data->io_lock);
@@ -971,7 +995,7 @@
 	input_report_abs(ps_data->als_input_dev, ABS_MISC, value);
 	input_sync(ps_data->als_input_dev);
 	mutex_unlock(&ps_data->io_lock);
-	printk(KERN_INFO "%s: als input event %ld lux\n",__func__, value);
+	dev_dbg(dev, "%s: als input event %ld lux\n", __func__, value);
 
     return size;
 }
@@ -1009,7 +1033,8 @@
 static ssize_t stk_als_delay_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct stk3x1x_data *ps_data =  dev_get_drvdata(dev);
-	return scnprintf(buf, PAGE_SIZE, "%lld\n", ktime_to_ns(ps_data->als_poll_delay));
+	return scnprintf(buf, PAGE_SIZE, "%u\n",
+			(u32)ktime_to_ms(ps_data->als_poll_delay));
 }
 
 static inline void stk_als_delay_store_fir(struct stk3x1x_data *ps_data)
@@ -1018,34 +1043,48 @@
 	ps_data->fir.idx = 0;
 	ps_data->fir.sum = 0;
 }
+
+static ssize_t stk_als_poll_delay_set(struct sensors_classdev *sensors_cdev,
+						unsigned int delay_msec)
+{
+	struct stk3x1x_data *als_data = container_of(sensors_cdev,
+						struct stk3x1x_data, als_cdev);
+	uint64_t value = 0;
+
+	value = delay_msec * 1000000;
+
+	if (value < MIN_ALS_POLL_DELAY_NS)
+		value = MIN_ALS_POLL_DELAY_NS;
+
+	mutex_lock(&als_data->io_lock);
+	if (value != ktime_to_ns(als_data->als_poll_delay))
+		als_data->als_poll_delay = ns_to_ktime(value);
+
+	if (als_data->use_fir)
+		stk_als_delay_store_fir(als_data);
+
+	mutex_unlock(&als_data->io_lock);
+
+	return 0;
+}
+
 static ssize_t stk_als_delay_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
 {
     uint64_t value = 0;
 	int ret;
-	struct stk3x1x_data *ps_data =  dev_get_drvdata(dev);
+	struct stk3x1x_data *als_data =  dev_get_drvdata(dev);
 	ret = kstrtoull(buf, 10, &value);
 	if(ret < 0)
 	{
-		printk(KERN_ERR "%s:kstrtoull failed, ret=0x%x\n",
-			__func__, ret);
+		dev_err(dev, "%s:kstrtoull failed, ret=0x%x\n",	__func__, ret);
 		return ret;
 	}
 #ifdef STK_DEBUG_PRINTF
-	printk(KERN_INFO "%s: set als poll delay=%lld\n", __func__, value);
+	dev_dbg(dev, "%s: set als poll delay=%lld\n", __func__, value);
 #endif
-	if(value < MIN_ALS_POLL_DELAY_NS)
-	{
-		printk(KERN_ERR "%s: delay is too small\n", __func__);
-		value = MIN_ALS_POLL_DELAY_NS;
-	}
-	mutex_lock(&ps_data->io_lock);
-	if(value != ktime_to_ns(ps_data->als_poll_delay))
-		ps_data->als_poll_delay = ns_to_ktime(value);
-
-	if (ps_data->use_fir)
-		stk_als_delay_store_fir(ps_data);
-
-	mutex_unlock(&ps_data->io_lock);
+	ret = stk_als_poll_delay_set(&als_data->als_cdev, value);
+	if (ret < 0)
+		return ret;
 	return size;
 }
 
@@ -1136,6 +1175,22 @@
     return scnprintf(buf, PAGE_SIZE, "%d\n", reading);
 }
 
+static ssize_t stk_ps_enable_set(struct sensors_classdev *sensors_cdev,
+						unsigned int enabled)
+{
+	struct stk3x1x_data *ps_data = container_of(sensors_cdev,
+						struct stk3x1x_data, ps_cdev);
+	int err;
+
+	mutex_lock(&ps_data->io_lock);
+	err = stk3x1x_enable_ps(ps_data, enabled);
+	mutex_unlock(&ps_data->io_lock);
+
+	if (err < 0)
+		return err;
+	return 0;
+}
+
 static ssize_t stk_ps_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
     int32_t enable, ret;
@@ -1166,7 +1221,7 @@
 		printk(KERN_ERR "%s, invalid value %d\n", __func__, *buf);
 		return -EINVAL;
 	}
-    printk(KERN_INFO "%s: Enable PS : %d\n", __func__, en);
+	dev_dbg(dev, "%s: Enable PS : %d\n", __func__, en);
     mutex_lock(&ps_data->io_lock);
     stk3x1x_enable_ps(ps_data, en);
     mutex_unlock(&ps_data->io_lock);
@@ -1200,7 +1255,7 @@
 		printk(KERN_ERR "%s, invalid value %d\n", __func__, *buf);
 		return -EINVAL;
 	}
-    printk(KERN_INFO "%s: Enable PS ASO : %d\n", __func__, en);
+	dev_dbg(dev, "%s: Enable PS ASO : %d\n", __func__, en);
 
     ret = i2c_smbus_read_byte_data(ps_data->client, STK_STATE_REG);
     if (ret < 0)
@@ -1288,7 +1343,7 @@
 	input_sync(ps_data->ps_input_dev);
     mutex_unlock(&ps_data->io_lock);
 	wake_lock_timeout(&ps_data->ps_wakelock, 3*HZ);
-	printk(KERN_INFO "%s: ps input event %d cm\n",__func__, dist);
+	dev_dbg(dev, "%s: ps input event %d cm\n", __func__, dist);
     return scnprintf(buf, PAGE_SIZE, "%d\n", dist);
 }
 
@@ -1311,7 +1366,7 @@
 	input_sync(ps_data->ps_input_dev);
     mutex_unlock(&ps_data->io_lock);
 	wake_lock_timeout(&ps_data->ps_wakelock, 3*HZ);
-	printk(KERN_INFO "%s: ps input event %ld cm\n",__func__, value);
+	dev_dbg(dev, "%s: ps input event %ld cm\n", __func__, value);
     return size;
 }
 
@@ -1507,7 +1562,7 @@
 		}
 		else
 		{
-			printk(KERN_INFO "reg[0x%2X]=0x%2X\n", cnt, ps_reg[cnt]);
+			dev_dbg(dev, "reg[0x%2X]=0x%2X\n", cnt, ps_reg[cnt]);
 		}
 	}
 	ps_reg[cnt] = i2c_smbus_read_byte_data(ps_data->client, STK_PDT_ID_REG);
@@ -1517,7 +1572,7 @@
 		printk( KERN_ERR "all_reg_show:i2c_smbus_read_byte_data fail, ret=%d", ps_reg[cnt]);
 		return -EINVAL;
 	}
-	printk( KERN_INFO "reg[0x%x]=0x%2X\n", STK_PDT_ID_REG, ps_reg[cnt]);
+	dev_dbg(dev, "reg[0x%x]=0x%2X\n", STK_PDT_ID_REG, ps_reg[cnt]);
 	cnt++;
 	ps_reg[cnt] = i2c_smbus_read_byte_data(ps_data->client, STK_RSRVD_REG);
 	if(ps_reg[cnt] < 0)
@@ -1526,7 +1581,7 @@
 		printk( KERN_ERR "all_reg_show:i2c_smbus_read_byte_data fail, ret=%d", ps_reg[cnt]);
 		return -EINVAL;
 	}
-	printk( KERN_INFO "reg[0x%x]=0x%2X\n", STK_RSRVD_REG, ps_reg[cnt]);
+	dev_dbg(dev, "reg[0x%x]=0x%2X\n", STK_RSRVD_REG, ps_reg[cnt]);
     mutex_unlock(&ps_data->io_lock);
 
     return scnprintf(buf, PAGE_SIZE, "%2X %2X %2X %2X %2X,%2X %2X %2X %2X %2X,%2X %2X %2X %2X %2X,%2X %2X %2X %2X %2X,%2X %2X %2X %2X %2X,%2X %2X\n",
@@ -1589,8 +1644,7 @@
 			__func__, ret);
 		return ret;
 	}
-	printk(KERN_INFO "%s: write reg 0x%x=0x%x\n", __func__, addr, cmd);
-
+	dev_dbg(dev, "%s: write reg 0x%x=0x%x\n", __func__, addr, cmd);
 	addr_u8 = (u8) addr;
 	cmd_u8 = (u8) cmd;
 	//mutex_lock(&ps_data->io_lock);
@@ -1688,7 +1742,6 @@
 	input_report_abs(ps_data->als_input_dev, ABS_MISC, ps_data->als_lux_last);
 	input_sync(ps_data->als_input_dev);
 	mutex_unlock(&ps_data->io_lock);
-	//printk(KERN_INFO "%s: als input event %d lux\n",__func__, ps_data->als_lux_last);
 }
 #endif
 
@@ -1948,7 +2001,6 @@
 	int err;
 #endif
 
-	printk(KERN_INFO "%s", __func__);
     mutex_lock(&ps_data->io_lock);
 	if(ps_data->als_enabled)
 	{
@@ -1976,7 +2028,6 @@
 	int err;
 #endif
 
-	printk(KERN_INFO "%s", __func__);
     mutex_lock(&ps_data->io_lock);
 	if(ps_data->als_enabled)
 		stk3x1x_enable_als(ps_data, 1);
@@ -2394,10 +2445,16 @@
 	register_early_suspend(&ps_data->stk_early_suspend);
 #endif
 	/* make sure everything is ok before registering the class device */
-	err = sensors_classdev_register(&client->dev, &sensors_light_cdev);
+	ps_data->als_cdev = sensors_light_cdev;
+	ps_data->als_cdev.sensors_enable = stk_als_enable_set;
+	ps_data->als_cdev.sensors_poll_delay = stk_als_poll_delay_set;
+	err = sensors_classdev_register(&client->dev, &ps_data->als_cdev);
 	if (err)
 		goto err_power_on;
-	err = sensors_classdev_register(&client->dev, &sensors_proximity_cdev);
+
+	ps_data->ps_cdev = sensors_proximity_cdev;
+	ps_data->ps_cdev.sensors_enable = stk_ps_enable_set;
+	err = sensors_classdev_register(&client->dev, &ps_data->ps_cdev);
 	if (err)
 		goto err_class_sysfs;
 
@@ -2411,9 +2468,9 @@
 
 err_init_all_setting:
 	stk3x1x_power_ctl(ps_data, false);
-	sensors_classdev_unregister(&sensors_proximity_cdev);
+	sensors_classdev_unregister(&ps_data->ps_cdev);
 err_class_sysfs:
-	sensors_classdev_unregister(&sensors_light_cdev);
+	sensors_classdev_unregister(&ps_data->als_cdev);
 err_power_on:
 	stk3x1x_power_init(ps_data, false);
 err_power_init:
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 9b0c5c7..1e08169 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -110,6 +110,18 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called atmel_mxt_ts.
 
+config TOUCHSCREEN_ATMEL_MAXTOUCH_TS
+	tristate "Atmel Maxtouch Touchscreen Family"
+	depends on I2C
+	help
+	  Say Y here if you have Atmel MaXTouch Touchscreen
+	  using i2c connected to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called atmel_maxtouch_ts.
+
 config TOUCHSCREEN_AUO_PIXCIR
 	tristate "AUO in-cell touchscreen using Pixcir ICs"
 	depends on I2C
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 3acc612..2b98145 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -14,6 +14,7 @@
 obj-$(CONFIG_TOUCHSCREEN_ADS7846)	+= ads7846.o
 obj-$(CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH)	+= atmel_maxtouch.o
 obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT)	+= atmel_mxt_ts.o
+obj-$(CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH_TS)	+= atmel_maxtouch_ts.o
 obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC)	+= atmel_tsadcc.o
 obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR)	+= auo-pixcir-ts.o
 obj-$(CONFIG_TOUCHSCREEN_BITSY)		+= h3600_ts_input.o
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 3731561..b79ab7a 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -2049,14 +2049,17 @@
 	return scnprintf(buf, PAGE_SIZE, "%u", val);
 }
 
-static DEVICE_ATTR(secure_touch_enable, 0666, mxt_secure_touch_enable_show,
-	mxt_secure_touch_enable_store);
-static DEVICE_ATTR(secure_touch, 0444, mxt_secure_touch_show, NULL);
+static DEVICE_ATTR(secure_touch_enable, S_IRUGO | S_IWUSR | S_IWGRP ,
+			 mxt_secure_touch_enable_show,
+			 mxt_secure_touch_enable_store);
+static DEVICE_ATTR(secure_touch, S_IRUGO, mxt_secure_touch_show, NULL);
 #endif
 
-static DEVICE_ATTR(object, 0444, mxt_object_show, NULL);
-static DEVICE_ATTR(update_fw, 0664, NULL, mxt_update_fw_store);
-static DEVICE_ATTR(force_cfg_update, 0664, NULL, mxt_force_cfg_update_store);
+static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL);
+static DEVICE_ATTR(update_fw, S_IWUSR | S_IWGRP , NULL, mxt_update_fw_store);
+static DEVICE_ATTR(force_cfg_update, S_IWUSR | S_IWGRP ,
+			 NULL,
+			 mxt_force_cfg_update_store);
 
 static struct attribute *mxt_attrs[] = {
 	&dev_attr_object.attr,
diff --git a/drivers/input/touchscreen/ft5x06_ts.c b/drivers/input/touchscreen/ft5x06_ts.c
index 9a4301e..4b8a3d4 100644
--- a/drivers/input/touchscreen/ft5x06_ts.c
+++ b/drivers/input/touchscreen/ft5x06_ts.c
@@ -1546,8 +1546,9 @@
 	data->family_id = pdata->family_id;
 
 	err = request_threaded_irq(client->irq, NULL,
-				   ft5x06_ts_interrupt, pdata->irqflags,
-				   client->dev.driver->name, data);
+				ft5x06_ts_interrupt,
+				pdata->irqflags | IRQF_ONESHOT,
+				client->dev.driver->name, data);
 	if (err) {
 		dev_err(&client->dev, "request irq failed\n");
 		goto free_reset_gpio;
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.c b/drivers/input/touchscreen/gt9xx/gt9xx.c
index b39cb0d..6d4c638 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx.c
+++ b/drivers/input/touchscreen/gt9xx/gt9xx.c
@@ -753,16 +753,13 @@
 	return ret;
 }
 #else
-/*******************************************************
-Function:
-	Enter sleep mode.
-Input:
-	ts: private data.
-Output:
-	Executive outcomes.
-	>0: succeed, otherwise failed.
-*******************************************************/
-static s8 gtp_enter_sleep(struct goodix_ts_data  *ts)
+/**
+ * gtp_enter_sleep - Enter sleep mode
+ * @ts: driver private data
+ *
+ * Returns zero on success, else an error.
+ */
+static u8 gtp_enter_sleep(struct goodix_ts_data *ts)
 {
 	int ret = -1;
 	s8 retry = 0;
@@ -784,16 +781,16 @@
 		ret = goodix_power_off(ts);
 		if (ret) {
 			dev_err(&ts->client->dev, "GTP power off failed.\n");
-			return 0;
+			return ret;
 		}
-		return 1;
+		return 0;
 	} else {
 		usleep(5000);
 		while (retry++ < 5) {
 			ret = gtp_i2c_write(ts->client, i2c_control_buf, 3);
 			if (ret == 1) {
 				dev_dbg(&ts->client->dev, "GTP enter sleep!");
-				return ret;
+				return 0;
 			}
 			msleep(20);
 		}
@@ -1220,7 +1217,8 @@
 	int ret;
 	const u8 irq_table[] = GTP_IRQ_TAB;
 
-	ret = request_irq(ts->client->irq, goodix_ts_irq_handler,
+	ret = request_threaded_irq(ts->client->irq, NULL,
+			goodix_ts_irq_handler,
 			irq_table[ts->int_trigger_type],
 			ts->client->name, ts);
 	if (ret) {
@@ -2031,7 +2029,7 @@
 
 	ret = gtp_enter_sleep(ts);
 #endif
-	if (ret <= 0)
+	if (ret < 0)
 		dev_err(&ts->client->dev, "GTP early suspend failed.\n");
 	/* to avoid waking up while not sleeping,
 	 * delay 48 + 10ms to ensure reliability
@@ -2268,8 +2266,15 @@
 }
 #endif
 
-static SIMPLE_DEV_PM_OPS(goodix_ts_dev_pm_ops, goodix_ts_suspend,
-					goodix_ts_resume);
+#if (!defined(CONFIG_FB) && !defined(CONFIG_HAS_EARLYSUSPEND))
+static const struct dev_pm_ops goodix_ts_dev_pm_ops = {
+	.suspend = goodix_ts_suspend,
+	.resume = goodix_ts_resume,
+};
+#else
+static const struct dev_pm_ops goodix_ts_dev_pm_ops = {
+};
+#endif
 
 static const struct i2c_device_id goodix_ts_id[] = {
 	{ GTP_I2C_NAME, 0 },
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.c b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
index 755084c..7152ec8 100644
--- a/drivers/input/touchscreen/synaptics_i2c_rmi4.c
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
@@ -2424,6 +2424,8 @@
 		}
 	}
 
+	INIT_LIST_HEAD(&rmi->support_fn_list);
+
 	retval = synaptics_rmi4_query_device(rmi4_data);
 	if (retval < 0) {
 		dev_err(&rmi4_data->i2c_client->dev,
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index 7954296..da90440 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -255,7 +255,7 @@
 	WLED_OVP_35V,
 	WLED_OVP_32V,
 	WLED_OVP_29V,
-	WLED_OVP_37V,
+	WLED_OVP_27V,
 };
 
 enum flash_headroom {
@@ -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,
@@ -1495,7 +1496,7 @@
 	num_wled_strings = led->wled_cfg->num_strings;
 
 	/* verify ranges */
-	if (led->wled_cfg->ovp_val > WLED_OVP_37V) {
+	if (led->wled_cfg->ovp_val > WLED_OVP_27V) {
 		dev_err(&led->spmi_dev->dev, "Invalid ovp value\n");
 		return -EINVAL;
 	}
@@ -3439,10 +3440,15 @@
 
 	return 0;
 }
+
+#ifdef CONFIG_OF
 static struct of_device_id spmi_match_table[] = {
-	{	.compatible = "qcom,leds-qpnp",
-	}
+	{ .compatible = "qcom,leds-qpnp",},
+	{ },
 };
+#else
+#define spmi_match_table NULL
+#endif
 
 static struct spmi_driver qpnp_leds_driver = {
 	.driver		= {
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..8c7890d 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);
@@ -459,54 +461,62 @@
 {
 	uint32_t error_status1 = vfe_dev->error_info.error_mask1;
 	if (error_status1 & (1 << 0))
-		pr_err("%s: camif error status: 0x%x\n",
+		pr_err_ratelimited("%s: camif error status: 0x%x\n",
 			__func__, vfe_dev->error_info.camif_status);
 	if (error_status1 & (1 << 1))
-		pr_err("%s: stats bhist overwrite\n", __func__);
+		pr_err_ratelimited("%s: stats bhist overwrite\n", __func__);
 	if (error_status1 & (1 << 2))
-		pr_err("%s: stats cs overwrite\n", __func__);
+		pr_err_ratelimited("%s: stats cs overwrite\n", __func__);
 	if (error_status1 & (1 << 3))
-		pr_err("%s: stats ihist overwrite\n", __func__);
+		pr_err_ratelimited("%s: stats ihist overwrite\n", __func__);
 	if (error_status1 & (1 << 4))
-		pr_err("%s: realign buf y overflow\n", __func__);
+		pr_err_ratelimited("%s: realign buf y overflow\n", __func__);
 	if (error_status1 & (1 << 5))
-		pr_err("%s: realign buf cb overflow\n", __func__);
+		pr_err_ratelimited("%s: realign buf cb overflow\n", __func__);
 	if (error_status1 & (1 << 6))
-		pr_err("%s: realign buf cr overflow\n", __func__);
+		pr_err_ratelimited("%s: realign buf cr overflow\n", __func__);
 	if (error_status1 & (1 << 7)) {
-		pr_err("%s: violation\n", __func__);
+		pr_err_ratelimited("%s: violation\n", __func__);
 		msm_vfe40_process_violation_status(vfe_dev);
 	}
 	if (error_status1 & (1 << 9))
-		pr_err("%s: image master 0 bus overflow\n", __func__);
+		pr_err_ratelimited("%s: image master 0 bus overflow\n",
+			__func__);
 	if (error_status1 & (1 << 10))
-		pr_err("%s: image master 1 bus overflow\n", __func__);
+		pr_err_ratelimited("%s: image master 1 bus overflow\n",
+			__func__);
 	if (error_status1 & (1 << 11))
-		pr_err("%s: image master 2 bus overflow\n", __func__);
+		pr_err_ratelimited("%s: image master 2 bus overflow\n",
+			__func__);
 	if (error_status1 & (1 << 12))
-		pr_err("%s: image master 3 bus overflow\n", __func__);
+		pr_err_ratelimited("%s: image master 3 bus overflow\n",
+			__func__);
 	if (error_status1 & (1 << 13))
-		pr_err("%s: image master 4 bus overflow\n", __func__);
+		pr_err_ratelimited("%s: image master 4 bus overflow\n",
+			__func__);
 	if (error_status1 & (1 << 14))
-		pr_err("%s: image master 5 bus overflow\n", __func__);
+		pr_err_ratelimited("%s: image master 5 bus overflow\n",
+			__func__);
 	if (error_status1 & (1 << 15))
-		pr_err("%s: image master 6 bus overflow\n", __func__);
+		pr_err_ratelimited("%s: image master 6 bus overflow\n",
+			__func__);
 	if (error_status1 & (1 << 16))
-		pr_err("%s: status be bus overflow\n", __func__);
+		pr_err_ratelimited("%s: status be bus overflow\n", __func__);
 	if (error_status1 & (1 << 17))
-		pr_err("%s: status bg bus overflow\n", __func__);
+		pr_err_ratelimited("%s: status bg bus overflow\n", __func__);
 	if (error_status1 & (1 << 18))
-		pr_err("%s: status bf bus overflow\n", __func__);
+		pr_err_ratelimited("%s: status bf bus overflow\n", __func__);
 	if (error_status1 & (1 << 19))
-		pr_err("%s: status awb bus overflow\n", __func__);
+		pr_err_ratelimited("%s: status awb bus overflow\n", __func__);
 	if (error_status1 & (1 << 20))
-		pr_err("%s: status rs bus overflow\n", __func__);
+		pr_err_ratelimited("%s: status rs bus overflow\n", __func__);
 	if (error_status1 & (1 << 21))
-		pr_err("%s: status cs bus overflow\n", __func__);
+		pr_err_ratelimited("%s: status cs bus overflow\n", __func__);
 	if (error_status1 & (1 << 22))
-		pr_err("%s: status ihist bus overflow\n", __func__);
+		pr_err_ratelimited("%s: status ihist bus overflow\n", __func__);
 	if (error_status1 & (1 << 23))
-		pr_err("%s: status skin bhist bus overflow\n", __func__);
+		pr_err_ratelimited("%s: status skin bhist bus overflow\n",
+			__func__);
 }
 
 static void msm_vfe40_read_irq_status(struct vfe_device *vfe_dev,
@@ -724,13 +734,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 +757,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 +786,7 @@
 			break;
 		default:
 			pr_err("%s: invalid pack fmt!\n", __func__);
-			return;
+			return -EINVAL;
 		}
 	}
 
@@ -789,9 +807,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 3202cdb..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;
 	}
 
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..a12c692 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
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -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;
@@ -258,6 +277,43 @@
 	return rc;
 }
 
+static int msm_isp_get_max_clk_rate(struct vfe_device *vfe_dev, long *rate)
+{
+	int           clk_idx = 0;
+	unsigned long max_value = ~0;
+	long          round_rate = 0;
+
+	if (!vfe_dev || !rate) {
+		pr_err("%s:%d failed: vfe_dev %p rate %p\n", __func__, __LINE__,
+			vfe_dev, rate);
+		return -EINVAL;
+	}
+
+	*rate = 0;
+	if (!vfe_dev->hw_info) {
+		pr_err("%s:%d failed: vfe_dev->hw_info %p\n", __func__,
+			__LINE__, vfe_dev->hw_info);
+		return -EINVAL;
+	}
+
+	clk_idx = vfe_dev->hw_info->vfe_clk_idx;
+	if (clk_idx >= ARRAY_SIZE(vfe_dev->vfe_clk)) {
+		pr_err("%s:%d failed: clk_idx %d max array size %d\n",
+			__func__, __LINE__, clk_idx,
+			ARRAY_SIZE(vfe_dev->vfe_clk));
+		return -EINVAL;
+	}
+
+	round_rate = clk_round_rate(vfe_dev->vfe_clk[clk_idx], max_value);
+	if (round_rate < 0) {
+		pr_err("%s: Invalid vfe clock rate\n", __func__);
+		return -EINVAL;
+	}
+
+	*rate = round_rate;
+	return 0;
+}
+
 static int msm_isp_set_clk_rate(struct vfe_device *vfe_dev, long *rate)
 {
 	int rc = 0;
@@ -599,6 +655,23 @@
 	case GET_SOC_HW_VER:
 		*cfg_data = vfe_dev->soc_hw_version;
 		break;
+	case GET_MAX_CLK_RATE: {
+		int rc = 0;
+
+		if (cmd_len < sizeof(unsigned long)) {
+			pr_err("%s:%d failed: invalid cmd len %d exp %d\n",
+				__func__, __LINE__, cmd_len,
+				sizeof(unsigned long));
+			return -EINVAL;
+		}
+		rc = msm_isp_get_max_clk_rate(vfe_dev,
+			(unsigned long *)cfg_data);
+		if (rc < 0) {
+			pr_err("%s:%d failed: rc %d\n", __func__, __LINE__, rc);
+			return -EINVAL;
+		}
+		break;
+	}
 	}
 	return 0;
 }
@@ -735,7 +808,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 +844,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 +853,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 +867,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 +899,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 +910,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/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
index de098c9..c4a23ca 100755
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -200,7 +200,7 @@
 			ispif->base + ISPIF_VFE_m_INTF_CMD_0(i));
 		msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY,
 			ispif->base + ISPIF_VFE_m_INTF_CMD_1(i));
-		pr_debug("%s: base %x", __func__, (unsigned int)ispif->base);
+		pr_debug("%s: base %lx", __func__, (unsigned long)ispif->base);
 		msm_camera_io_w(0, ispif->base +
 			ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 0));
 		msm_camera_io_w(0, ispif->base +
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/msm.c b/drivers/media/platform/msm/camera_v2/msm.c
index c79b3a3..8a2c8e5 100644
--- a/drivers/media/platform/msm/camera_v2/msm.c
+++ b/drivers/media/platform/msm/camera_v2/msm.c
@@ -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 7520ce5..cb8fcdd 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
@@ -109,8 +109,9 @@
 	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);
+			pr_err("%s: Error delete invalid bufs =%x, ses_id=%d, str_id=%d, idx=%d\n",
+				__func__, (unsigned int)bufs, bufs->session_id,
+				bufs->stream_id, bufs->vb2_buf->v4l2_buf.index);
 			list_del_init(&bufs->entry);
 			kfree(bufs);
 		}
@@ -118,6 +119,36 @@
 	spin_unlock_irqrestore(&buf_mngr_dev->buf_q_spinlock, flags);
 }
 
+static int msm_generic_buf_mngr_open(struct v4l2_subdev *sd,
+	struct v4l2_subdev_fh *fh)
+{
+	int rc = 0;
+	struct msm_buf_mngr_device *buf_mngr_dev = v4l2_get_subdevdata(sd);
+	if (!buf_mngr_dev) {
+		pr_err("%s buf manager device NULL\n", __func__);
+		rc = -ENODEV;
+		return rc;
+	}
+	buf_mngr_dev->msm_buf_mngr_open_cnt++;
+	return rc;
+}
+
+static int msm_generic_buf_mngr_close(struct v4l2_subdev *sd,
+	struct v4l2_subdev_fh *fh)
+{
+	int rc = 0;
+	struct msm_buf_mngr_device *buf_mngr_dev = v4l2_get_subdevdata(sd);
+	if (!buf_mngr_dev) {
+		pr_err("%s buf manager device NULL\n", __func__);
+		rc = -ENODEV;
+		return rc;
+	}
+	buf_mngr_dev->msm_buf_mngr_open_cnt--;
+	if (buf_mngr_dev->msm_buf_mngr_open_cnt == 0)
+		msm_buf_mngr_sd_shutdown(buf_mngr_dev);
+	return rc;
+}
+
 static long msm_buf_mngr_subdev_ioctl(struct v4l2_subdev *sd,
 	unsigned int cmd, void *arg)
 {
@@ -141,6 +172,12 @@
 	case VIDIOC_MSM_BUF_MNGR_PUT_BUF:
 		rc = msm_buf_mngr_put_buf(buf_mngr_dev, argp);
 		break;
+	case VIDIOC_MSM_BUF_MNGR_INIT:
+		rc = msm_generic_buf_mngr_open(sd, NULL);
+		break;
+	case VIDIOC_MSM_BUF_MNGR_DEINIT:
+		rc = msm_generic_buf_mngr_close(sd, NULL);
+		break;
 	case MSM_SD_SHUTDOWN:
 		msm_buf_mngr_sd_shutdown(buf_mngr_dev);
 		break;
@@ -154,6 +191,12 @@
 	.ioctl = msm_buf_mngr_subdev_ioctl,
 };
 
+static const struct v4l2_subdev_internal_ops
+	msm_generic_buf_mngr_subdev_internal_ops = {
+	.open  = msm_generic_buf_mngr_open,
+	.close = msm_generic_buf_mngr_close,
+};
+
 static const struct v4l2_subdev_ops msm_buf_mngr_subdev_ops = {
 	.core = &msm_buf_mngr_subdev_core_ops,
 };
@@ -183,6 +226,8 @@
 	msm_buf_mngr_dev->subdev.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
 	msm_buf_mngr_dev->subdev.sd.entity.group_id =
 		MSM_CAMERA_SUBDEV_BUF_MNGR;
+	msm_buf_mngr_dev->subdev.sd.internal_ops =
+		&msm_generic_buf_mngr_subdev_internal_ops;
 	msm_buf_mngr_dev->subdev.close_seq = MSM_SD_CLOSE_4TH_CATEGORY;
 	rc = msm_sd_register(&msm_buf_mngr_dev->subdev);
 	if (rc != 0) {
diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h
index 56886cd..49fad22 100644
--- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h
+++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h
@@ -36,5 +36,6 @@
 	spinlock_t buf_q_spinlock;
 	struct msm_sd_subdev subdev;
 	struct msm_sd_req_vb2_q vb2_ops;
+	uint32_t msm_buf_mngr_open_cnt;
 };
 #endif
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 69f0a3d..e50e8c5 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
@@ -67,6 +67,9 @@
 /* dump the frame command before writing to the hardware */
 #define  MSM_CPP_DUMP_FRM_CMD 0
 
+static int msm_cpp_buffer_ops(struct cpp_device *cpp_dev,
+	uint32_t buff_mgr_ops, struct msm_buf_mngr_info *buff_mgr_info);
+
 #if CONFIG_MSM_CPP_DBG
 #define CPP_DBG(fmt, args...) pr_err(fmt, ##args)
 #else
@@ -714,6 +717,14 @@
 			goto req_irq_fail;
 		}
 		cpp_dev->buf_mgr_subdev = msm_buf_mngr_get_subdev();
+
+		rc = msm_cpp_buffer_ops(cpp_dev,
+			VIDIOC_MSM_BUF_MNGR_INIT, NULL);
+		if (rc < 0) {
+			pr_err("buf mngr init failed\n");
+			free_irq(cpp_dev->irq->start, cpp_dev);
+			goto req_irq_fail;
+		}
 	}
 
 	cpp_dev->hw_info.cpp_hw_version =
@@ -757,7 +768,12 @@
 
 static void cpp_release_hardware(struct cpp_device *cpp_dev)
 {
+	int32_t rc;
 	if (cpp_dev->state != CPP_STATE_BOOT) {
+		rc = msm_cpp_buffer_ops(cpp_dev,
+			VIDIOC_MSM_BUF_MNGR_DEINIT, NULL);
+		if (rc < 0)
+			pr_err("error in buf mngr deinit rc=%d\n", rc);
 		free_irq(cpp_dev->irq->start, cpp_dev);
 		tasklet_kill(&cpp_dev->cpp_tasklet);
 		atomic_set(&cpp_dev->irq_cnt, 0);
@@ -807,7 +823,7 @@
 
 		/*Start firmware loading*/
 		msm_cpp_write(MSM_CPP_CMD_FW_LOAD, cpp_dev->base);
-		msm_cpp_write(MSM_CPP_END_ADDRESS, cpp_dev->base);
+		msm_cpp_write(fw->size, cpp_dev->base);
 		msm_cpp_write(MSM_CPP_START_ADDRESS, cpp_dev->base);
 
 		if (ptr_bin) {
@@ -1845,6 +1861,11 @@
 	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;
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/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
index bb2b074..ea16ebd 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
@@ -254,6 +254,9 @@
 	int32_t num_steps = move_params->num_steps;
 	struct msm_camera_i2c_reg_setting reg_setting;
 
+	curr_lens_pos = a_ctrl->step_position_table[a_ctrl->curr_step_pos];
+	move_params->curr_lens_pos = curr_lens_pos;
+
 	if (copy_from_user(&ringing_params_kernel,
 		&(move_params->ringing_params[a_ctrl->curr_region_index]),
 		sizeof(struct damping_params_t))) {
@@ -267,7 +270,6 @@
 	if (dest_step_pos == a_ctrl->curr_step_pos)
 		return rc;
 
-	curr_lens_pos = a_ctrl->step_position_table[a_ctrl->curr_step_pos];
 	a_ctrl->i2c_tbl_index = 0;
 	CDBG("curr_step_pos =%d dest_step_pos =%d curr_lens_pos=%d\n",
 		a_ctrl->curr_step_pos, dest_step_pos, curr_lens_pos);
@@ -305,6 +307,7 @@
 		a_ctrl->curr_step_pos = target_step_pos;
 	}
 
+	move_params->curr_lens_pos = curr_lens_pos;
 	reg_setting.reg_setting = a_ctrl->i2c_reg_tbl;
 	reg_setting.data_type = a_ctrl->i2c_data_type;
 	reg_setting.size = a_ctrl->i2c_tbl_index;
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_trigger.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
index 699142a..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
@@ -71,9 +71,9 @@
 	case MSM_CAMERA_LED_LOW:
 		if (fctrl->torch_trigger) {
 			max_curr_l = fctrl->torch_max_current;
-			if (cfg->led_current > 0 &&
-					cfg->led_current < max_curr_l) {
-				curr_l = cfg->led_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",
@@ -90,9 +90,9 @@
 		for (i = 0; i < fctrl->num_sources; i++)
 			if (fctrl->flash_trigger[i]) {
 				max_curr_l = fctrl->flash_max_current[i];
-				if (cfg->led_current > 0 &&
-						cfg->led_current < max_curr_l) {
-					curr_l = cfg->led_current;
+				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",
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_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index 3fd5d3a..189fca0 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -263,7 +263,9 @@
 		break;
 	case HFI_EVENT_RELEASE_BUFFER_REFERENCE:
 		dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE\n");
-		hfi_process_evt_release_buffer_ref(callback, device_id, pkt);
+		if (!validate_session_pkt(sessions, sess, session_lock))
+			hfi_process_evt_release_buffer_ref(callback,
+				device_id, pkt);
 		break;
 	default:
 		dprintk(VIDC_WARN, "hal_process_event_notify:unkown_event_id");
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 9dd4e93..7e24510 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -22,7 +22,7 @@
 #define MSM_VDEC_DVC_NAME "msm_vdec_8974"
 #define MIN_NUM_OUTPUT_BUFFERS 4
 #define MAX_NUM_OUTPUT_BUFFERS 6
-#define DEFAULT_CONCEAL_COLOR 0x0
+#define DEFAULT_VIDEO_CONCEAL_COLOR_BLACK 0x8080
 
 #define TZ_INFO_GET_FEATURE_VERSION_ID 0x3
 #define TZ_DYNAMIC_BUFFER_FEATURE_ID 12
@@ -323,6 +323,16 @@
 		.qmenu = NULL,
 		.cluster = 0,
 	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR,
+		.name = "Picture concealed color",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 0x0,
+		.maximum = 0xffffff,
+		.default_value = DEFAULT_VIDEO_CONCEAL_COLOR_BLACK,
+		.step = 1,
+		.cluster = 0,
+	},
 };
 
 #define NUM_CTRLS ARRAY_SIZE(msm_vdec_ctrls)
@@ -971,11 +981,17 @@
 			rc = -EINVAL;
 			goto err_invalid_fmt;
 		}
+		rc = msm_comm_try_state(inst, MSM_VIDC_CORE_INIT_DONE);
+		if (rc) {
+			dprintk(VIDC_ERR, "Failed to initialize instance\n");
+			goto err_invalid_fmt;
+		}
 		if (!(get_hal_codec_type(fmt->fourcc) &
 			inst->core->dec_codec_supported)) {
 			dprintk(VIDC_ERR,
-				"Codec(0x%x) not supported\n",
-				get_hal_codec_type(fmt->fourcc));
+				"Codec(0x%x) is not present in the supported codecs list(0x%x)\n",
+				get_hal_codec_type(fmt->fourcc),
+				inst->core->dec_codec_supported);
 			rc = -EINVAL;
 			goto err_invalid_fmt;
 		}
@@ -1319,7 +1335,6 @@
 {
 	struct msm_vidc_inst *inst;
 	int rc = 0;
-	int pdata = DEFAULT_CONCEAL_COLOR;
 	struct hfi_device *hdev;
 	if (!q || !q->drv_priv) {
 		dprintk(VIDC_ERR, "Invalid input, q = %p\n", q);
@@ -1337,10 +1352,6 @@
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
 		if (inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
 			rc = start_streaming(inst);
-		rc = call_hfi_op(hdev, session_set_property,
-			(void *) inst->session,
-			HAL_PARAM_VDEC_CONCEAL_COLOR,
-			(void *) &pdata);
 		break;
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
 		if (inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
@@ -1410,7 +1421,19 @@
 	}
 	switch (dec->cmd) {
 	case V4L2_DEC_QCOM_CMD_FLUSH:
+		if (core->state != VIDC_CORE_INVALID &&
+			inst->state ==  MSM_VIDC_CORE_INVALID) {
+			rc = msm_comm_recover_from_session_error(inst);
+			if (rc)
+				dprintk(VIDC_ERR,
+					"Failed to recover from session_error: %d\n",
+					rc);
+		}
 		rc = msm_comm_flush(inst, dec->flags);
+		if (rc) {
+			dprintk(VIDC_ERR,
+					"Failed to flush buffers: %d\n", rc);
+		}
 		break;
 	case V4L2_DEC_CMD_STOP:
 		if (core->state != VIDC_CORE_INVALID &&
@@ -1732,6 +1755,11 @@
 			break;
 		}
 		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR:
+		property_id = HAL_PARAM_VDEC_CONCEAL_COLOR;
+		property_val = ctrl->val;
+		pdata = &property_val;
+		break;
 	default:
 		break;
 	}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 9da1220..a9521a1 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -717,6 +717,8 @@
 		return -EINVAL;
 
 	list_for_each_safe(ptr, next, &inst->registered_bufs) {
+		bool release_buf = false;
+		mutex_lock(&inst->lock);
 		bi = list_entry(ptr, struct buffer_info, list);
 		if (bi->type == buffer_type) {
 			buffer_info.type = bi->type;
@@ -734,19 +736,28 @@
 					buffer_info.m.planes[i].length);
 			}
 			buffer_info.length = bi->num_planes;
-			if (inst->session_type == MSM_VIDC_DECODER)
-				rc = msm_vdec_release_buf(instance,
-					&buffer_info);
-			if (inst->session_type == MSM_VIDC_ENCODER)
-				rc = msm_venc_release_buf(instance,
-					&buffer_info);
-			if (rc)
-				dprintk(VIDC_ERR,
-					"Failed Release buffer: %d, %d, %d\n",
-					buffer_info.m.planes[0].reserved[0],
-					buffer_info.m.planes[0].reserved[1],
-					buffer_info.m.planes[0].length);
-
+			release_buf = true;
+		}
+		mutex_unlock(&inst->lock);
+		if (!release_buf)
+			continue;
+		if (inst->session_type == MSM_VIDC_DECODER)
+			rc = msm_vdec_release_buf(instance,
+				&buffer_info);
+		if (inst->session_type == MSM_VIDC_ENCODER)
+			rc = msm_venc_release_buf(instance,
+				&buffer_info);
+		if (rc)
+			dprintk(VIDC_ERR,
+				"Failed Release buffer: %d, %d, %d\n",
+				buffer_info.m.planes[0].reserved[0],
+				buffer_info.m.planes[0].reserved[1],
+				buffer_info.m.planes[0].length);
+	}
+	mutex_lock(&inst->lock);
+	list_for_each_safe(ptr, next, &inst->registered_bufs) {
+		bi = list_entry(ptr, struct buffer_info, list);
+		if (bi->type == buffer_type) {
 			list_del(&bi->list);
 			for (i = 0; i < bi->num_planes; i++) {
 				if (bi->handle[i] && bi->mapped[i]) {
@@ -762,6 +773,7 @@
 			kfree(bi);
 		}
 	}
+	mutex_unlock(&inst->lock);
 	return rc;
 }
 
@@ -1076,8 +1088,6 @@
 {
 	int rc = 0;
 	struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
-	spin_lock_init(&pvdev->fh_lock);
-	INIT_LIST_HEAD(&pvdev->fh_list);
 
 	v4l2_fh_init(&vidc_inst->event_handler, pvdev);
 	v4l2_fh_add(&vidc_inst->event_handler);
@@ -1302,6 +1312,7 @@
 	if (!inst)
 		return -EINVAL;
 
+	v4l2_fh_del(&inst->event_handler);
 	list_for_each_safe(ptr, next, &inst->registered_bufs) {
 		bi = list_entry(ptr, struct buffer_info, list);
 		if (bi->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 7588994..8921b13 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -519,6 +519,14 @@
 					event_notify->packet_buffer,
 					event_notify->exra_data_buffer);
 
+				if (inst->state == MSM_VIDC_CORE_INVALID ||
+					inst->core->state ==
+						VIDC_CORE_INVALID) {
+					dprintk(VIDC_DBG,
+						"Event release buf ref received in invalid state - discard\n");
+					return;
+				}
+
 				/*
 				* Get the buffer_info entry for the
 				* device address.
@@ -2999,6 +3007,9 @@
 		dprintk(VIDC_INFO, "Input only flush not supported\n");
 		return 0;
 	}
+	mutex_lock(&inst->sync_lock);
+	msm_comm_flush_dynamic_buffers(inst);
+	mutex_unlock(&inst->sync_lock);
 	if (inst->state == MSM_VIDC_CORE_INVALID ||
 			core->state == VIDC_CORE_INVALID) {
 		dprintk(VIDC_ERR,
@@ -3009,7 +3020,6 @@
 	}
 
 	mutex_lock(&inst->sync_lock);
-	msm_comm_flush_dynamic_buffers(inst);
 	if (inst->in_reconfig && !ip_flush && op_flush) {
 		if (!list_empty(&inst->pendingq)) {
 			/*Execution can never reach here since port reconfig
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 2596a30..7f09b24 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -1635,15 +1635,23 @@
 	return 0;
 }
 
-static int venus_hfi_is_cmd_pending(struct venus_hfi_device *dev)
+static int venus_hfi_get_q_size(struct venus_hfi_device *dev,
+	unsigned int q_index)
 {
 	struct hfi_queue_header *queue;
 	struct vidc_iface_q_info *q_info;
 	u32 write_ptr, read_ptr;
 	u32 rc = 0;
-	q_info = &dev->iface_queues[VIDC_IFACEQ_CMDQ_IDX];
-	if (!q_info)
+	if (q_index >= VIDC_IFACEQ_NUMQ) {
+		dprintk(VIDC_ERR, "Invalid q index: %d\n", q_index);
+		return -ENOENT;
+	}
+
+	q_info = &dev->iface_queues[q_index];
+	if (!q_info) {
 		dprintk(VIDC_ERR, "cannot read shared Q's");
+		return -ENOENT;
+	}
 	queue = (struct hfi_queue_header *) q_info->q_hdr;
 	if (!queue) {
 		dprintk(VIDC_ERR, "queue not present");
@@ -1667,9 +1675,12 @@
 	}
 	/*SYS Idle should be last message so mask any further interrupts
 	 * until clocks are enabled again.*/
-	venus_hfi_write_register(device,
-			VIDC_WRAPPER_INTR_MASK,
-			VIDC_WRAPPER_INTR_MASK_A2HVCODEC_BMSK | VIDC_WRAPPER_INTR_MASK_A2HCPU_BMSK, 0);
+	if (!venus_hfi_get_q_size(device, VIDC_IFACEQ_MSGQ_IDX)) {
+		venus_hfi_write_register(device,
+				VIDC_WRAPPER_INTR_MASK,
+				VIDC_WRAPPER_INTR_MASK_A2HVCODEC_BMSK |
+				VIDC_WRAPPER_INTR_MASK_A2HCPU_BMSK, 0);
+	}
 	venus_hfi_clk_disable(device);
 	if (!queue_delayed_work(device->venus_pm_workq, &venus_hfi_pm_work,
 			msecs_to_jiffies(msm_vidc_pwr_collapse_delay)))
@@ -2512,7 +2523,7 @@
 	}
 	mutex_lock(&device->write_lock);
 	mutex_lock(&device->clk_pwr_lock);
-	rc = venus_hfi_is_cmd_pending(device);
+	rc = venus_hfi_get_q_size(device, VIDC_IFACEQ_CMDQ_IDX);
 	ctrl_status = venus_hfi_read_register(
 		device,
 		VIDC_CPU_CS_SCIACMDARG0);
diff --git a/drivers/media/platform/msm/wfd/vsg-subdev.c b/drivers/media/platform/msm/wfd/vsg-subdev.c
index c20250e..1f827bb 100644
--- a/drivers/media/platform/msm/wfd/vsg-subdev.c
+++ b/drivers/media/platform/msm/wfd/vsg-subdev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -23,6 +23,8 @@
 #define DEFAULT_MAX_FRAME_INTERVAL (1*NSEC_PER_SEC)
 #define DEFAULT_MODE ((enum vsg_modes)VSG_MODE_CFR)
 #define MAX_BUFS_BUSY_WITH_ENC 5
+#define TICKS_PER_TIMEOUT 2
+
 
 static void vsg_reset_timer(struct hrtimer *timer, ktime_t time)
 {
@@ -120,9 +122,10 @@
 	INIT_LIST_HEAD(&buf_info->node);
 
 	ktime_get_ts(&buf_info->time);
-	vsg_reset_timer(&context->threshold_timer, ns_to_ktime(
-				context->max_frame_interval));
-
+	if (work->work_delayed) {
+		buf_info->time = timespec_sub(buf_info->time,
+					context->delayed_frame_interval);
+	}
 	temp = NULL;
 	list_for_each_entry(temp, &context->busy_queue.node, node) {
 		if (mdp_buf_info_equals(&temp->mdp_buf_info,
@@ -233,6 +236,7 @@
 
 		INIT_WORK(&new_work->work, vsg_work_func);
 		new_work->context = context;
+		new_work->work_delayed = work->work_delayed;
 		queue_work(context->work_queue, &new_work->work);
 	}
 
@@ -245,25 +249,43 @@
 {
 	struct vsg_context *context = NULL;
 	struct vsg_work *task = NULL;
-
-	task = kzalloc(sizeof(*task), GFP_ATOMIC);
+	int64_t max_frame_interval = 0;
 	context = container_of(timer, struct vsg_context,
 			threshold_timer);
+
+	if (!context) {
+		WFD_MSG_ERR("Context not proper in %s", __func__);
+		goto threshold_err_no_context;
+	}
+	max_frame_interval = context->max_frame_interval;
+	if (list_empty(&context->free_queue.node) && !context->vsync_wait) {
+		context->vsync_wait = true;
+		max_frame_interval = context->max_frame_interval /
+					TICKS_PER_TIMEOUT;
+		goto restart_timer;
+	} else if (context->vsync_wait) {
+			max_frame_interval = context->max_frame_interval /
+						TICKS_PER_TIMEOUT;
+		context->vsync_wait = false;
+	}
+
+	task = kzalloc(sizeof(*task), GFP_ATOMIC);
 	if (!task) {
 		WFD_MSG_ERR("Out of memory in %s", __func__);
 		goto threshold_err_bad_param;
-	} else if (!context) {
-		WFD_MSG_ERR("Context not proper in %s", __func__);
-		goto threshold_err_no_context;
 	}
 
 	INIT_WORK(&task->work, vsg_timer_helper_func);
 	task->context = context;
+	task->work_delayed = false;
+	if (max_frame_interval < context->max_frame_interval)
+		task->work_delayed = true;
 
 	queue_work(context->work_queue, &task->work);
+restart_timer:
 threshold_err_bad_param:
 	hrtimer_forward_now(&context->threshold_timer, ns_to_ktime(
-				context->max_frame_interval));
+				max_frame_interval));
 	return HRTIMER_RESTART;
 threshold_err_no_context:
 	return HRTIMER_NORESTART;
@@ -298,6 +320,7 @@
 	context->last_buffer = NULL;
 	context->mode = DEFAULT_MODE;
 	context->state = VSG_STATE_NONE;
+	context->vsync_wait = false;
 	mutex_init(&context->mutex);
 
 	sd->dev_priv = context;
@@ -568,7 +591,8 @@
 				context->max_frame_interval, interval);
 		context->max_frame_interval = interval;
 	}
-
+	context->delayed_frame_interval =
+		ns_to_timespec(context->frame_interval / TICKS_PER_TIMEOUT);
 	mutex_unlock(&context->mutex);
 	return 0;
 }
diff --git a/drivers/media/platform/msm/wfd/vsg-subdev.h b/drivers/media/platform/msm/wfd/vsg-subdev.h
index 3347e5b..bbaced1 100644
--- a/drivers/media/platform/msm/wfd/vsg-subdev.h
+++ b/drivers/media/platform/msm/wfd/vsg-subdev.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -56,7 +56,7 @@
 };
 
 struct vsg_context {
-	struct vsg_buf_info	free_queue, busy_queue;
+	struct vsg_buf_info free_queue, busy_queue;
 	struct vsg_msg_ops vmops;
 	/* All time related values below in nanosecs */
 	int64_t frame_interval, max_frame_interval, frame_interval_variance;
@@ -66,11 +66,14 @@
 	struct vsg_buf_info *last_buffer;
 	int mode;
 	int state;
+	bool vsync_wait;
+	struct timespec delayed_frame_interval;
 };
 
 struct vsg_work {
 	struct vsg_context *context;
 	struct work_struct work;
+	bool work_delayed;
 };
 
 struct vsg_encode_work {
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 a554749..9f18508 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;
@@ -499,7 +499,7 @@
 	struct kfifo *data_b;
 	unsigned char evt = event;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return;
 	}
@@ -511,9 +511,14 @@
 
 static int hci_send_frame(struct sk_buff *skb)
 {
-	struct radio_hci_dev *hdev = (struct radio_hci_dev *) skb->dev;
+	struct radio_hci_dev *hdev;
 
-	if (!hdev) {
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return -EINVAL;
+	}
+	hdev = (struct radio_hci_dev *) skb->dev;
+	if (unlikely(!hdev)) {
 		kfree_skb(skb);
 		return -ENODEV;
 	}
@@ -528,6 +533,11 @@
 {
 	struct radio_hci_dev *hdev = (struct radio_hci_dev *) arg;
 	struct sk_buff *skb;
+
+	if (unlikely(hdev == NULL)) {
+		FMDERR("%s, HCI Device is null\n", __func__);
+		return;
+	}
 	if (!(atomic_read(&hdev->cmd_cnt))
 		&& time_after(jiffies, hdev->cmd_last_tx + HZ)) {
 		FMDERR("%s command tx timeout", hdev->name);
@@ -555,6 +565,10 @@
 	struct radio_hci_dev *hdev = (struct radio_hci_dev *) arg;
 	struct sk_buff *skb;
 
+	if (unlikely(hdev == NULL)) {
+		FMDERR("%s, HCI Device is null\n", __func__);
+		return;
+	}
 	read_lock(&hci_task_lock);
 
 	skb = skb_dequeue(&hdev->rx_q);
@@ -618,8 +632,14 @@
 
 int radio_hci_recv_frame(struct sk_buff *skb)
 {
-	struct radio_hci_dev *hdev = (struct radio_hci_dev *) skb->dev;
-	if (!hdev) {
+	struct radio_hci_dev *hdev;
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return -EINVAL;
+	}
+	hdev = (struct radio_hci_dev *) skb->dev;
+	if (unlikely(!hdev)) {
 		FMDERR("%s hdev is null while receiving frame", hdev->name);
 		kfree_skb(skb);
 		return -ENXIO;
@@ -641,6 +661,10 @@
 	struct sk_buff *skb;
 	int ret = 0;
 
+	if (unlikely(hdev == NULL)) {
+		FMDERR("%s, hci device is null\n", __func__);
+		return -EINVAL;
+	}
 	skb = alloc_skb(len, GFP_ATOMIC);
 	if (!skb) {
 		FMDERR("%s no memory for command", hdev->name);
@@ -679,7 +703,7 @@
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 	__u16 opcode = 0;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return -EINVAL;
 	}
@@ -746,6 +770,10 @@
 	struct hci_fm_recv_conf_req *recv_conf_req =
 		(struct hci_fm_recv_conf_req *) param;
 
+	if (recv_conf_req == NULL) {
+		FMDERR("%s, recv conf is null\n", __func__);
+		return -EINVAL;
+	}
 	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
 		HCI_OCF_FM_SET_RECV_CONF_REQ);
 	return radio_hci_send_cmd(hdev, opcode, sizeof((*recv_conf_req)),
@@ -760,6 +788,11 @@
 	struct hci_fm_trans_conf_req_struct *trans_conf_req =
 		(struct hci_fm_trans_conf_req_struct *) param;
 
+	if (trans_conf_req == NULL) {
+		FMDERR("%s, tx conf is null\n", __func__);
+		return -EINVAL;
+	}
+
 	opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
 		HCI_OCF_FM_SET_TRANS_CONF_REQ);
 	return radio_hci_send_cmd(hdev, opcode, sizeof((*trans_conf_req)),
@@ -783,6 +816,10 @@
 	struct hci_fm_mute_mode_req *mute_mode_req =
 		(struct hci_fm_mute_mode_req *) param;
 
+	if (mute_mode_req == NULL) {
+		FMDERR("%s, mute mode is null\n", __func__);
+		return -EINVAL;
+	}
 	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
 		HCI_OCF_FM_SET_MUTE_MODE_REQ);
 	return radio_hci_send_cmd(hdev, opcode, sizeof((*mute_mode_req)),
@@ -797,6 +834,10 @@
 	struct hci_fm_tx_ps *tx_ps_req =
 		(struct hci_fm_tx_ps *) param;
 
+	if (tx_ps_req == NULL) {
+		FMDERR("%s, tx ps req is null\n", __func__);
+		return -EINVAL;
+	}
 	opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
 		HCI_OCF_FM_RDS_PS_REQ);
 
@@ -811,6 +852,10 @@
 	struct hci_fm_tx_rt *tx_rt_req =
 		(struct hci_fm_tx_rt *) param;
 
+	if (tx_rt_req == NULL) {
+		FMDERR("%s, tx rt req is null\n", __func__);
+		return -EINVAL;
+	}
 	opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
 		HCI_OCF_FM_RDS_RT_REQ);
 
@@ -824,6 +869,11 @@
 	__u16 opcode = 0;
 	struct hci_fm_stereo_mode_req *stereo_mode_req =
 		(struct hci_fm_stereo_mode_req *) param;
+
+	if (stereo_mode_req == NULL) {
+		FMDERR("%s, stere mode req is null\n", __func__);
+		return -EINVAL;
+	}
 	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
 		HCI_OCF_FM_SET_STEREO_MODE_REQ);
 	return radio_hci_send_cmd(hdev, opcode, sizeof((*stereo_mode_req)),
@@ -913,6 +963,10 @@
 	struct hci_fm_search_station_req *srch_stations =
 		(struct hci_fm_search_station_req *) param;
 
+	if (srch_stations == NULL) {
+		FMDERR("%s, search station param is null\n", __func__);
+		return -EINVAL;
+	}
 	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
 		HCI_OCF_FM_SEARCH_STATIONS);
 	return radio_hci_send_cmd(hdev, opcode, sizeof((*srch_stations)),
@@ -926,6 +980,10 @@
 	struct hci_fm_search_rds_station_req *srch_stations =
 		(struct hci_fm_search_rds_station_req *) param;
 
+	if (srch_stations == NULL) {
+		FMDERR("%s, rds stations param is null\n", __func__);
+		return -EINVAL;
+	}
 	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
 		HCI_OCF_FM_SEARCH_RDS_STATIONS);
 	return radio_hci_send_cmd(hdev, opcode, sizeof((*srch_stations)),
@@ -939,6 +997,10 @@
 	struct hci_fm_search_station_list_req *srch_list =
 		(struct hci_fm_search_station_list_req *) param;
 
+	if (srch_list == NULL) {
+		FMDERR("%s, search list param is null\n", __func__);
+		return -EINVAL;
+	}
 	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
 		HCI_OCF_FM_SEARCH_STATIONS_LIST);
 	return radio_hci_send_cmd(hdev, opcode, sizeof((*srch_list)),
@@ -963,6 +1025,10 @@
 	struct hci_fm_rds_grp_req *fm_grp_mask =
 		(struct hci_fm_rds_grp_req *)param;
 
+	if (fm_grp_mask == NULL) {
+		FMDERR("%s, grp mask param is null\n", __func__);
+		return -EINVAL;
+	}
 	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
 		HCI_OCF_FM_RDS_GRP);
 	return radio_hci_send_cmd(hdev, opcode, sizeof(*fm_grp_mask),
@@ -1001,6 +1067,10 @@
 	struct hci_fm_def_data_rd_req *def_data_rd =
 		(struct hci_fm_def_data_rd_req *) param;
 
+	if (def_data_rd == NULL) {
+		FMDERR("%s, def data read param is null\n", __func__);
+		return -EINVAL;
+	}
 	opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
 		HCI_OCF_FM_DEFAULT_DATA_READ);
 	return radio_hci_send_cmd(hdev, opcode, sizeof((*def_data_rd)),
@@ -1014,6 +1084,10 @@
 	struct hci_fm_def_data_wr_req *def_data_wr =
 		(struct hci_fm_def_data_wr_req *) param;
 
+	if (def_data_wr == NULL) {
+		FMDERR("%s, def data write param is null\n", __func__);
+		return -EINVAL;
+	}
 	opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
 		HCI_OCF_FM_DEFAULT_DATA_WRITE);
 
@@ -1083,6 +1157,10 @@
 	__u16 opcode = 0;
 	struct hci_fm_riva_data *peek_data = (struct hci_fm_riva_data *)param;
 
+	if (peek_data == NULL) {
+		FMDERR("%s, peek data param is null\n", __func__);
+		return -EINVAL;
+	}
 	opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
 		HCI_OCF_FM_PEEK_DATA);
 	return radio_hci_send_cmd(hdev, opcode, sizeof((*peek_data)),
@@ -1094,6 +1172,10 @@
 	__u16 opcode = 0;
 	struct hci_fm_riva_poke *poke_data = (struct hci_fm_riva_poke *) param;
 
+	if (poke_data == NULL) {
+		FMDERR("%s, poke data param is null\n", __func__);
+		return -EINVAL;
+	}
 	opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
 		HCI_OCF_FM_POKE_DATA);
 	return radio_hci_send_cmd(hdev, opcode, sizeof((*poke_data)),
@@ -1106,6 +1188,10 @@
 	__u16 opcode = 0;
 	struct hci_fm_ssbi_peek *ssbi_peek = (struct hci_fm_ssbi_peek *) param;
 
+	if (ssbi_peek == NULL) {
+		FMDERR("%s, ssbi peek param is null\n", __func__);
+		return -EINVAL;
+	}
 	opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
 		HCI_OCF_FM_SSBI_PEEK_REG);
 	return radio_hci_send_cmd(hdev, opcode, sizeof((*ssbi_peek)),
@@ -1118,6 +1204,10 @@
 	__u16 opcode = 0;
 	struct hci_fm_ssbi_req *ssbi_poke = (struct hci_fm_ssbi_req *) param;
 
+	if (ssbi_poke == NULL) {
+		FMDERR("%s, ssbi poke param is null\n", __func__);
+		return -EINVAL;
+	}
 	opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
 		HCI_OCF_FM_SSBI_POKE_REG);
 	return radio_hci_send_cmd(hdev, opcode, sizeof((*ssbi_poke)),
@@ -1139,7 +1229,13 @@
 {
 	struct hci_fm_ch_det_threshold *ch_det_th =
 			 (struct hci_fm_ch_det_threshold *) param;
-	u16 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+	u16 opcode;
+
+	if (ch_det_th == NULL) {
+		FMDERR("%s, channel det thrshld is null\n", __func__);
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
 		HCI_OCF_FM_SET_CH_DET_THRESHOLD);
 	return radio_hci_send_cmd(hdev, opcode, sizeof((*ch_det_th)),
 		ch_det_th);
@@ -1183,9 +1279,13 @@
 			unsigned long param, __u32 timeout)
 {
 	int err = 0;
-
 	DECLARE_WAITQUEUE(wait, current);
 
+	if (unlikely(hdev == NULL)) {
+		FMDERR("%s, hci dev is null\n", __func__);
+		return -EINVAL;
+	}
+
 	mutex_lock(&iris_fm);
 	hdev->req_status = HCI_REQ_PEND;
 
@@ -1208,11 +1308,6 @@
 	case HCI_REQ_STATUS:
 		err = radio_hci_err(hdev->req_result);
 		break;
-
-	case HCI_REQ_CANCELED:
-		err = -hdev->req_result;
-		break;
-
 	default:
 		err = -ETIMEDOUT;
 		break;
@@ -1239,7 +1334,13 @@
 static inline int hci_conf_event_mask(__u8 *arg,
 		struct radio_hci_dev *hdev)
 {
-	u8 event_mask = *arg;
+	u8 event_mask;
+
+	if (arg == NULL) {
+		FMDERR("%s, arg is null\n", __func__);
+		return -EINVAL;
+	}
+	event_mask = *arg;
 	return  radio_hci_request(hdev, hci_fm_set_event_mask,
 				event_mask, RADIO_HCI_TIMEOUT);
 }
@@ -1270,8 +1371,13 @@
 static int hci_fm_tune_station(__u32 *arg, struct radio_hci_dev *hdev)
 {
 	int ret = 0;
-	__u32 tune_freq = *arg;
+	__u32 tune_freq;
 
+	if (arg == NULL) {
+		FMDERR("%s, arg is null\n", __func__);
+		return -EINVAL;
+	}
+	tune_freq = *arg;
 	ret = radio_hci_request(hdev, hci_fm_tune_station_req, tune_freq,
 		RADIO_HCI_TIMEOUT);
 
@@ -1305,8 +1411,13 @@
 static int hci_fm_set_antenna(__u8 *arg, struct radio_hci_dev *hdev)
 {
 	int ret = 0;
-	__u8 antenna = *arg;
+	__u8 antenna;
 
+	if (arg == NULL) {
+		FMDERR("%s, arg is null\n", __func__);
+		return -EINVAL;
+	}
+	antenna = *arg;
 	ret = radio_hci_request(hdev, hci_fm_set_antenna_req, antenna,
 		RADIO_HCI_TIMEOUT);
 
@@ -1317,8 +1428,13 @@
 	struct radio_hci_dev *hdev)
 {
 	int ret = 0;
-	__u8 sig_threshold = *arg;
+	__u8 sig_threshold;
 
+	if (arg == NULL) {
+		FMDERR("%s, arg is null\n", __func__);
+		return -EINVAL;
+	}
+	sig_threshold = *arg;
 	ret = radio_hci_request(hdev, hci_fm_set_sig_threshold_req,
 		sig_threshold, RADIO_HCI_TIMEOUT);
 
@@ -1377,8 +1493,13 @@
 static int hci_fm_rds_grps_process(__u32 *arg, struct radio_hci_dev *hdev)
 {
 	int ret = 0;
-	__u32 fm_grps_process = *arg;
+	__u32 fm_grps_process;
 
+	if (arg == NULL) {
+		FMDERR("%s, arg is null\n", __func__);
+		return -EINVAL;
+	}
+	fm_grps_process = *arg;
 	ret = radio_hci_request(hdev, hci_fm_rds_grp_process_req,
 		fm_grps_process, RADIO_HCI_TIMEOUT);
 
@@ -1410,8 +1531,13 @@
 int hci_fm_do_calibration(__u8 *arg, struct radio_hci_dev *hdev)
 {
 	int ret = 0;
-	__u8 mode = *arg;
+	__u8 mode;
 
+	if (arg == NULL) {
+		FMDERR("%s, arg is null\n", __func__);
+		return -EINVAL;
+	}
+	mode = *arg;
 	ret = radio_hci_request(hdev, hci_fm_do_calibration_req, mode,
 		RADIO_HCI_TIMEOUT);
 
@@ -1421,7 +1547,13 @@
 static int hci_read_grp_counters(__u8 *arg, struct radio_hci_dev *hdev)
 {
 	int ret = 0;
-	__u8 reset_counters = *arg;
+	__u8 reset_counters;
+
+	if (arg == NULL) {
+		FMDERR("%s, arg is null\n", __func__);
+		return -EINVAL;
+	}
+	reset_counters = *arg;
 	ret = radio_hci_request(hdev, hci_read_grp_counters_req,
 		reset_counters, RADIO_HCI_TIMEOUT);
 
@@ -1431,7 +1563,14 @@
 static int hci_set_notch_filter(__u8 *arg, struct radio_hci_dev *hdev)
 {
 	int ret = 0;
-	__u8 notch_filter = *arg;
+	__u8 notch_filter;
+
+	if (arg == NULL) {
+		FMDERR("%s, arg is null\n", __func__);
+		return -EINVAL;
+	}
+
+	notch_filter = *arg;
 	ret = radio_hci_request(hdev, hci_set_notch_filter_req,
 		notch_filter, RADIO_HCI_TIMEOUT);
 
@@ -1505,8 +1644,8 @@
 
 	opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
 		HCI_OCF_FM_SET_CALIBRATION);
-	return radio_hci_send_cmd(hdev, opcode, sizeof(*cal_req),
-		cal_req);
+	return radio_hci_send_cmd(hdev, opcode,
+		sizeof(hci_fm_set_cal_req_proc), cal_req);
 }
 
 static int hci_fm_do_cal_req(struct radio_hci_dev *hdev,
@@ -1623,6 +1762,11 @@
 
 static void radio_hci_req_complete(struct radio_hci_dev *hdev, int result)
 {
+
+	if (unlikely(hdev == NULL)) {
+		FMDERR("%s, hci device is null\n", __func__);
+		return;
+	}
 	hdev->req_result = result;
 	hdev->req_status = HCI_REQ_DONE;
 	wake_up_interruptible(&hdev->req_wait_q);
@@ -1630,6 +1774,10 @@
 
 static void radio_hci_status_complete(struct radio_hci_dev *hdev, int result)
 {
+	if (unlikely(hdev == NULL)) {
+		FMDERR("%s, hci device is null\n", __func__);
+		return;
+	}
 	hdev->req_result = result;
 	hdev->req_status = HCI_REQ_STATUS;
 	wake_up_interruptible(&hdev->req_wait_q);
@@ -1637,10 +1785,13 @@
 
 static void hci_cc_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
 {
-	__u8 status = *((__u8 *) skb->data);
+	__u8 status;
 
-	if (status)
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
 		return;
+	}
+	status = *((__u8 *) skb->data);
 
 	radio_hci_req_complete(hdev, status);
 }
@@ -1648,14 +1799,20 @@
 static void hci_cc_fm_disable_rsp(struct radio_hci_dev *hdev,
 	struct sk_buff *skb)
 {
-	__u8 status = *((__u8 *) skb->data);
+	__u8 status;
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 
-	if (radio == NULL) {
-                FMDERR(":radio is null");
-                return;
-        }
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null");
+		return;
+	}
 
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
+	status = *((__u8 *) skb->data);
 	if ((radio->mode == FM_TURNING_OFF) && (status == 0)) {
 		iris_q_event(radio, IRIS_EVT_RADIO_DISABLED);
 		radio_hci_req_complete(hdev, status);
@@ -1665,54 +1822,71 @@
 	} else if ((radio->mode == FM_RECV) || (radio->mode == FM_TRANS)) {
 		iris_q_event(radio, IRIS_EVT_RADIO_DISABLED);
 		radio->mode = FM_OFF;
+	} else if ((radio->mode == FM_TURNING_OFF) && (status != 0)) {
+		radio_hci_req_complete(hdev, status);
 	}
 }
 
 static void hci_cc_conf_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_fm_conf_rsp  *rsp = (void *)skb->data;
+	struct hci_fm_conf_rsp  *rsp;
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return;
 	}
-	if (rsp->status)
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
 		return;
-
-	radio->recv_conf = rsp->recv_conf_rsp;
+	}
+	rsp = (struct hci_fm_conf_rsp *)skb->data;
+	if (!rsp->status)
+		radio->recv_conf = rsp->recv_conf_rsp;
 	radio_hci_req_complete(hdev, rsp->status);
 }
 
 static void hci_cc_fm_trans_get_conf_rsp(struct radio_hci_dev *hdev,
 		struct sk_buff *skb)
 {
-	struct hci_fm_get_trans_conf_rsp  *rsp = (void *)skb->data;
+	struct hci_fm_get_trans_conf_rsp  *rsp;
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return;
 	}
-
-	if (rsp->status)
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
 		return;
-	memcpy((void *)&radio->trans_conf,  (void*)&rsp->trans_conf_rsp,
+	}
+
+	rsp = (struct hci_fm_get_trans_conf_rsp *)skb->data;
+	if (!rsp->status)
+		memcpy((void *)&radio->trans_conf,
+			(void *)&rsp->trans_conf_rsp,
 			sizeof(rsp->trans_conf_rsp));
+
 	radio_hci_req_complete(hdev, rsp->status);
 }
 
 static void hci_cc_fm_enable_rsp(struct radio_hci_dev *hdev,
 	struct sk_buff *skb)
 {
-	struct hci_fm_conf_rsp  *rsp = (void *)skb->data;
+	struct hci_fm_conf_rsp  *rsp;
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return;
 	}
 
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
+	rsp = (struct hci_fm_conf_rsp *)skb->data;
 	if (rsp->status) {
 		radio_hci_req_complete(hdev, rsp->status);
 		return;
@@ -1732,18 +1906,21 @@
 static void hci_cc_fm_trans_set_conf_rsp(struct radio_hci_dev *hdev,
 	struct sk_buff *skb)
 {
-	struct hci_fm_conf_rsp  *rsp = (void *)skb->data;
+	struct hci_fm_conf_rsp  *rsp;
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return;
 	}
 
-	if (rsp->status)
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
 		return;
-
-	iris_q_event(radio, HCI_EV_CMD_COMPLETE);
+	}
+	rsp = (struct hci_fm_conf_rsp  *)skb->data;
+	if (!rsp->status)
+		iris_q_event(radio, HCI_EV_CMD_COMPLETE);
 
 	radio_hci_req_complete(hdev, rsp->status);
 }
@@ -1752,31 +1929,41 @@
 static void hci_cc_sig_threshold_rsp(struct radio_hci_dev *hdev,
 		struct sk_buff *skb)
 {
-	struct hci_fm_sig_threshold_rsp  *rsp = (void *)skb->data;
+	struct hci_fm_sig_threshold_rsp  *rsp;
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return;
 	}
-
-	if (rsp->status)
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
 		return;
+	}
 
-	memcpy(&radio->sig_th, rsp, sizeof(struct hci_fm_sig_threshold_rsp));
+	rsp = (struct hci_fm_sig_threshold_rsp  *)skb->data;
+	if (!rsp->status)
+		memcpy(&radio->sig_th, rsp,
+			sizeof(struct hci_fm_sig_threshold_rsp));
+
 	radio_hci_req_complete(hdev, rsp->status);
 }
 
 static void hci_cc_station_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
 {
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
-	struct hci_fm_station_rsp *rsp = (void *)skb->data;
+	struct hci_fm_station_rsp *rsp;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return;
 	}
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
 
+	rsp = (struct hci_fm_station_rsp *)skb->data;
 	radio->fm_st_rsp = *(rsp);
 
 	/* Tune is always succesful */
@@ -1785,31 +1972,41 @@
 
 static void hci_cc_prg_srv_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_fm_prgm_srv_rsp  *rsp = (void *)skb->data;
+	struct hci_fm_prgm_srv_rsp  *rsp;
 
-	if (rsp->status)
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
 		return;
+	}
+
+	rsp = (struct hci_fm_prgm_srv_rsp  *)skb->data;
 
 	radio_hci_req_complete(hdev, rsp->status);
 }
 
 static void hci_cc_rd_txt_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_fm_radio_txt_rsp  *rsp = (void *)skb->data;
+	struct hci_fm_radio_txt_rsp  *rsp;
 
-	if (rsp->status)
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
 		return;
+	}
 
+	rsp = (struct hci_fm_radio_txt_rsp  *)skb->data;
 	radio_hci_req_complete(hdev, rsp->status);
 }
 
 static void hci_cc_af_list_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_fm_af_list_rsp  *rsp = (void *)skb->data;
+	struct hci_fm_af_list_rsp  *rsp;
 
-	if (rsp->status)
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
 		return;
+	}
 
+	rsp = (struct hci_fm_af_list_rsp  *)skb->data;
 	radio_hci_req_complete(hdev, rsp->status);
 }
 
@@ -1817,20 +2014,25 @@
 	struct sk_buff *skb)
 {
 	struct v4l2_capability *v4l_cap;
-	struct hci_fm_feature_list_rsp  *rsp = (void *)skb->data;
+	struct hci_fm_feature_list_rsp  *rsp;
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return;
 	}
 
-	v4l_cap = radio->g_cap;
-
-	if (rsp->status)
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
 		return;
-	v4l_cap->capabilities = (rsp->feature_mask & 0x000002) |
-		(rsp->feature_mask & 0x000001);
+	}
+
+	rsp = (struct hci_fm_feature_list_rsp  *)skb->data;
+	v4l_cap = &radio->g_cap;
+
+	if (!rsp->status)
+		v4l_cap->capabilities = (rsp->feature_mask & 0x000002) |
+						(rsp->feature_mask & 0x000001);
 
 	radio_hci_req_complete(hdev, rsp->status);
 }
@@ -1839,17 +2041,20 @@
 	struct sk_buff *skb)
 {
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
-	struct hci_fm_dbg_param_rsp *rsp = (void *)skb->data;
+	struct hci_fm_dbg_param_rsp *rsp;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return;
 	}
 
-	radio->st_dbg_param = *(rsp);
-	if (radio->st_dbg_param.status)
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
 		return;
+	}
 
+	rsp = (struct hci_fm_dbg_param_rsp *)skb->data;
+	radio->st_dbg_param = *(rsp);
 	radio_hci_req_complete(hdev, radio->st_dbg_param.status);
 }
 
@@ -1858,7 +2063,7 @@
 {
 	struct kfifo *data_b;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return;
 	}
@@ -1871,46 +2076,55 @@
 		struct sk_buff *skb)
 {
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
-	__u8 status = *((__u8 *) skb->data);
+	__u8 status;
 	int len;
 	char *data;
 
-	if (status)
-		return;
-	len = skb->data[RIVA_PEEK_LEN_OFSET] + RIVA_PEEK_PARAM;
-	data = kmalloc(len, GFP_ATOMIC);
-
-	if (!data) {
-		FMDERR("Memory allocation failed");
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
 		return;
 	}
+	status = *((__u8 *) skb->data);
+	if (!status) {
+		len = skb->data[RIVA_PEEK_LEN_OFSET] + RIVA_PEEK_PARAM;
+		data = kmalloc(len, GFP_ATOMIC);
 
-	memcpy(data, &skb->data[PEEK_DATA_OFSET], len);
-	iris_q_evt_data(radio, data, len, IRIS_BUF_PEEK);
+		if (data != NULL) {
+			memcpy(data, &skb->data[PEEK_DATA_OFSET], len);
+			iris_q_evt_data(radio, data, len, IRIS_BUF_PEEK);
+			kfree(data);
+		} else {
+			FMDERR("Memory allocation failed");
+		}
+	}
+
 	radio_hci_req_complete(hdev, status);
-	kfree(data);
-
 }
 
 static void hci_cc_riva_read_default_rsp(struct radio_hci_dev *hdev,
 		struct sk_buff *skb)
 {
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
-	__u8 status = *((__u8 *) skb->data);
+	__u8 status;
 	__u8 len;
 
-        if (radio == NULL) {
-                FMDERR(":radio is null");
-                return;
-        }
-
-	if (status)
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null");
 		return;
-	len = skb->data[1];
-
-	memset(&radio->default_data, 0 , sizeof(struct hci_fm_data_rd_rsp));
-	memcpy(&radio->default_data, &skb->data[0], len+2);
-	iris_q_evt_data(radio, &skb->data[0], len+2, IRIS_BUF_RD_DEFAULT);
+	}
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+	status = *((__u8 *) skb->data);
+	if (!status) {
+		len = skb->data[1];
+		memset(&radio->default_data, 0,
+			sizeof(struct hci_fm_data_rd_rsp));
+		memcpy(&radio->default_data, &skb->data[0], len+2);
+		iris_q_evt_data(radio, &skb->data[0], len+2,
+				IRIS_BUF_RD_DEFAULT);
+	}
 	radio_hci_req_complete(hdev, status);
 }
 
@@ -1918,41 +2132,53 @@
 		struct sk_buff *skb)
 {
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
-	__u8 status = *((__u8 *) skb->data);
+	__u8 status;
 	char *data;
 
-	if (status)
-		return;
-	data = kmalloc(SSBI_PEEK_LEN, GFP_ATOMIC);
-	if (!data) {
-		FMDERR("Memory allocation failed");
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
 		return;
 	}
+	status = *((__u8 *) skb->data);
+	if (!status) {
+		data = kmalloc(SSBI_PEEK_LEN, GFP_ATOMIC);
+		if (data != NULL) {
+			data[0] = skb->data[PEEK_DATA_OFSET];
+			iris_q_evt_data(radio, data, SSBI_PEEK_LEN,
+					IRIS_BUF_SSBI_PEEK);
+			kfree(data);
+		} else {
+			FMDERR("Memory allocation failed");
+		}
+	}
 
-	data[0] = skb->data[PEEK_DATA_OFSET];
-	iris_q_evt_data(radio, data, SSBI_PEEK_LEN, IRIS_BUF_SSBI_PEEK);
 	radio_hci_req_complete(hdev, status);
-	kfree(data);
 }
 
 static void hci_cc_rds_grp_cntrs_rsp(struct radio_hci_dev *hdev,
 		struct sk_buff *skb)
 {
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
-	__u8 status = *((__u8 *) skb->data);
+	__u8 status;
 	char *data;
-	if (status)
-		return;
-	data = kmalloc(RDS_GRP_CNTR_LEN, GFP_ATOMIC);
-	if (!data) {
-		FMDERR("memory allocation failed");
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
 		return;
 	}
-	memcpy(data, &skb->data[1], RDS_GRP_CNTR_LEN);
-	iris_q_evt_data(radio, data, RDS_GRP_CNTR_LEN, IRIS_BUF_RDS_CNTRS);
+	status = *((__u8 *) skb->data);
+	if (!status) {
+		data = kmalloc(RDS_GRP_CNTR_LEN, GFP_ATOMIC);
+		if (data != NULL) {
+			memcpy(data, &skb->data[1], RDS_GRP_CNTR_LEN);
+			iris_q_evt_data(radio, data, RDS_GRP_CNTR_LEN,
+						IRIS_BUF_RDS_CNTRS);
+			kfree(data);
+		} else {
+			FMDERR("memory allocation failed");
+		}
+	}
 	radio_hci_req_complete(hdev, status);
-	kfree(data);
-
 }
 
 static void hci_cc_do_calibration_rsp(struct radio_hci_dev *hdev,
@@ -1960,22 +2186,23 @@
 {
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 	static struct hci_cc_do_calibration_rsp rsp ;
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
 	rsp.status = skb->data[0];
 	rsp.mode = skb->data[CALIB_MODE_OFSET];
 
-	if (rsp.status) {
-		FMDERR("status = %d", rsp.status);
-		return;
-	}
-	if (rsp.mode == PROCS_CALIB_MODE) {
-		memcpy(&rsp.data[0], &skb->data[CALIB_DATA_OFSET],
+	if (!rsp.status) {
+		if (rsp.mode == PROCS_CALIB_MODE) {
+			memcpy(&rsp.data[0], &skb->data[CALIB_DATA_OFSET],
 				PROCS_CALIB_SIZE);
-	iris_q_evt_data(radio, rsp.data, PROCS_CALIB_SIZE,
+			iris_q_evt_data(radio, rsp.data, PROCS_CALIB_SIZE,
 					IRIS_BUF_CAL_DATA);
-	} else {
-		return;
+		}
 	}
-
 	radio_hci_req_complete(hdev, rsp.status);
 }
 
@@ -1983,27 +2210,37 @@
 		struct sk_buff *skb)
 {
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
-	u8  status = skb->data[0];
+	u8  status;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return;
 	}
-	if (status) {
-		FMDERR("status = %d", status);
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
 		return;
 	}
-	memcpy(&radio->ch_det_threshold, &skb->data[1],
-		sizeof(struct hci_fm_ch_det_threshold));
+	status = skb->data[0];
+	if (!status)
+		memcpy(&radio->ch_det_threshold, &skb->data[1],
+			sizeof(struct hci_fm_ch_det_threshold));
+
 	radio_hci_req_complete(hdev, status);
 }
 
 static inline void hci_cmd_complete_event(struct radio_hci_dev *hdev,
 		struct sk_buff *skb)
 {
-	struct hci_ev_cmd_complete *cmd_compl_ev = (void *) skb->data;
+	struct hci_ev_cmd_complete *cmd_compl_ev;
 	__u16 opcode;
 
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
+	cmd_compl_ev = (struct hci_ev_cmd_complete *)skb->data;
 	skb_pull(skb, sizeof(*cmd_compl_ev));
 
 	opcode = __le16_to_cpu(cmd_compl_ev->cmd_opcode);
@@ -2122,7 +2359,7 @@
 	int i;
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return;
 	}
@@ -2154,6 +2391,7 @@
 		struct sk_buff *skb)
 {
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	radio->search_on = 0;
 	iris_q_event(radio, IRIS_EVT_SEEK_COMPLETE);
 }
 
@@ -2168,10 +2406,15 @@
 	int abs_freq;
 	int len;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return;
 	}
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
 	ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
 	if (!ev) {
 		FMDERR("Memory allocation failed");
@@ -2210,7 +2453,13 @@
 		struct sk_buff *skb)
 {
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
-	__u8 st_status = *((__u8 *) skb->data);
+	__u8 st_status;
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+	st_status = *((__u8 *) skb->data);
 	if (st_status)
 		iris_q_event(radio, IRIS_EVT_STEREO);
 	else
@@ -2230,10 +2479,16 @@
 	radio = video_get_drvdata(video_get_dev());
 	index = RDSGRP_DATA_OFFSET;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return;
 	}
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
 	for (blocknum = 0; blocknum < RDS_BLOCKS_NUM; blocknum++) {
 		temp.rdsBlk[blocknum].rdsLsb =
 			(skb->data[index]);
@@ -2304,6 +2559,10 @@
 	unsigned short int info_byte = 0;
 	unsigned short int byte_pair_index;
 
+	if (rds_buf == NULL) {
+		FMDERR("%s, rds buffer is null\n", __func__);
+		return;
+	}
 	byte_pair_index = AGT(rds_buf->rdsBlk[1].rdsLsb);
 	if (byte_pair_index == 0) {
 		c_byt_pair_index = 0;
@@ -2486,6 +2745,10 @@
 	int len = 0;
 	char *data;
 
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
 	iris_q_event(radio, IRIS_EVT_NEW_RT_RDS);
 
 	while ((skb->data[len+RDS_OFFSET] != 0x0d) && (len < MAX_RT_LENGTH))
@@ -2516,6 +2779,10 @@
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
 	struct hci_ev_af_list ev;
 
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
 	ev.tune_freq = *((int *) &skb->data[0]);
 	ev.pi_code = *((__le16 *) &skb->data[PI_CODE_OFFSET]);
 	ev.af_size = skb->data[AF_SIZE_OFFSET];
@@ -2534,7 +2801,14 @@
 	struct sk_buff *skb)
 {
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
-	__u8 rds_status = skb->data[0];
+	__u8 rds_status;
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
+	rds_status = skb->data[0];
 
 	if (rds_status)
 		iris_q_event(radio, IRIS_EVT_RDS_AVAIL);
@@ -2546,7 +2820,13 @@
 	struct sk_buff *skb)
 {
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
-	u8 serv_avble = skb->data[0];
+	u8 serv_avble;
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+	serv_avble = skb->data[0];
 	if (serv_avble)
 		iris_q_event(radio, IRIS_EVT_ABOVE_TH);
 	else
@@ -2641,13 +2921,15 @@
 {
 	int retval = 0;
 	enum search_t srch;
+	int saved_val;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return -EINVAL;
 	}
 
 	srch = radio->g_search_mode & SRCH_MODE;
+	saved_val = radio->search_on;
 	radio->search_on = on;
 	if (on) {
 		switch (srch) {
@@ -2682,6 +2964,8 @@
 		retval = hci_cmd(HCI_FM_CANCEL_SEARCH_CMD, radio->fm_hdev);
 	}
 
+	if (retval < 0)
+		radio->search_on = saved_val;
 	return retval;
 }
 
@@ -2691,7 +2975,7 @@
 	int rds_grps_proc = 0x00;
 	int retval = 0;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return -EINVAL;
 	}
@@ -2734,18 +3018,22 @@
 static int iris_recv_set_region(struct iris_device *radio, int req_region)
 {
 	int retval;
+	int saved_val;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return -EINVAL;
 	}
-
+	saved_val = radio->region;
 	radio->region = req_region;
 
 	retval = hci_set_fm_recv_conf(
 			&radio->recv_conf,
 			radio->fm_hdev);
 
+	if (retval < 0)
+		radio->region = saved_val;
+
 	return retval;
 }
 
@@ -2753,16 +3041,22 @@
 static int iris_trans_set_region(struct iris_device *radio, int req_region)
 {
 	int retval;
+	int saved_val;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return -EINVAL;
 	}
+
+	saved_val = radio->region;
 	radio->region = req_region;
 
 	retval = hci_set_fm_trans_conf(
 			&radio->trans_conf,
 				radio->fm_hdev);
+
+	if (retval < 0)
+		radio->region = saved_val;
 	return retval;
 }
 
@@ -2772,7 +3066,7 @@
 
 	int retval;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return -EINVAL;
 	}
@@ -2789,6 +3083,10 @@
 	unsigned char i;
 	int retval = -EINVAL;
 
+	if (unlikely(qc == NULL)) {
+		FMDERR("%s, query ctrl is null\n", __func__);
+		return retval;
+	}
 	for (i = 0; i < ARRAY_SIZE(iris_v4l2_queryctrl); i++) {
 		if (qc->id && qc->id == iris_v4l2_queryctrl[i].id) {
 			memcpy(qc, &(iris_v4l2_queryctrl[i]), sizeof(*qc));
@@ -2805,7 +3103,7 @@
 	char cal_mode = 0x00;
 	int retval = 0x00;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return -EINVAL;
 	}
@@ -2844,28 +3142,46 @@
 	struct hci_fm_def_data_rd_req rd;
 	int lsb, msb;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
-		return -EINVAL;
+		retval = -EINVAL;
+		goto END;
 	}
 
+	if (unlikely(ctrl == NULL)) {
+		FMDERR("%s, v4l2 ctrl is null\n", __func__);
+		retval = -EINVAL;
+		goto END;
+	}
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_VOLUME:
 		break;
 	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = radio->mute_mode.hard_mute;
+		if (is_valid_hard_mute(radio->mute_mode.hard_mute))
+			ctrl->value = radio->mute_mode.hard_mute;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCHMODE:
-		ctrl->value = radio->g_search_mode;
+		if (is_valid_srch_mode(radio->g_search_mode))
+			ctrl->value = radio->g_search_mode;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SCANDWELL:
-		ctrl->value = radio->g_scan_time;
+		if (is_valid_scan_dwell_prd(radio->g_scan_time))
+			ctrl->value = radio->g_scan_time;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCHON:
 		ctrl->value = radio->search_on;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_STATE:
-		ctrl->value = radio->mode;
+		if (is_valid_fm_state(radio->mode))
+			ctrl->value = radio->mode;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_IOVERC:
 		retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
@@ -2875,68 +3191,115 @@
 		break;
 	case V4L2_CID_PRIVATE_IRIS_INTDET:
 		retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
-		if (retval < 0)
-			return retval;
-		ctrl->value = radio->st_dbg_param.in_det_out;
+		if (retval == 0)
+			ctrl->value = radio->st_dbg_param.in_det_out;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_REGION:
 		ctrl->value = radio->region;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SIGNAL_TH:
 		retval = hci_cmd(HCI_FM_GET_SIGNAL_TH_CMD, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("Error in get signal threshold %d\n", retval);
-			return retval;
-		}
-		ctrl->value = radio->sig_th.sig_threshold;
+		if ((retval == 0) &&
+			is_valid_sig_th(radio->sig_th.sig_threshold))
+			ctrl->value = radio->sig_th.sig_threshold;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCH_PTY:
-		ctrl->value = radio->srch_rds.srch_pty;
+		if (is_valid_pty(radio->srch_rds.srch_pty))
+			ctrl->value = radio->srch_rds.srch_pty;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCH_PI:
-		ctrl->value = radio->srch_rds.srch_pi;
+		if (is_valid_pi(radio->srch_rds.srch_pi))
+			ctrl->value = radio->srch_rds.srch_pi;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCH_CNT:
-		ctrl->value = radio->srch_st_result.num_stations_found;
+		if (is_valid_srch_station_cnt(
+			radio->srch_st_result.num_stations_found))
+			ctrl->value = radio->srch_st_result.num_stations_found;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_EMPHASIS:
 		if (radio->mode == FM_RECV) {
-			ctrl->value = radio->recv_conf.emphasis;
+			retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
+						radio->fm_hdev);
+			if ((retval == 0) &&
+				is_valid_emphasis(radio->recv_conf.emphasis))
+				ctrl->value = radio->recv_conf.emphasis;
+			else
+				retval = -EINVAL;
 		} else if (radio->mode == FM_TRANS) {
-			ctrl->value = radio->trans_conf.emphasis;
+			retval =  hci_cmd(HCI_FM_GET_TX_CONFIG,
+						radio->fm_hdev);
+			if ((retval == 0) &&
+				is_valid_emphasis(radio->trans_conf.emphasis))
+				ctrl->value = radio->trans_conf.emphasis;
+			else
+				retval = -EINVAL;
 		} else {
-			FMDERR("Error in radio mode"
-				" %d\n", retval);
-			return -EINVAL;
+			retval = -EINVAL;
+			FMDERR("Error in radio mode"" %d\n", retval);
 		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_RDS_STD:
 		if (radio->mode == FM_RECV) {
-			ctrl->value = radio->recv_conf.rds_std;
+			retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
+						radio->fm_hdev);
+			if ((retval == 0) &&
+				is_valid_rds_std(radio->recv_conf.rds_std))
+				ctrl->value = radio->recv_conf.rds_std;
+			else
+				retval = -EINVAL;
 		} else if (radio->mode == FM_TRANS) {
-			ctrl->value = radio->trans_conf.rds_std;
+			retval =  hci_cmd(HCI_FM_GET_TX_CONFIG,
+						radio->fm_hdev);
+			if ((retval == 0) &&
+				is_valid_rds_std(radio->trans_conf.rds_std))
+				ctrl->value = radio->trans_conf.rds_std;
+			else
+				retval = -EINVAL;
 		} else {
+			retval = -EINVAL;
 			FMDERR("Error in radio mode"
 				" %d\n", retval);
-			return -EINVAL;
 		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SPACING:
 		if (radio->mode == FM_RECV) {
-			ctrl->value = radio->recv_conf.ch_spacing;
+			retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
+						radio->fm_hdev);
+			if ((retval == 0) &&
+				is_valid_chan_spacing(
+						radio->recv_conf.ch_spacing))
+				ctrl->value = radio->recv_conf.ch_spacing;
+			else
+				retval = -EINVAL;
 		} else {
+			retval = -EINVAL;
 			FMDERR("Error in radio mode"
 				" %d\n", retval);
-			return -EINVAL;
 		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_RDSON:
 		if (radio->mode == FM_RECV) {
-			ctrl->value = radio->recv_conf.rds_std;
+			retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
+						radio->fm_hdev);
+			if ((retval == 0) &&
+				is_valid_rds_std(radio->recv_conf.rds_std))
+				ctrl->value = radio->recv_conf.rds_std;
+			else
+				retval = -EINVAL;
 		} else {
+			retval = -EINVAL;
 			FMDERR("Error in radio mode"
 				" %d\n", retval);
-			return -EINVAL;
 		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_RDSGROUP_MASK:
@@ -2956,7 +3319,12 @@
 		ctrl->value = radio->g_antenna;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SOFT_MUTE:
-		ctrl->value = radio->mute_mode.soft_mute;
+		retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
+		if ((retval == 0) &&
+			is_valid_soft_mute(radio->mute_mode.soft_mute))
+			ctrl->value = radio->mute_mode.soft_mute;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_DO_CALIBRATION:
 		retval = iris_do_calibration(radio);
@@ -2965,47 +3333,30 @@
 		if (radio->mode == FM_RECV) {
 			retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD,
 						 radio->fm_hdev);
-			if (retval < 0) {
-				FMDERR("Get SINR Failed");
-				return retval;
-			}
-			ctrl->value = radio->fm_st_rsp.station_rsp.sinr;
-
+			if (retval == 0)
+				ctrl->value = radio->fm_st_rsp.station_rsp.sinr;
 		} else
 			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_INTF_HIGH_THRESHOLD:
 		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("Get High det threshold failed %x", retval);
-			return retval;
-		}
-		ctrl->value = radio->ch_det_threshold.high_th;
+		if (retval == 0)
+			ctrl->value = radio->ch_det_threshold.high_th;
 		break;
 	case V4L2_CID_PRIVATE_INTF_LOW_THRESHOLD:
 		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("Get Low det threshold failed %x", retval);
-			return retval;
-		}
-		ctrl->value = radio->ch_det_threshold.low_th;
+		if (retval == 0)
+			ctrl->value = radio->ch_det_threshold.low_th;
 		break;
 	case V4L2_CID_PRIVATE_SINR_THRESHOLD:
 		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("Get SINR threshold failed %x", retval);
-			return retval;
-		}
-		ctrl->value = radio->ch_det_threshold.sinr;
+		if (retval == 0)
+			ctrl->value = radio->ch_det_threshold.sinr;
 		break;
 	case V4L2_CID_PRIVATE_SINR_SAMPLES:
 		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("Get SINR samples failed %x", retval);
-			return retval;
-		}
-
-		ctrl->value = radio->ch_det_threshold.sinr_samples;
+		if (retval == 0)
+			ctrl->value = radio->ch_det_threshold.sinr_samples;
 		break;
 	case V4L2_CID_PRIVATE_VALID_CHANNEL:
 		ctrl->value = radio->is_station_valid;
@@ -3017,13 +3368,11 @@
 		rd.param = 0;
 
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("Get AF Jump Threshold failed %x", retval);
-			return retval;
+		if (retval == 0) {
+			lsb = radio->default_data.data[AF_RMSSI_TH_LSB_OFFSET];
+			msb = radio->default_data.data[AF_RMSSI_TH_MSB_OFFSET];
+			ctrl->value = ((msb << 8) | lsb);
 		}
-		lsb = radio->default_data.data[AF_RMSSI_TH_LSB_OFFSET];
-		msb = radio->default_data.data[AF_RMSSI_TH_MSB_OFFSET];
-		ctrl->value = ((msb << 8) | lsb);
 		break;
 	case V4L2_CID_PRIVATE_AF_RMSSI_SAMPLES:
 		rd.mode = FM_RDS_CNFG_MODE;
@@ -3032,11 +3381,9 @@
 		rd.param = 0;
 
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("Get AF jump rmssi samples failed %x", retval);
-			return retval;
-		}
-		ctrl->value = radio->default_data.data[AF_RMSSI_SAMPLES_OFFSET];
+		if (retval == 0)
+			ctrl->value =
+			radio->default_data.data[AF_RMSSI_SAMPLES_OFFSET];
 		break;
 	case V4L2_CID_PRIVATE_GOOD_CH_RMSSI_TH:
 		rd.mode = FM_RX_CONFG_MODE;
@@ -3045,13 +3392,12 @@
 		rd.param = 0;
 
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("get good channel rmssi th failed %x", retval);
-			return retval;
+		if (retval == 0) {
+			ctrl->value =
+			radio->default_data.data[GD_CH_RMSSI_TH_OFFSET];
+			if (ctrl->value > MAX_GD_CH_RMSSI_TH)
+				ctrl->value -= 256;
 		}
-		ctrl->value = radio->default_data.data[GD_CH_RMSSI_TH_OFFSET];
-		if (ctrl->value > MAX_GD_CH_RMSSI_TH)
-			ctrl->value -= 256;
 		break;
 	case V4L2_CID_PRIVATE_SRCHALGOTYPE:
 		rd.mode = FM_RX_CONFG_MODE;
@@ -3060,11 +3406,9 @@
 		rd.param = 0;
 
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("get search algo type failed %x", retval);
-			return retval;
-		}
-		ctrl->value = radio->default_data.data[SRCH_ALGO_TYPE_OFFSET];
+		if (retval == 0)
+			ctrl->value =
+			radio->default_data.data[SRCH_ALGO_TYPE_OFFSET];
 		break;
 	case V4L2_CID_PRIVATE_SINRFIRSTSTAGE:
 		rd.mode = FM_RX_CONFG_MODE;
@@ -3073,13 +3417,12 @@
 		rd.param = 0;
 
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("default data read failed %x", retval);
-			return retval;
+		if (retval == 0) {
+			ctrl->value =
+			radio->default_data.data[SINRFIRSTSTAGE_OFFSET];
+			if (ctrl->value > MAX_SINR_FIRSTSTAGE)
+				ctrl->value -= 256;
 		}
-		ctrl->value = radio->default_data.data[SINRFIRSTSTAGE_OFFSET];
-		if (ctrl->value > MAX_SINR_FIRSTSTAGE)
-			ctrl->value -= 256;
 		break;
 	case V4L2_CID_PRIVATE_RMSSIFIRSTSTAGE:
 		rd.mode = FM_RX_CONFG_MODE;
@@ -3088,13 +3431,12 @@
 		rd.param = 0;
 
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("default data read failed %x", retval);
-			return retval;
+		if (retval == 0) {
+			ctrl->value =
+			radio->default_data.data[RMSSIFIRSTSTAGE_OFFSET];
+			if (ctrl->value > MAX_RMSSI_FIRSTSTAGE)
+				ctrl->value -= 256;
 		}
-		ctrl->value = radio->default_data.data[RMSSIFIRSTSTAGE_OFFSET];
-		if (ctrl->value > MAX_RMSSI_FIRSTSTAGE)
-			ctrl->value -= 256;
 		break;
 	case V4L2_CID_PRIVATE_CF0TH12:
 		rd.mode = FM_RX_CONFG_MODE;
@@ -3103,26 +3445,31 @@
 		rd.param = 0;
 
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("default data read failed %x", retval);
-			return retval;
+		if (retval == 0) {
+			ctrl->value =
+			radio->default_data.data[CF0TH12_BYTE1_OFFSET];
+			cf0 = radio->default_data.data[CF0TH12_BYTE2_OFFSET];
+			ctrl->value |= (cf0 << 8);
+			cf0 = radio->default_data.data[CF0TH12_BYTE3_OFFSET];
+			ctrl->value |= (cf0 << 16);
+			cf0 = radio->default_data.data[CF0TH12_BYTE4_OFFSET];
+			if (cf0 > 127)
+				cf0 -= 256;
+			ctrl->value |= (cf0 << 24);
 		}
-		ctrl->value = radio->default_data.data[CF0TH12_BYTE1_OFFSET];
-		cf0 = radio->default_data.data[CF0TH12_BYTE2_OFFSET];
-		ctrl->value |= (cf0 << 8);
-		cf0 = radio->default_data.data[CF0TH12_BYTE3_OFFSET];
-		ctrl->value |= (cf0 << 16);
-		cf0 = radio->default_data.data[CF0TH12_BYTE4_OFFSET];
-		if (cf0 > 127)
-			cf0 -= 256;
-		ctrl->value |= (cf0 << 24);
 		break;
 	default:
 		retval = -EINVAL;
+		break;
 	}
+
+END:
+	if (retval > 0)
+		retval = -EINVAL;
 	if (retval < 0)
 		FMDERR("get control failed with %d, id: %d\n",
 			retval, ctrl->id);
+
 	return retval;
 }
 
@@ -3134,24 +3481,38 @@
 	struct iris_device *radio = video_get_drvdata(video_devdata(file));
 	struct hci_fm_def_data_rd_req default_data_rd;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
-		return -EINVAL;
+		retval = -EINVAL;
+		goto END;
 	}
 
+	if (unlikely((ctrl == NULL)) || unlikely((ctrl->count == 0))
+		|| unlikely((ctrl->controls == NULL))) {
+		FMDERR("%s, invalid v4l2 ctrl\n", __func__);
+		retval = -EINVAL;
+		goto END;
+	}
 	switch ((ctrl->controls[0]).id) {
 	case V4L2_CID_PRIVATE_IRIS_READ_DEFAULT:
 		data = (ctrl->controls[0]).string;
 		memset(&default_data_rd, 0, sizeof(default_data_rd));
 		if (copy_from_user(&default_data_rd.mode, data,
-					sizeof(default_data_rd)))
-			return -EFAULT;
+					sizeof(default_data_rd))) {
+			retval = -EFAULT;
+			goto END;
+		}
 		retval = hci_def_data_read(&default_data_rd, radio->fm_hdev);
 		break;
 	default:
 		retval = -EINVAL;
+		break;
 	}
 
+END:
+	if (retval > 0)
+		retval = -EINVAL;
+
 	return retval;
 }
 
@@ -3159,7 +3520,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;
@@ -3168,50 +3529,72 @@
 	struct iris_device *radio = video_get_drvdata(video_devdata(file));
 	char *data = NULL;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
-		return -EINVAL;
+		retval = -EINVAL;
+		goto END;
 	}
+
+	if (unlikely((ctrl == NULL)) || unlikely((ctrl->count == 0))
+		|| unlikely((ctrl->controls == NULL))) {
+		FMDERR("%s, invalid v4l2 ctrl\n", __func__);
+		retval = -EINVAL;
+		goto END;
+	}
+
 	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,
-				data, bytes_to_copy))
-				return -EFAULT;
-		tx_ps.ps_control =  0x01;
-		tx_ps.pi = radio->pi;
-		tx_ps.pty = radio->pty;
-		tx_ps.ps_repeatcount = radio->ps_repeatcount;
-		tx_ps.ps_num = (bytes_to_copy / PS_STRING_LEN);
+				data, bytes_to_copy)) {
+			FMDERR("%s: copy from user for tx ps name failed\n",
+				__func__);
+			retval = -EFAULT;
+			goto END;
+		} else {
+			tx_ps.ps_control =  0x01;
+			tx_ps.pi = radio->pi;
+			tx_ps.pty = radio->pty;
+			tx_ps.ps_repeatcount = radio->ps_repeatcount;
+			tx_ps.ps_num = (bytes_to_copy / PS_STRING_LEN);
 
-		retval = radio_hci_request(radio->fm_hdev, hci_trans_ps_req,
-				(unsigned long)&tx_ps, RADIO_HCI_TIMEOUT);
+			retval = radio_hci_request(radio->fm_hdev,
+							hci_trans_ps_req,
+							(unsigned long)&tx_ps,
+							RADIO_HCI_TIMEOUT);
+		}
 		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);
 
 		if (copy_from_user(tx_rt.rt_data,
-				data, bytes_to_copy))
-				return -EFAULT;
+				data, bytes_to_copy)) {
+			FMDERR("%s: copy from user for tx rt failed\n",
+				 __func__);
+			retval = -EFAULT;
+			goto END;
+		} else {
+			tx_rt.rt_control = 0x01;
+			tx_rt.pi = radio->pi;
+			tx_rt.pty = radio->pty;
+			tx_rt.rt_len = bytes_to_copy;
 
-		tx_rt.rt_control =  0x01;
-		tx_rt.pi = radio->pi;
-		tx_rt.pty = radio->pty;
-		tx_rt.rt_len = bytes_to_copy;
-
-		retval = radio_hci_request(radio->fm_hdev, hci_trans_rt_req,
-				(unsigned long)&tx_rt, RADIO_HCI_TIMEOUT);
+			retval = radio_hci_request(radio->fm_hdev,
+							hci_trans_rt_req,
+							(unsigned long)&tx_rt,
+							RADIO_HCI_TIMEOUT);
+		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_WRITE_DEFAULT:
 		data = (ctrl->controls[0]).string;
@@ -3226,7 +3609,8 @@
 		 */
 		if (ctrl->controls[0].size > (DEFAULT_DATA_SIZE + 2)) {
 			pr_err("%s: Default data buffer overflow!\n", __func__);
-			return -EINVAL;
+			retval = -EINVAL;
+			goto END;
 		}
 
 		/* copy only 'size' bytes of data as requested by user */
@@ -3235,7 +3619,8 @@
 		if (retval > 0) {
 			pr_err("%s: Failed to copy %d bytes of default data"
 				" passed by user\n", __func__, retval);
-			return -EFAULT;
+			retval = -EFAULT;
+			goto END;
 		}
 		FMDBG("%s: XFR Mode\t: 0x%x\n", __func__, default_data.mode);
 		FMDBG("%s: XFR Data Length\t: %d\n", __func__,
@@ -3250,7 +3635,8 @@
 		if (default_data.length != (ctrl->controls[0].size - 2)) {
 			pr_err("%s: Invalid 'length' parameter passed for "
 				"actual xfr data\n", __func__);
-			return -EINVAL;
+			retval = -EINVAL;
+			goto END;
 		}
 		retval = hci_def_data_write(&default_data, radio->fm_hdev);
 		break;
@@ -3259,24 +3645,32 @@
 		bytes_to_copy = (ctrl->controls[0]).size;
 		if (bytes_to_copy < PROCS_CALIB_SIZE) {
 			FMDERR("data is less than required size");
-			return -EFAULT;
+			retval = -EFAULT;
+			goto END;
 		}
 		memset(proc_cal_req.data, 0, PROCS_CALIB_SIZE);
 		proc_cal_req.mode = PROCS_CALIB_MODE;
 		if (copy_from_user(&proc_cal_req.data[0],
-				data, sizeof(proc_cal_req.data)))
-				return -EFAULT;
+				data, sizeof(proc_cal_req.data))) {
+			retval = -EFAULT;
+			goto END;
+		}
 		retval = radio_hci_request(radio->fm_hdev,
 				hci_fm_set_cal_req_proc,
 				(unsigned long)&proc_cal_req,
 				 RADIO_HCI_TIMEOUT);
-		if (retval < 0)
-			FMDERR("Set Process calibration failed %d", retval);
 		break;
 	default:
 		FMDBG("Shouldn't reach here\n");
 		retval = -1;
+		goto END;
+		break;
 	}
+
+END:
+	if (retval > 0)
+		retval = -EINVAL;
+
 	return retval;
 }
 
@@ -3287,6 +3681,7 @@
 	int retval = 0;
 	unsigned int rds_grps_proc = 0;
 	__u8 temp_val = 0;
+	int saved_val;
 	unsigned long arg = 0;
 	struct hci_fm_tx_ps tx_ps = {0};
 	struct hci_fm_tx_rt tx_rt = {0};
@@ -3295,37 +3690,71 @@
 	char sinr_th, sinr;
 	__u8 intf_det_low_th, intf_det_high_th, intf_det_out;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
-		return -EINVAL;
+		retval = -EINVAL;
+		goto END;
 	}
 
+	if (unlikely(ctrl == NULL)) {
+		FMDERR("%s, v4l2 ctrl is null\n", __func__);
+		retval = -EINVAL;
+		goto END;
+	}
 	switch (ctrl->id) {
 	case V4L2_CID_PRIVATE_IRIS_TX_TONE:
+		if (!is_valid_tone(ctrl->value)) {
+			retval = -EINVAL;
+			FMDERR("%s: tone value is not valid\n", __func__);
+			goto END;
+		}
+		saved_val = radio->tone_freq;
 		radio->tone_freq = ctrl->value;
 		retval = radio_hci_request(radio->fm_hdev,
 				hci_fm_tone_generator, arg,
 				msecs_to_jiffies(RADIO_HCI_TIMEOUT));
-		if (retval < 0)
+		if (retval < 0) {
 			FMDERR("Error while setting the tone %d", retval);
+			radio->tone_freq = saved_val;
+		}
 		break;
 	case V4L2_CID_AUDIO_VOLUME:
 		break;
 	case V4L2_CID_AUDIO_MUTE:
+		if (!is_valid_hard_mute(ctrl->value)) {
+			retval = -EINVAL;
+			FMDERR("%s: hard mute value is not valid\n", __func__);
+			goto END;
+		}
+		saved_val = radio->mute_mode.hard_mute;
 		radio->mute_mode.hard_mute = ctrl->value;
 		radio->mute_mode.soft_mute = IOC_SFT_MUTE;
 		retval = hci_set_fm_mute_mode(
 				&radio->mute_mode,
 				radio->fm_hdev);
-		if (retval < 0)
+		if (retval < 0) {
 			FMDERR("Error while set FM hard mute"" %d\n",
-			retval);
+				retval);
+			radio->mute_mode.hard_mute = saved_val;
+		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCHMODE:
-		radio->g_search_mode = ctrl->value;
+		if (is_valid_srch_mode(ctrl->value)) {
+			radio->g_search_mode = ctrl->value;
+		} else {
+			FMDERR("%s: srch mode is not valid\n", __func__);
+			retval = -EINVAL;
+			goto END;
+		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SCANDWELL:
-		radio->g_scan_time = ctrl->value;
+		if (is_valid_scan_dwell_prd(ctrl->value)) {
+			radio->g_scan_time = ctrl->value;
+		} else {
+			FMDERR("%s: scandwell period is not valid\n", __func__);
+			retval = -EINVAL;
+			goto END;
+		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCHON:
 		iris_search(radio, ctrl->value, SRCH_DIR_UP);
@@ -3333,8 +3762,12 @@
 	case V4L2_CID_PRIVATE_IRIS_STATE:
 		switch (ctrl->value) {
 		case FM_RECV:
-			if (is_enable_rx_possible(radio) != 0)
-				return -EINVAL;
+			if (is_enable_rx_possible(radio) != 0) {
+				FMDERR("%s: fm is not in proper state\n",
+					 __func__);
+				retval = -EINVAL;
+				goto END;
+			}
 			radio->mode = FM_RECV_TURNING_ON;
 			retval = hci_cmd(HCI_FM_ENABLE_RECV_CMD,
 							 radio->fm_hdev);
@@ -3342,14 +3775,16 @@
 				FMDERR("Error while enabling RECV FM"
 							" %d\n", retval);
 				radio->mode = FM_OFF;
-				return retval;
+				goto END;
 			} else {
 				initialise_recv(radio);
 			}
 			break;
 		case FM_TRANS:
-			if (is_enable_tx_possible(radio) != 0)
-				return -EINVAL;
+			if (is_enable_tx_possible(radio) != 0) {
+				retval = -EINVAL;
+				goto END;
+			}
 			radio->mode = FM_TRANS_TURNING_ON;
 			retval = hci_cmd(HCI_FM_ENABLE_TRANS_CMD,
 							 radio->fm_hdev);
@@ -3357,7 +3792,7 @@
 				FMDERR("Error while enabling TRANS FM"
 							" %d\n", retval);
 				radio->mode = FM_OFF;
-				return retval;
+				goto END;
 			} else {
 				initialise_trans(radio);
 			}
@@ -3373,7 +3808,7 @@
 					FMDERR("Err on disable recv FM"
 						   " %d\n", retval);
 					radio->mode = FM_RECV;
-					return retval;
+					goto END;
 				}
 				break;
 			case FM_TRANS:
@@ -3385,7 +3820,7 @@
 					FMDERR("Err disabling trans FM"
 						" %d\n", retval);
 					radio->mode = FM_TRANS;
-					return retval;
+					goto END;
 				}
 				break;
 			default:
@@ -3400,136 +3835,236 @@
 		if (radio->mode == FM_RECV) {
 			retval = iris_recv_set_region(radio, ctrl->value);
 		} else {
-			if (radio->mode == FM_TRANS)
+			if (radio->mode == FM_TRANS) {
 				retval = iris_trans_set_region(radio,
 						ctrl->value);
-			else
+			} else {
+				FMDERR("%s: fm is not in proper state\n",
+					__func__);
 				retval = -EINVAL;
+				goto END;
+			}
 		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SIGNAL_TH:
+		if (!is_valid_sig_th(ctrl->value)) {
+			retval = -EINVAL;
+			FMDERR("%s: sig threshold is not valid\n", __func__);
+			goto END;
+		}
 		temp_val = ctrl->value;
 		retval = hci_fm_set_signal_threshold(
 				&temp_val,
 				radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("Error while setting signal threshold\n");
-			break;
+			goto END;
 		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCH_PTY:
-		radio->srch_rds.srch_pty = ctrl->value;
-		radio->srch_st_list.srch_pty = ctrl->value;
+		if (is_valid_pty(ctrl->value)) {
+			radio->srch_rds.srch_pty = ctrl->value;
+			radio->srch_st_list.srch_pty = ctrl->value;
+		} else {
+			FMDERR("%s: pty is not valid\n", __func__);
+			retval = -EINVAL;
+			goto END;
+		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCH_PI:
-		radio->srch_rds.srch_pi = ctrl->value;
+		if (is_valid_pi(ctrl->value)) {
+			radio->srch_rds.srch_pi = ctrl->value;
+		} else {
+			retval = -EINVAL;
+			FMDERR("%s: Pi is not valid\n", __func__);
+			goto END;
+		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCH_CNT:
-		radio->srch_st_list.srch_list_max = ctrl->value;
+		if (is_valid_srch_station_cnt(ctrl->value)) {
+			radio->srch_st_list.srch_list_max = ctrl->value;
+		} else {
+			retval = -EINVAL;
+			FMDERR("%s: srch station count is not valid\n",
+				__func__);
+			goto END;
+		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SPACING:
+		if (!is_valid_chan_spacing(ctrl->value)) {
+			retval = -EINVAL;
+			FMDERR("%s: channel spacing is not valid\n", __func__);
+			goto END;
+		}
 		if (radio->mode == FM_RECV) {
+			saved_val = radio->recv_conf.ch_spacing;
 			radio->recv_conf.ch_spacing = ctrl->value;
 			retval = hci_set_fm_recv_conf(
 					&radio->recv_conf,
 						radio->fm_hdev);
-			if (retval < 0)
+			if (retval < 0) {
 				FMDERR("Error in setting channel spacing");
+				radio->recv_conf.ch_spacing = saved_val;
+				goto END;
+			}
 		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_EMPHASIS:
+		if (!is_valid_emphasis(ctrl->value)) {
+			retval = -EINVAL;
+			FMDERR("%s, emphasis is not valid\n", __func__);
+			goto END;
+		}
 		switch (radio->mode) {
 		case FM_RECV:
+			saved_val = radio->recv_conf.emphasis;
 			radio->recv_conf.emphasis = ctrl->value;
 			retval = hci_set_fm_recv_conf(
 					&radio->recv_conf,
 						radio->fm_hdev);
-			if (retval < 0)
+			if (retval < 0) {
 				FMDERR("Error in setting emphasis");
+				radio->recv_conf.emphasis = saved_val;
+				goto END;
+			}
 			break;
 		case FM_TRANS:
+			saved_val = radio->trans_conf.emphasis;
 			radio->trans_conf.emphasis = ctrl->value;
 			retval = hci_set_fm_trans_conf(
 					&radio->trans_conf,
 						radio->fm_hdev);
-			if (retval < 0)
+			if (retval < 0) {
 				FMDERR("Error in setting emphasis");
+				radio->trans_conf.emphasis = saved_val;
+				goto END;
+			}
 			break;
 		default:
 			retval = -EINVAL;
+			FMDERR("%s, FM is not in proper state\n", __func__);
+			goto END;
+			break;
 		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_RDS_STD:
+		if (!is_valid_rds_std(ctrl->value)) {
+			retval = -EINVAL;
+			FMDERR("%s: rds std is not valid\n", __func__);
+			goto END;
+		}
 		switch (radio->mode) {
 		case FM_RECV:
+			saved_val = radio->recv_conf.rds_std;
 			radio->recv_conf.rds_std = ctrl->value;
 			retval = hci_set_fm_recv_conf(
 					&radio->recv_conf,
 						radio->fm_hdev);
-			if (retval < 0)
+			if (retval < 0) {
 				FMDERR("Error in rds_std");
+				radio->recv_conf.rds_std = saved_val;
+				goto END;
+			}
 			break;
 		case FM_TRANS:
+			saved_val = radio->trans_conf.rds_std;
 			radio->trans_conf.rds_std = ctrl->value;
 			retval = hci_set_fm_trans_conf(
 					&radio->trans_conf,
 						radio->fm_hdev);
-			if (retval < 0)
+			if (retval < 0) {
 				FMDERR("Error in rds_Std");
+				radio->trans_conf.rds_std = saved_val;
+				goto END;
+			}
 			break;
 		default:
 			retval = -EINVAL;
+			FMDERR("%s: fm is not in proper state\n", __func__);
+			goto END;
+			break;
 		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_RDSON:
+		if (!is_valid_rds_std(ctrl->value)) {
+			retval = -EINVAL;
+			FMDERR("%s: rds std is not valid\n", __func__);
+			goto END;
+		}
 		switch (radio->mode) {
 		case FM_RECV:
+			saved_val = radio->recv_conf.rds_std;
 			radio->recv_conf.rds_std = ctrl->value;
 			retval = hci_set_fm_recv_conf(
 					&radio->recv_conf,
 						radio->fm_hdev);
-			if (retval < 0)
+			if (retval < 0) {
 				FMDERR("Error in rds_std");
+				radio->recv_conf.rds_std = saved_val;
+				goto END;
+			}
 			break;
 		case FM_TRANS:
+			saved_val = radio->trans_conf.rds_std;
 			radio->trans_conf.rds_std = ctrl->value;
 			retval = hci_set_fm_trans_conf(
 					&radio->trans_conf,
 						radio->fm_hdev);
-			if (retval < 0)
+			if (retval < 0) {
 				FMDERR("Error in rds_Std");
+				radio->trans_conf.rds_std = saved_val;
+				goto END;
+			}
 			break;
 		default:
 			retval = -EINVAL;
+			FMDERR("%s: fm is not in proper state\n", __func__);
+			goto END;
+			break;
 		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_RDSGROUP_MASK:
+		saved_val = radio->rds_grp.rds_grp_enable_mask;
 		grp_mask = (grp_mask | oda_agt | ctrl->value);
 		radio->rds_grp.rds_grp_enable_mask = grp_mask;
 		radio->rds_grp.rds_buf_size = 1;
 		radio->rds_grp.en_rds_change_filter = 0;
 		retval = hci_fm_rds_grp(&radio->rds_grp, radio->fm_hdev);
-		if (retval < 0)
+		if (retval < 0) {
 			FMDERR("error in setting group mask\n");
+			radio->rds_grp.rds_grp_enable_mask = saved_val;
+			goto END;
+		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_RDSGROUP_PROC:
+		saved_val = radio->g_rds_grp_proc_ps;
 		rds_grps_proc = radio->g_rds_grp_proc_ps | ctrl->value;
 		radio->g_rds_grp_proc_ps = (rds_grps_proc >> RDS_CONFIG_OFFSET);
 		retval = hci_fm_rds_grps_process(
 				&radio->g_rds_grp_proc_ps,
 				radio->fm_hdev);
+		if (retval < 0) {
+			radio->g_rds_grp_proc_ps = saved_val;
+			goto END;
+		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_RDSD_BUF:
 		radio->rds_grp.rds_buf_size = ctrl->value;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_PSALL:
+		saved_val = radio->g_rds_grp_proc_ps;
 		rds_grps_proc = (ctrl->value << RDS_CONFIG_OFFSET);
 		radio->g_rds_grp_proc_ps |= rds_grps_proc;
 		retval = hci_fm_rds_grps_process(
 				&radio->g_rds_grp_proc_ps,
 				radio->fm_hdev);
+		if (retval < 0) {
+			radio->g_rds_grp_proc_ps = saved_val;
+			goto END;
+		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_AF_JUMP:
+		saved_val = radio->g_rds_grp_proc_ps;
 		/*Clear the current AF jump settings*/
 		radio->g_rds_grp_proc_ps &= ~(1 << RDS_AF_JUMP_OFFSET);
 		radio->af_jump_bit = ctrl->value;
@@ -3539,24 +4074,45 @@
 		retval = hci_fm_rds_grps_process(
 				&radio->g_rds_grp_proc_ps,
 				radio->fm_hdev);
+		if (retval < 0) {
+			radio->g_rds_grp_proc_ps = saved_val;
+			goto END;
+		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_LP_MODE:
 		set_low_power_mode(radio, ctrl->value);
 		break;
 	case V4L2_CID_PRIVATE_IRIS_ANTENNA:
+		if (!is_valid_antenna(ctrl->value)) {
+			retval = -EINVAL;
+			FMDERR("%s: antenna type is not valid\n", __func__);
+			goto END;
+		}
 		temp_val = ctrl->value;
 		retval = hci_fm_set_antenna(&temp_val, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("Set Antenna failed retval = %x", retval);
-			return retval;
+			goto END;
 		}
 		radio->g_antenna =  ctrl->value;
 		break;
 	case V4L2_CID_RDS_TX_PTY:
-		radio->pty = ctrl->value;
+		if (is_valid_pty(ctrl->value)) {
+			radio->pty = ctrl->value;
+		} else {
+			retval = -EINVAL;
+			FMDERR("%s: pty is not valid\n", __func__);
+			goto END;
+		}
 		break;
 	case V4L2_CID_RDS_TX_PI:
-		radio->pi = ctrl->value;
+		if (is_valid_pi(ctrl->value)) {
+			radio->pi = ctrl->value;
+		} else {
+			retval = -EINVAL;
+			FMDERR("%s: pi is not valid\n", __func__);
+			goto END;
+		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_PS_NAME:
 		tx_ps.ps_control =  0x00;
@@ -3569,7 +4125,13 @@
 				(unsigned long)&tx_rt, RADIO_HCI_TIMEOUT);
 		break;
 	case V4L2_CID_PRIVATE_IRIS_TX_SETPSREPEATCOUNT:
-		radio->ps_repeatcount = ctrl->value;
+		if (is_valid_ps_repeat_cnt(ctrl->value)) {
+			radio->ps_repeatcount = ctrl->value;
+		} else {
+			retval = -EINVAL;
+			FMDERR("%s: ps repeat count is not valid\n", __func__);
+			goto END;
+		}
 		break;
 	case V4L2_CID_TUNE_POWER_LEVEL:
 		if (ctrl->value > FM_TX_PWR_LVL_MAX)
@@ -3584,8 +4146,8 @@
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("Default data read failed for PHY_CFG %d\n",
-			retval);
-			break;
+				retval);
+			goto END;
 		}
 		memset(&wrd, 0, sizeof(wrd));
 		wrd.mode = FM_TX_PHY_CFG_MODE;
@@ -3597,40 +4159,58 @@
 		retval = hci_def_data_write(&wrd, radio->fm_hdev);
 		if (retval < 0)
 			FMDERR("Default write failed for PHY_TXGAIN %d\n",
-			retval);
+				retval);
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SOFT_MUTE:
+		if (!is_valid_soft_mute(ctrl->value)) {
+			retval = -EINVAL;
+			FMDERR("%s: soft mute is not valid\n", __func__);
+			goto END;
+		}
+		saved_val = radio->mute_mode.soft_mute;
 		radio->mute_mode.soft_mute = ctrl->value;
 		retval = hci_set_fm_mute_mode(
 				&radio->mute_mode,
 				radio->fm_hdev);
-		if (retval < 0)
+		if (retval < 0) {
 			FMDERR("Error while setting FM soft mute"" %d\n",
-			retval);
+				retval);
+			radio->mute_mode.soft_mute = saved_val;
+			goto END;
+		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_RIVA_ACCS_ADDR:
 		radio->riva_data_req.cmd_params.start_addr = ctrl->value;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_RIVA_ACCS_LEN:
-		if ((ctrl->value > 0) &&
-			(ctrl->value <= MAX_RIVA_PEEK_RSP_SIZE)) {
+		if (is_valid_peek_len(ctrl->value)) {
 			radio->riva_data_req.cmd_params.length = ctrl->value;
 		} else {
-			FMDERR("Length %d is more than the buffer size %d\n",
-			ctrl->value, MAX_RIVA_PEEK_RSP_SIZE);
 			retval = -EINVAL;
+			FMDERR("%s: riva access len is not valid\n", __func__);
+			goto END;
 		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_RIVA_POKE:
-		if (radio->riva_data_req.cmd_params.length <= MAX_RIVA_PEEK_RSP_SIZE) {
-			memcpy(radio->riva_data_req.data, (void *)ctrl->value,
-						radio->riva_data_req.cmd_params.length);
-			radio->riva_data_req.cmd_params.subopcode = RIVA_POKE_OPCODE;
-			retval = hci_poke_data(&radio->riva_data_req , radio->fm_hdev);
+		if (radio->riva_data_req.cmd_params.length <=
+		    MAX_RIVA_PEEK_RSP_SIZE) {
+			retval = copy_from_user(
+					radio->riva_data_req.data,
+					(void *)ctrl->value,
+					radio->riva_data_req.cmd_params.length);
+			if (retval != 0) {
+				retval = -retval;
+				goto END;
+			}
+			radio->riva_data_req.cmd_params.subopcode =
+						RIVA_POKE_OPCODE;
+			retval = hci_poke_data(
+					&radio->riva_data_req,
+					radio->fm_hdev);
 		} else {
-			FMDERR("Can not copy into driver's buffer. Length %d is more than"
-			 "the buffer size %d\n", ctrl->value, MAX_RIVA_PEEK_RSP_SIZE);
+			FMDERR("Can not copy into driver's buffer.\n");
 			retval = -EINVAL;
+			goto END;
 		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SSBI_ACCS_ADDR:
@@ -3651,80 +4231,133 @@
 		hci_ssbi_peek_reg(&radio->ssbi_peek_reg, radio->fm_hdev);
 		break;
 	case V4L2_CID_PRIVATE_IRIS_RDS_GRP_COUNTERS:
-		temp_val = ctrl->value;
-		hci_read_grp_counters(&temp_val, radio->fm_hdev);
+		if (is_valid_reset_cntr(ctrl->value)) {
+			temp_val = ctrl->value;
+			hci_read_grp_counters(&temp_val, radio->fm_hdev);
+		} else {
+			FMDERR("%s: reset counter value is not valid\n",
+				__func__);
+			retval = -EINVAL;
+			goto END;
+		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_HLSI:
+		if (!is_valid_hlsi(ctrl->value)) {
+			FMDERR("%s: hlsi value is not valid\n", __func__);
+			retval = -EINVAL;
+			goto END;
+		}
 		retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
 						radio->fm_hdev);
 		if (retval)
-			break;
+			goto END;
+		saved_val = radio->recv_conf.hlsi;
 		radio->recv_conf.hlsi = ctrl->value;
 		retval = hci_set_fm_recv_conf(
 					&radio->recv_conf,
 						radio->fm_hdev);
+		if (retval < 0)
+			radio->recv_conf.hlsi = saved_val;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SET_NOTCH_FILTER:
-		temp_val = ctrl->value;
-		retval = hci_set_notch_filter(&temp_val, radio->fm_hdev);
+		if (is_valid_notch_filter(ctrl->value)) {
+			temp_val = ctrl->value;
+			retval = hci_set_notch_filter(&temp_val,
+							radio->fm_hdev);
+		} else {
+			FMDERR("%s: notch filter is not valid\n", __func__);
+			retval = -EINVAL;
+			goto END;
+		}
 		break;
 	case V4L2_CID_PRIVATE_INTF_HIGH_THRESHOLD:
+		if (!is_valid_intf_det_hgh_th(ctrl->value)) {
+			FMDERR("%s: intf high threshold is not valid\n",
+				__func__);
+			retval = -EINVAL;
+			goto END;
+		}
 		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("Failed to get chnl det thresholds  %d", retval);
-			return retval;
+			goto END;
 		}
+		saved_val = radio->ch_det_threshold.high_th;
 		radio->ch_det_threshold.high_th = ctrl->value;
 		retval = hci_set_ch_det_thresholds_req(&radio->ch_det_threshold,
 							 radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("Failed to set High det threshold %d ", retval);
-			return retval;
+			radio->ch_det_threshold.high_th = saved_val;
+			goto END;
 		}
 		break;
 
 	case V4L2_CID_PRIVATE_INTF_LOW_THRESHOLD:
+		if (!is_valid_intf_det_low_th(ctrl->value)) {
+			FMDERR("%s: intf det low threshold is not valid\n",
+				__func__);
+			retval = -EINVAL;
+			goto END;
+		}
 		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("Failed to get chnl det thresholds  %d", retval);
-			return retval;
+			goto END;
 		}
+		saved_val = radio->ch_det_threshold.low_th;
 		radio->ch_det_threshold.low_th = ctrl->value;
 		retval = hci_set_ch_det_thresholds_req(&radio->ch_det_threshold,
 							 radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("Failed to Set Low det threshold %d", retval);
-			return retval;
+			radio->ch_det_threshold.low_th = saved_val;
+			goto END;
 		}
 		break;
 
 	case V4L2_CID_PRIVATE_SINR_THRESHOLD:
+		if (!is_valid_sinr_th(ctrl->value)) {
+			FMDERR("%s: sinr threshold is not valid\n", __func__);
+			retval = -EINVAL;
+			goto END;
+		}
 		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("Failed to get chnl det thresholds  %d", retval);
-			return retval;
+			goto END;
 		}
+		saved_val = radio->ch_det_threshold.sinr;
 		radio->ch_det_threshold.sinr = ctrl->value;
 		retval = hci_set_ch_det_thresholds_req(&radio->ch_det_threshold,
 							 radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("Failed to set SINR threshold %d", retval);
-			return retval;
+			radio->ch_det_threshold.sinr = saved_val;
+			goto END;
 		}
 		break;
 
 	case V4L2_CID_PRIVATE_SINR_SAMPLES:
+		if (!is_valid_sinr_samples(ctrl->value)) {
+			FMDERR("%s: sinr samples count is not valid\n",
+				__func__);
+			retval = -EINVAL;
+			goto END;
+		}
 		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("Failed to get chnl det thresholds  %d", retval);
-			return retval;
+			goto END;
 		}
+		saved_val = radio->ch_det_threshold.sinr_samples;
 		radio->ch_det_threshold.sinr_samples = ctrl->value;
 		retval = hci_set_ch_det_thresholds_req(&radio->ch_det_threshold,
 							 radio->fm_hdev);
 	       if (retval < 0) {
 			FMDERR("Failed to set SINR samples  %d", retval);
-			return retval;
+			radio->ch_det_threshold.sinr_samples = saved_val;
+			goto END;
 		}
 		break;
 
@@ -3771,18 +4404,23 @@
 		if (retval < 0) {
 			FMDERR("%s: Failed to determine channel's validity\n",
 				__func__);
-			return retval;
+			goto END;
 		} else {
 			sinr_th = radio->ch_det_threshold.sinr;
 			intf_det_low_th = radio->ch_det_threshold.low_th;
 			intf_det_high_th = radio->ch_det_threshold.high_th;
 		}
-
+		if (!is_valid_sinr_th(sinr_th) ||
+			!is_valid_intf_det_low_th(intf_det_low_th) ||
+			!is_valid_intf_det_hgh_th(intf_det_high_th)) {
+			retval = -EINVAL;
+			goto END;
+		}
 		retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("%s: Failed to determine channel's validity\n",
 				__func__);
-			return retval;
+			goto END;
 		} else
 			sinr = radio->fm_st_rsp.station_rsp.sinr;
 
@@ -3790,7 +4428,7 @@
 		if (retval < 0) {
 			FMDERR("%s: Failed to determine channel's validity\n",
 				 __func__);
-			return retval;
+			goto END;
 		} else
 			intf_det_out = radio->st_dbg_param.in_det_out;
 
@@ -3809,7 +4447,7 @@
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("default data read failed %x", retval);
-			return retval;
+			goto END;
 		}
 		wrd.mode = FM_RDS_CNFG_MODE;
 		wrd.length = FM_RDS_CNFG_LEN;
@@ -3830,7 +4468,7 @@
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("default data read failed %x", retval);
-			return retval;
+			goto END;
 		}
 		wrd.mode = FM_RDS_CNFG_MODE;
 		wrd.length = FM_RDS_CNFG_LEN;
@@ -3850,7 +4488,7 @@
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("default data read failed %x", retval);
-			return retval;
+			goto END;
 		}
 		wrd.mode = FM_RX_CONFG_MODE;
 		wrd.length = FM_RX_CNFG_LEN;
@@ -3870,7 +4508,7 @@
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("default data read failed %x", retval);
-			return retval;
+			goto END;
 		}
 		wrd.mode = FM_RX_CONFG_MODE;
 		wrd.length = FM_RX_CNFG_LEN;
@@ -3890,7 +4528,7 @@
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("default data read failed %x", retval);
-			return retval;
+			goto END;
 		}
 		wrd.mode = FM_RX_CONFG_MODE;
 		wrd.length = FM_RX_CNFG_LEN;
@@ -3910,7 +4548,7 @@
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("default data read failed %x", retval);
-			return retval;
+			goto END;
 		}
 		wrd.mode = FM_RX_CONFG_MODE;
 		wrd.length = FM_RX_CNFG_LEN;
@@ -3930,7 +4568,7 @@
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("default data read failed %x", retval);
-			return retval;
+			goto END;
 		}
 		wrd.mode = FM_RX_CONFG_MODE;
 		wrd.length = FM_RX_CNFG_LEN;
@@ -3953,7 +4591,7 @@
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("default data read failed for PS0 %x", retval);
-			return retval;
+			goto END;
 		}
 		wrd.mode = RDS_PS0_XFR_MODE;
 		wrd.length = RDS_PS0_LEN;
@@ -3967,7 +4605,13 @@
 		break;
 	default:
 		retval = -EINVAL;
+		break;
 	}
+
+END:
+	if (retval > 0)
+		retval = -EINVAL;
+
 	return retval;
 }
 
@@ -3982,7 +4626,7 @@
 	/* Pass the mode of SPUR_CLK */
 	default_data.mode = CKK_SPUR;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return -EINVAL;
 	}
@@ -4056,10 +4700,14 @@
 	int retval;
 	struct iris_device *radio = video_get_drvdata(video_devdata(file));
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return -EINVAL;
 	}
+	if (unlikely(tuner == NULL)) {
+		FMDERR("%s, tuner is null\n", __func__);
+		return -EINVAL;
+	}
 	if (tuner->index > 0) {
 		FMDERR("Invalid Tuner Index");
 		return -EINVAL;
@@ -4104,11 +4752,16 @@
 	struct iris_device *radio = video_get_drvdata(video_devdata(file));
 	int retval = 0;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return -EINVAL;
 	}
 
+	if (unlikely(tuner == NULL)) {
+		FMDERR("%s, tuner is null\n", __func__);
+		return -EINVAL;
+	}
+
 	if (tuner->index > 0)
 		return -EINVAL;
 
@@ -4158,9 +4811,15 @@
 {
 	struct iris_device  *radio = video_get_drvdata(video_devdata(file));
 	int retval = -1;
-	freq->frequency = freq->frequency / TUNE_PARAM;
+	u32 f;
 
-	if (radio == NULL) {
+	if (unlikely(freq == NULL)) {
+		FMDERR("%s, v4l2 freq is null\n", __func__);
+		return -EINVAL;
+	}
+	f = (freq->frequency / TUNE_PARAM);
+
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return -EINVAL;
 	}
@@ -4180,7 +4839,7 @@
 				radio->fm_hdev);
 	}
 
-	retval = iris_set_freq(radio, freq->frequency);
+	retval = iris_set_freq(radio, f);
 
 	if (radio->mode == FM_TRANS
 		 && radio->trans_conf.rds_std == 2
@@ -4279,6 +4938,11 @@
 {
 	struct iris_device *radio = video_get_drvdata(video_devdata(file));
 	int dir;
+
+	if (unlikely(seek == NULL)) {
+		FMDERR("%s, v4l2_hw_freq_seek is null\n", __func__);
+		return -EINVAL;
+	}
 	if (seek->seek_upward)
 		dir = SRCH_DIR_UP;
 	else
@@ -4292,14 +4956,22 @@
 	struct iris_device *radio;
 	radio = video_get_drvdata(video_devdata(file));
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return -EINVAL;
 	}
+	if (unlikely(capability == NULL)) {
+		FMDERR("%s, capability struct is null\n", __func__);
+		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;
 }
 
@@ -4307,7 +4979,7 @@
 {
 	int retval;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return -EINVAL;
 	}
@@ -4351,7 +5023,7 @@
 
 	int retval;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return -EINVAL;
 	}
@@ -4367,7 +5039,7 @@
 {
 	int retval = 1;
 
-	if (radio == NULL) {
+	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return -EINVAL;
 	}
@@ -4470,11 +5142,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;
 		}
 	}
 
@@ -4502,8 +5174,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;
 }
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/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index 907ce7c..64053de 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -1673,10 +1673,8 @@
 		wcd9xxx->slim_device_bootup = false;
 		return 0;
 	}
-	ret = wcd9xxx_reset(wcd9xxx);
-	if (ret)
-		pr_err("%s: Resetting Codec failed\n", __func__);
 
+	dev_info(wcd9xxx->dev, "%s: codec bring up\n", __func__);
 	wcd9xxx_bring_up(wcd9xxx);
 	ret = wcd9xxx_irq_init(wcd9xxx_res);
 	if (ret) {
@@ -1688,6 +1686,25 @@
 	return ret;
 }
 
+static int wcd9xxx_slim_device_reset(struct slim_device *sldev)
+{
+	int ret;
+	struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
+	if (!wcd9xxx) {
+		pr_err("%s: wcd9xxx is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	dev_info(wcd9xxx->dev, "%s: device reset\n", __func__);
+	if (wcd9xxx->slim_device_bootup)
+		return 0;
+	ret = wcd9xxx_reset(wcd9xxx);
+	if (ret)
+		dev_err(wcd9xxx->dev, "%s: Resetting Codec failed\n", __func__);
+
+	return ret;
+}
+
 static int wcd9xxx_slim_device_up(struct slim_device *sldev)
 {
 	struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
@@ -1695,7 +1712,7 @@
 		pr_err("%s: wcd9xxx is NULL\n", __func__);
 		return -EINVAL;
 	}
-	dev_dbg(wcd9xxx->dev, "%s: device up\n", __func__);
+	dev_info(wcd9xxx->dev, "%s: slim device up\n", __func__);
 	return wcd9xxx_device_up(wcd9xxx);
 }
 
@@ -1703,6 +1720,7 @@
 {
 	struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
 
+	dev_info(wcd9xxx->dev, "%s: device down\n", __func__);
 	if (!wcd9xxx) {
 		pr_err("%s: wcd9xxx is NULL\n", __func__);
 		return -EINVAL;
@@ -1826,6 +1844,7 @@
 	.resume = wcd9xxx_slim_resume,
 	.suspend = wcd9xxx_slim_suspend,
 	.device_up = wcd9xxx_slim_device_up,
+	.reset_device = wcd9xxx_slim_device_reset,
 	.device_down = wcd9xxx_slim_device_down,
 };
 
@@ -1845,6 +1864,7 @@
 	.resume = wcd9xxx_slim_resume,
 	.suspend = wcd9xxx_slim_suspend,
 	.device_up = wcd9xxx_slim_device_up,
+	.reset_device = wcd9xxx_slim_device_reset,
 	.device_down = wcd9xxx_slim_device_down,
 };
 
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 0bc18fb..c5c0ce8 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -99,7 +99,7 @@
 struct qseecom_registered_listener_list {
 	struct list_head                 list;
 	struct qseecom_register_listener_req svc;
-	u8  *sb_reg_req;
+	uint32_t user_virt_sb_base;
 	u8 *sb_virt;
 	s32 sb_phys;
 	size_t sb_length;
@@ -319,6 +319,10 @@
 		pr_err("copy_from_user failed\n");
 		return ret;
 	}
+	if (!access_ok(VERIFY_WRITE, (void __user *)rcvd_lstnr.virt_sb_base,
+			rcvd_lstnr.sb_size))
+		return -EFAULT;
+
 	data->listener.id = 0;
 	if (!__qseecom_is_svc_unique(data, &rcvd_lstnr)) {
 		pr_err("Service is not unique and is already registered\n");
@@ -336,6 +340,7 @@
 
 	new_entry->svc.listener_id = rcvd_lstnr.listener_id;
 	new_entry->sb_length = rcvd_lstnr.sb_size;
+	new_entry->user_virt_sb_base = rcvd_lstnr.virt_sb_base;
 	if (__qseecom_set_sb_memory(new_entry, data, &rcvd_lstnr)) {
 		pr_err("qseecom_set_sb_memoryfailed\n");
 		kzfree(new_entry);
@@ -446,6 +451,10 @@
 			req.ifd_data_fd, req.sb_len, req.virt_sb_base);
 		return -EFAULT;
 	}
+	if (!access_ok(VERIFY_WRITE, (void __user *)req.virt_sb_base,
+			req.sb_len))
+		return -EFAULT;
+
 	/* Get the handle of the shared fd */
 	data->client.ihandle = ion_import_dma_buf(qseecom.ion_clnt,
 						req.ifd_data_fd);
@@ -861,6 +870,13 @@
 	return data->client.sb_phys + (virt - data->client.user_virt_sb_base);
 }
 
+static uint32_t __qseecom_uvirt_to_kvirt(struct qseecom_dev_handle *data,
+						uint32_t virt)
+{
+	return (uint32_t)data->client.sb_virt +
+				(virt - data->client.user_virt_sb_base);
+}
+
 int __qseecom_process_rpmb_svc_cmd(struct qseecom_dev_handle *data_ptr,
 		struct qseecom_send_svc_cmd_req *req_ptr,
 		struct qseecom_client_send_service_ireq *send_svc_ireq_ptr)
@@ -1269,6 +1285,24 @@
 		pr_err("copy_from_user failed\n");
 		return ret;
 	}
+
+	if (req.cmd_req_buf == NULL || req.resp_buf == NULL) {
+		pr_err("cmd buffer or response buffer is null\n");
+		return -EINVAL;
+	}
+	if (((uint32_t)req.cmd_req_buf < data->client.user_virt_sb_base) ||
+		((uint32_t)req.cmd_req_buf >= (data->client.user_virt_sb_base +
+					data->client.sb_length))) {
+		pr_err("cmd buffer address not within shared bufffer\n");
+		return -EINVAL;
+	}
+
+	if (((uint32_t)req.resp_buf < data->client.user_virt_sb_base)  ||
+		((uint32_t)req.resp_buf >= (data->client.user_virt_sb_base +
+					data->client.sb_length))){
+		pr_err("response buffer address not within shared bufffer\n");
+		return -EINVAL;
+	}
 	send_cmd_req.cmd_req_buf = req.cmd_req_buf;
 	send_cmd_req.cmd_req_len = req.cmd_req_len;
 	send_cmd_req.resp_buf = req.resp_buf;
@@ -1282,6 +1316,11 @@
 			return -EINVAL;
 		}
 	}
+	req.cmd_req_buf = (void *)__qseecom_uvirt_to_kvirt(data,
+						(uint32_t)req.cmd_req_buf);
+	req.resp_buf = (void *)__qseecom_uvirt_to_kvirt(data,
+						(uint32_t)req.resp_buf);
+
 	ret = __qseecom_update_cmd_buf(&req, false, data, false);
 	if (ret)
 		return ret;
@@ -1877,11 +1916,20 @@
 {
 	struct qseecom_send_modfd_listener_resp resp;
 	int i;
+	struct qseecom_registered_listener_list *this_lstnr = NULL;
 
 	if (copy_from_user(&resp, argp, sizeof(resp))) {
 		pr_err("copy_from_user failed");
 		return -EINVAL;
 	}
+	this_lstnr = __qseecom_find_svc(data->listener.id);
+	if (this_lstnr == NULL)
+		return -EINVAL;
+
+	if (resp.resp_buf_ptr == NULL) {
+		pr_err("Invalid resp_buf_ptr\n");
+		return -EINVAL;
+	}
 	/* validate offsets */
 	for (i = 0; i < MAX_ION_FD; i++) {
 		if (resp.ifd_data[i].cmd_buf_offset >= resp.resp_len) {
@@ -1890,6 +1938,17 @@
 			return -EINVAL;
 		}
 	}
+
+	if (((uint32_t)resp.resp_buf_ptr <
+			this_lstnr->user_virt_sb_base)
+			|| ((uint32_t)resp.resp_buf_ptr >=
+			(this_lstnr->user_virt_sb_base +
+			this_lstnr->sb_length))) {
+		pr_err("resp_buf_ptr address not within shared buffer\n");
+		return -EINVAL;
+	}
+	resp.resp_buf_ptr = (uint32_t)this_lstnr->sb_virt +
+		(resp.resp_buf_ptr - this_lstnr->user_virt_sb_base);
 	__qseecom_update_cmd_buf(&resp, false, data, true);
 	qseecom.send_resp_flag = 1;
 	wake_up_interruptible(&qseecom.send_resp_wq);
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/card/block.c b/drivers/mmc/card/block.c
index 743668b..ff3e4ac 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -3073,6 +3073,8 @@
 		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
 	MMC_FIXUP("VZL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
 		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
+	MMC_FIXUP(CID_NAME_ANY, CID_MANFID_HYNIX, CID_OEMID_ANY, add_quirk_mmc,
+		  MMC_QUIRK_BROKEN_DATA_TIMEOUT),
 
 	END_FIXUP
 };
diff --git a/drivers/mmc/card/mmc_block_test.c b/drivers/mmc/card/mmc_block_test.c
index 39296ef..5cc2806 100644
--- a/drivers/mmc/card/mmc_block_test.c
+++ b/drivers/mmc/card/mmc_block_test.c
@@ -2285,6 +2285,9 @@
 			       size_t count,
 			       loff_t *offset)
 {
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return count;
+
 	memset((void *)buffer, 0, count);
 
 	snprintf(buffer, count,
@@ -2383,6 +2386,9 @@
 			       size_t count,
 			       loff_t *offset)
 {
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return count;
+
 	memset((void *)buffer, 0, count);
 
 	snprintf(buffer, count,
@@ -2491,6 +2497,9 @@
 			       size_t count,
 			       loff_t *offset)
 {
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return count;
+
 	memset((void *)buffer, 0, count);
 
 	snprintf(buffer, count,
@@ -2605,6 +2614,9 @@
 			       size_t count,
 			       loff_t *offset)
 {
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return count;
+
 	memset((void *)buffer, 0, count);
 
 	snprintf(buffer, count,
@@ -2730,6 +2742,9 @@
 			       size_t count,
 			       loff_t *offset)
 {
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return count;
+
 	memset((void *)buffer, 0, count);
 
 	snprintf(buffer, count,
@@ -2818,6 +2833,9 @@
 			       size_t count,
 			       loff_t *offset)
 {
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return count;
+
 	memset((void *)buffer, 0, count);
 
 	snprintf(buffer, count,
@@ -2978,6 +2996,9 @@
 			       size_t count,
 			       loff_t *offset)
 {
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return count;
+
 	memset((void *)buffer, 0, count);
 
 	snprintf(buffer, count,
@@ -3051,6 +3072,9 @@
 			       size_t count,
 			       loff_t *offset)
 {
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return count;
+
 	memset((void *)buffer, 0, count);
 
 	snprintf(buffer, count,
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 421774f..b36faff 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -467,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/core.c b/drivers/mmc/core/core.c
index a296e48..f288231 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1307,6 +1307,11 @@
 		data->timeout_ns = 4000000000u; /* 4s */
 		data->timeout_clks = 0;
 	}
+	/* Some emmc cards require a longer read/write time */
+	if (card->quirks & MMC_QUIRK_BROKEN_DATA_TIMEOUT) {
+		if (data->timeout_ns <  4000000000u)
+			data->timeout_ns = 4000000000u;	/* 4s */
+	}
 }
 EXPORT_SYMBOL(mmc_set_data_timeout);
 
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 903decf..4ec8941 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/fault-inject.h>
+#include <linux/uaccess.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -392,6 +393,9 @@
 	if (!card)
 		return cnt;
 
+	if (!access_ok(VERIFY_WRITE, ubuf, cnt))
+		return cnt;
+
 	if (!card->wr_pack_stats.print_in_read)
 		return 0;
 
@@ -532,6 +536,9 @@
 	if (!card)
 		return cnt;
 
+	if (!access_ok(VERIFY_READ, ubuf, cnt))
+		return cnt;
+
 	sscanf(ubuf, "%d", &value);
 	if (value) {
 		mmc_blk_init_packed_statistics(card);
@@ -571,6 +578,9 @@
 	if (!card)
 		return cnt;
 
+	if (!access_ok(VERIFY_WRITE, ubuf, cnt))
+		return cnt;
+
 	bkops_stats = &card->bkops_info.bkops_stats;
 
 	if (!bkops_stats->print_stats)
@@ -637,6 +647,9 @@
 	if (!card)
 		return cnt;
 
+	if (!access_ok(VERIFY_READ, ubuf, cnt))
+		return cnt;
+
 	bkops_stats = &card->bkops_info.bkops_stats;
 
 	sscanf(ubuf, "%d", &value);
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 e391a06..4d3a560 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -3113,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 830223d..24b7d04 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -746,12 +746,6 @@
 	if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL)
 		return 0xE;
 
-	/* During initialization, don't use max timeout as the clock is slow */
-	if ((host->quirks2 & SDHCI_QUIRK2_USE_RESERVED_MAX_TIMEOUT) &&
-		(host->clock > 400000)) {
-		return 0xF;
-	}
-
 	/* Unspecified timeout, assume max */
 	if (!data && !cmd->cmd_timeout_ms)
 		return 0xE;
diff --git a/drivers/mtd/devices/msm_qpic_nand.c b/drivers/mtd/devices/msm_qpic_nand.c
index 7f02187..2e06b42 100644
--- a/drivers/mtd/devices/msm_qpic_nand.c
+++ b/drivers/mtd/devices/msm_qpic_nand.c
@@ -1919,7 +1919,7 @@
 	buf = (uint8_t *)dma_buffer + sizeof(*dma_buffer);
 
 	cmd = dma_buffer->cmd;
-	memset(&data, 0, sizeof(struct msm_nand_erase_reg_data));
+	memset(&data, 0, sizeof(struct msm_nand_blk_isbad_data));
 	data.cfg.cmd = MSM_NAND_CMD_PAGE_READ_ALL;
 	data.cfg.cfg0 = chip->cfg0_raw & ~(7U << CW_PER_PAGE);
 	data.cfg.cfg1 = chip->cfg1_raw;
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 76eb15b..8e695c3 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -45,11 +45,13 @@
 #endif
 
 #define DEVICE "wcnss_wlan"
+#define CTRL_DEVICE "wcnss_ctrl"
 #define VERSION "1.01"
 #define WCNSS_PIL_DEVICE "wcnss"
 
 /* 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);
@@ -156,6 +158,14 @@
 #define WCNSS_MAX_FRAME_SIZE		(4*1024)
 #define WCNSS_VERSION_LEN			30
 #define WCNSS_MAX_BUILD_VER_LEN		256
+#define WCNSS_MAX_CMD_LEN		(128)
+#define WCNSS_MIN_CMD_LEN		(3)
+#define WCNSS_MIN_SERIAL_LEN		(6)
+
+/* control messages from userspace */
+#define WCNSS_USR_CTRL_MSG_START  0x00000000
+#define WCNSS_USR_SERIAL_NUM      (WCNSS_USR_CTRL_MSG_START + 1)
+#define WCNSS_USR_HAS_CAL_DATA    (WCNSS_USR_CTRL_MSG_START + 2)
 
 /* message types */
 #define WCNSS_CTRL_MSG_START	0x01000000
@@ -355,12 +365,14 @@
 	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;
 	int	fw_vbatt_state;
+	int	ctrl_device_opened;
 	struct mutex dev_lock;
+	struct mutex ctrl_lock;
 	wait_queue_head_t read_wait;
 	struct qpnp_adc_tm_btm_param vbat_monitor_params;
 	struct qpnp_adc_tm_chip *adc_tm_dev;
@@ -1822,6 +1834,80 @@
 	.notifier_call = wcnss_pm_notify,
 };
 
+static int wcnss_ctrl_open(struct inode *inode, struct file *file)
+{
+	int rc = 0;
+
+	if (!penv || penv->ctrl_device_opened)
+		return -EFAULT;
+
+	penv->ctrl_device_opened = 1;
+
+	return rc;
+}
+
+
+void process_usr_ctrl_cmd(u8 *buf, size_t len)
+{
+	u16 cmd = buf[0] << 8 | buf[1];
+
+	switch (cmd) {
+
+	case WCNSS_USR_SERIAL_NUM:
+		if (WCNSS_MIN_SERIAL_LEN > len) {
+			pr_err("%s: Invalid serial number\n", __func__);
+			return;
+		}
+		penv->serial_number = buf[2] << 24 | buf[3] << 16
+			| buf[4] << 8 | buf[5];
+		break;
+
+	case WCNSS_USR_HAS_CAL_DATA:
+		if (1 < buf[2])
+			pr_err("%s: Invalid data for cal %d\n", __func__,
+				buf[2]);
+		has_calibrated_data = buf[2];
+		break;
+
+	default:
+		pr_err("%s: Invalid command %d\n", __func__, cmd);
+		break;
+	}
+}
+
+static ssize_t wcnss_ctrl_write(struct file *fp, const char __user
+			*user_buffer, size_t count, loff_t *position)
+{
+	int rc = 0;
+	u8 buf[WCNSS_MAX_CMD_LEN];
+
+	if (!penv || !penv->ctrl_device_opened || WCNSS_MAX_CMD_LEN < count
+			|| WCNSS_MIN_CMD_LEN > count)
+		return -EFAULT;
+
+	mutex_lock(&penv->ctrl_lock);
+	rc = copy_from_user(buf, user_buffer, count);
+	if (0 == rc)
+		process_usr_ctrl_cmd(buf, count);
+
+	mutex_unlock(&penv->ctrl_lock);
+
+	return rc;
+}
+
+
+static const struct file_operations wcnss_ctrl_fops = {
+	.owner = THIS_MODULE,
+	.open = wcnss_ctrl_open,
+	.write = wcnss_ctrl_write,
+};
+
+static struct miscdevice wcnss_usr_ctrl = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = CTRL_DEVICE,
+	.fops = &wcnss_ctrl_fops,
+};
+
 static int
 wcnss_trigger_config(struct platform_device *pdev)
 {
@@ -2134,7 +2220,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;
@@ -2142,7 +2228,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;
 		}
@@ -2161,7 +2247,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;
@@ -2223,6 +2310,7 @@
 	}
 
 	mutex_init(&penv->dev_lock);
+	mutex_init(&penv->ctrl_lock);
 	mutex_init(&penv->vbat_monitor_mutex);
 	init_waitqueue_head(&penv->read_wait);
 
@@ -2235,6 +2323,9 @@
 	 * place
 	 */
 	pr_info(DEVICE " probed in built-in mode\n");
+
+	misc_register(&wcnss_usr_ctrl);
+
 	return misc_register(&wcnss_misc);
 
 }
diff --git a/drivers/platform/msm/ipa/teth_bridge.c b/drivers/platform/msm/ipa/teth_bridge.c
index b3a6b17..79ec0c0 100644
--- a/drivers/platform/msm/ipa/teth_bridge.c
+++ b/drivers/platform/msm/ipa/teth_bridge.c
@@ -1780,7 +1780,7 @@
 			break;
 		}
 
-		if (caps.num_protocols < teth_ctx->aggr_caps->num_protocols) {
+		if (caps.num_protocols != teth_ctx->aggr_caps->num_protocols) {
 			caps.num_protocols = teth_ctx->aggr_caps->num_protocols;
 			if (copy_to_user((struct teth_aggr_capabilities *)arg,
 					 &caps,
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-power-on.c b/drivers/platform/msm/qpnp-power-on.c
index b55b66b..507d02c 100644
--- a/drivers/platform/msm/qpnp-power-on.c
+++ b/drivers/platform/msm/qpnp-power-on.c
@@ -50,6 +50,8 @@
 #define QPNP_PON_KPDPWR_RESIN_S2_CNTL2(base)	(base + 0x4B)
 #define QPNP_PON_PS_HOLD_RST_CTL(base)		(base + 0x5A)
 #define QPNP_PON_PS_HOLD_RST_CTL2(base)		(base + 0x5B)
+#define QPNP_PON_WD_RST_S2_CTL(base)		(base + 0x56)
+#define QPNP_PON_WD_RST_S2_CTL2(base)		(base + 0x57)
 #define QPNP_PON_TRIGGER_EN(base)		(base + 0x80)
 #define QPNP_PON_S3_DBC_CTL(base)		(base + 0x75)
 
@@ -73,6 +75,7 @@
 #define QPNP_PON_RESIN_BARK_N_SET		BIT(4)
 #define QPNP_PON_KPDPWR_RESIN_BARK_N_SET	BIT(5)
 
+#define QPNP_PON_WD_EN			BIT(7)
 #define QPNP_PON_RESET_EN			BIT(7)
 #define QPNP_PON_POWER_OFF_MASK			0xF
 
@@ -270,6 +273,32 @@
 EXPORT_SYMBOL(qpnp_pon_is_warm_reset);
 
 /**
+ * qpnp_pon_wd_config - Disable the wd in a warm reset.
+ * @enable: to enable or disable the PON watch dog
+ *
+ * Returns = 0 for operate successfully, < 0 for errors
+ */
+int qpnp_pon_wd_config(bool enable)
+{
+	struct qpnp_pon *pon = sys_reset_dev;
+	int rc = 0;
+
+	if (!pon)
+		return -EPROBE_DEFER;
+
+	rc = qpnp_pon_masked_write(pon, QPNP_PON_WD_RST_S2_CTL2(pon->base),
+			QPNP_PON_WD_EN, enable ? QPNP_PON_WD_EN : 0);
+	if (rc)
+		dev_err(&pon->spmi->dev,
+				"Unable to write to addr=%x, rc(%d)\n",
+				QPNP_PON_WD_RST_S2_CTL2(pon->base), rc);
+
+	return rc;
+}
+EXPORT_SYMBOL(qpnp_pon_wd_config);
+
+
+/**
  * qpnp_pon_trigger_config - Configures (enable/disable) the PON trigger source
  * @pon_src: PON source to be configured
  * @enable: to enable or disable the PON trigger
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 c621d2a..55a5a2d 100644
--- a/drivers/platform/msm/sps/sps.c
+++ b/drivers/platform/msm/sps/sps.c
@@ -184,6 +184,11 @@
 		return -EFAULT;
 	}
 
+	if (buf_size_kb > (INT_MAX/SZ_1K)) {
+		pr_err("sps:debugfs: buffer size is too large\n");
+		return -EFAULT;
+	}
+
 	new_buf_size = buf_size_kb * SZ_1K;
 
 	if (debugfs_record_enabled) {
@@ -2529,21 +2534,8 @@
 		goto device_create_err;
 	}
 
-	sps->dfab_clk = clk_get(sps->dev, "dfab_clk");
-	if (IS_ERR(sps->dfab_clk)) {
-		if (PTR_ERR(sps->dfab_clk) == -EPROBE_DEFER)
-			ret = -EPROBE_DEFER;
-		else
-			SPS_ERR("sps:fail to get dfab_clk.");
-		goto clk_err;
-	} else {
-		ret = clk_set_rate(sps->dfab_clk, 64000000);
-		if (ret) {
-			SPS_ERR("sps:failed to set dfab_clk rate.");
-			clk_put(sps->dfab_clk);
-			goto clk_err;
-		}
-	}
+	if (pdev->dev.of_node)
+		sps->dev->of_node = pdev->dev.of_node;
 
 	if (!d_type) {
 		sps->pmem_clk = clk_get(sps->dev, "mem_clk");
@@ -2552,36 +2544,58 @@
 				ret = -EPROBE_DEFER;
 			else
 				SPS_ERR("sps:fail to get pmem_clk.");
-			goto clk_err;
+			goto pmem_clk_err;
 		} else {
 			ret = clk_prepare_enable(sps->pmem_clk);
 			if (ret) {
 				SPS_ERR("sps:failed to enable pmem_clk.");
-				goto clk_err;
+				goto pmem_clk_en_err;
 			}
 		}
 	}
 
 #ifdef CONFIG_SPS_SUPPORT_BAMDMA
+	sps->dfab_clk = clk_get(sps->dev, "dfab_clk");
+	if (IS_ERR(sps->dfab_clk)) {
+		if (PTR_ERR(sps->dfab_clk) == -EPROBE_DEFER)
+			ret = -EPROBE_DEFER;
+		else
+			SPS_ERR("sps:fail to get dfab_clk.");
+		goto dfab_clk_err;
+	} else {
+		ret = clk_set_rate(sps->dfab_clk, 64000000);
+		if (ret) {
+			SPS_ERR("sps:failed to set dfab_clk rate.");
+			clk_put(sps->dfab_clk);
+			goto dfab_clk_err;
+		}
+	}
+
 	sps->bamdma_clk = clk_get(sps->dev, "dma_bam_pclk");
 	if (IS_ERR(sps->bamdma_clk)) {
 		if (PTR_ERR(sps->bamdma_clk) == -EPROBE_DEFER)
 			ret = -EPROBE_DEFER;
 		else
 			SPS_ERR("sps:fail to get bamdma_clk.");
-		goto clk_err;
+		clk_put(sps->dfab_clk);
+		goto dfab_clk_err;
 	} else {
 		ret = clk_prepare_enable(sps->bamdma_clk);
 		if (ret) {
 			SPS_ERR("sps:failed to enable bamdma_clk. ret=%d", ret);
-			goto clk_err;
+			clk_put(sps->bamdma_clk);
+			clk_put(sps->dfab_clk);
+			goto dfab_clk_err;
 		}
 	}
 
 	ret = clk_prepare_enable(sps->dfab_clk);
 	if (ret) {
 		SPS_ERR("sps:failed to enable dfab_clk. ret=%d", ret);
-		goto clk_err;
+		clk_disable_unprepare(sps->bamdma_clk);
+		clk_put(sps->bamdma_clk);
+		clk_put(sps->dfab_clk);
+		goto dfab_clk_err;
 	}
 #endif
 	ret = sps_device_init();
@@ -2590,8 +2604,10 @@
 #ifdef CONFIG_SPS_SUPPORT_BAMDMA
 		clk_disable_unprepare(sps->dfab_clk);
 		clk_disable_unprepare(sps->bamdma_clk);
+		clk_put(sps->bamdma_clk);
+		clk_put(sps->dfab_clk);
 #endif
-		goto sps_device_init_err;
+		goto dfab_clk_err;
 	}
 #ifdef CONFIG_SPS_SUPPORT_BAMDMA
 	clk_disable_unprepare(sps->dfab_clk);
@@ -2602,8 +2618,13 @@
 	SPS_INFO("sps:sps is ready.");
 
 	return 0;
-clk_err:
-sps_device_init_err:
+dfab_clk_err:
+	if (!d_type)
+		clk_disable_unprepare(sps->pmem_clk);
+pmem_clk_en_err:
+	if (!d_type)
+		clk_put(sps->pmem_clk);
+pmem_clk_err:
 	device_destroy(sps->dev_class, sps->dev_num);
 device_create_err:
 	unregister_chrdev_region(sps->dev_num, 1);
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 8572616..32623f4 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -832,13 +832,12 @@
 	int rc = 0;
 	u8 usb_reg = 0, temp = 8;
 
-	if (mA < QPNP_CHG_I_MAX_MIN_100
-			|| mA > QPNP_CHG_I_MAX_MAX_MA) {
+	if (mA < 0 || mA > QPNP_CHG_I_MAX_MAX_MA) {
 		pr_err("bad mA=%d asked to set\n", mA);
 		return -EINVAL;
 	}
 
-	if (mA == QPNP_CHG_I_MAX_MIN_100) {
+	if (mA <= QPNP_CHG_I_MAX_MIN_100) {
 		usb_reg = 0x00;
 		pr_debug("current=%d setting %02x\n", mA, usb_reg);
 		return qpnp_chg_write(chip, &usb_reg,
@@ -1285,6 +1284,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)
@@ -1461,6 +1475,7 @@
 				chip->chg_done = false;
 			}
 			qpnp_chg_usb_suspend_enable(chip, 0);
+			qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100);
 			chip->prev_usb_max_ma = -EINVAL;
 			chip->aicl_settled = false;
 		} else {
@@ -2077,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
@@ -3118,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);
@@ -3617,7 +3641,8 @@
 		qpnp_batt_system_temp_level_set(chip, val->intval);
 		break;
 	case POWER_SUPPLY_PROP_INPUT_CURRENT_MAX:
-		qpnp_chg_iusbmax_set(chip, val->intval / 1000);
+		if (qpnp_chg_is_usb_chg_plugged_in(chip))
+			qpnp_chg_iusbmax_set(chip, val->intval / 1000);
 		break;
 	case POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM:
 		qpnp_chg_iusb_trim_set(chip, val->intval);
diff --git a/drivers/rtc/alarm.c b/drivers/rtc/alarm.c
index 7d59e28..51e176f 100644
--- a/drivers/rtc/alarm.c
+++ b/drivers/rtc/alarm.c
@@ -553,8 +553,8 @@
 	return;
 
 disable_alarm:
-	rtc_alarm_irq_enable(alarm_rtc_dev, 0);
 	spin_unlock_irqrestore(&alarm_slock, flags);
+	rtc_alarm_irq_enable(alarm_rtc_dev, 0);
 }
 
 static struct rtc_task alarm_rtc_task = {
diff --git a/drivers/sensors/sensors_class.c b/drivers/sensors/sensors_class.c
index 74e0d8d..bbf168c 100644
--- a/drivers/sensors/sensors_class.c
+++ b/drivers/sensors/sensors_class.c
@@ -105,6 +105,78 @@
 			sensors_cdev->fifo_max_event_count);
 }
 
+static ssize_t sensors_enable_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev);
+	ssize_t ret = -EINVAL;
+	unsigned long data = 0;
+
+	ret = kstrtoul(buf, 10, &data);
+	if (ret)
+		return ret;
+	if (data > 1) {
+		dev_err(dev, "Invalid value of input, input=%ld\n", data);
+		return -EINVAL;
+	}
+
+	if (sensors_cdev->sensors_enable == NULL) {
+		dev_err(dev, "Invalid sensor class enable handle\n");
+		return -EINVAL;
+	}
+	ret = sensors_cdev->sensors_enable(sensors_cdev, data);
+	if (ret)
+		return ret;
+
+	sensors_cdev->enabled = data;
+	return size;
+}
+
+
+static ssize_t sensors_enable_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev);
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+			sensors_cdev->enabled);
+}
+
+static ssize_t sensors_delay_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev);
+	ssize_t ret = -EINVAL;
+	unsigned long data = 0;
+
+	ret = kstrtoul(buf, 10, &data);
+	if (ret)
+		return ret;
+	/* The data unit is millisecond, the min_delay unit is microseconds. */
+	if ((data * 1000) < sensors_cdev->min_delay) {
+		dev_err(dev, "Invalid value of delay, delay=%ld\n", data);
+		return -EINVAL;
+	}
+	if (sensors_cdev->sensors_poll_delay == NULL) {
+		dev_err(dev, "Invalid sensor class delay handle\n");
+		return -EINVAL;
+	}
+	ret = sensors_cdev->sensors_poll_delay(sensors_cdev, data);
+	if (ret)
+		return ret;
+
+	sensors_cdev->delay_msec = data;
+	return size;
+}
+
+static ssize_t sensors_delay_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev);
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+			sensors_cdev->delay_msec);
+}
+
+
 static struct device_attribute sensors_class_attrs[] = {
 	__ATTR(name, 0444, sensors_name_show, NULL),
 	__ATTR(vendor, 0444, sensors_vendor_show, NULL),
@@ -117,6 +189,8 @@
 	__ATTR(min_delay, 0444, sensors_min_delay_show, NULL),
 	__ATTR(fifo_reserved_event_count, 0444, sensors_fifo_event_show, NULL),
 	__ATTR(fifo_max_event_count, 0444, sensors_fifo_max_show, NULL),
+	__ATTR(enable, 0664, sensors_enable_show, sensors_enable_store),
+	__ATTR(poll_delay, 0664, sensors_delay_show, sensors_delay_store),
 	__ATTR_NULL,
 };
 
diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c
index 67cf049..adca457 100644
--- a/drivers/slimbus/slim-msm-ngd.c
+++ b/drivers/slimbus/slim-msm-ngd.c
@@ -973,6 +973,7 @@
 	struct slim_controller *ctrl = &dev->ctrl;
 	struct slim_device *sbdev;
 	int i;
+	slim_framer_booted(ctrl);
 	mutex_lock(&ctrl->m_ctrl);
 	list_for_each_entry(sbdev, &ctrl->devs, dev_list) {
 		int ret = 0;
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index b074289..f6594c8 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -650,6 +650,36 @@
 EXPORT_SYMBOL(slim_report_absent);
 
 /*
+ * slim_framer_booted: This function is called by controller after the active
+ * framer has booted (using Bus Reset sequence, or after it has shutdown and has
+ * come back up). Components, devices on the bus may be in undefined state,
+ * and this function triggers their drivers to do the needful
+ * to bring them back in Reset state so that they can acquire sync, report
+ * present and be operational again.
+ */
+void slim_framer_booted(struct slim_controller *ctrl)
+{
+	struct slim_device *sbdev;
+	struct list_head *pos, *next;
+	if (!ctrl)
+		return;
+	mutex_lock(&ctrl->m_ctrl);
+	list_for_each_safe(pos, next, &ctrl->devs) {
+		struct slim_driver *sbdrv;
+		sbdev = list_entry(pos, struct slim_device, dev_list);
+		mutex_unlock(&ctrl->m_ctrl);
+		if (sbdev && sbdev->dev.driver) {
+			sbdrv = to_slim_driver(sbdev->dev.driver);
+			if (sbdrv->reset_device)
+				sbdrv->reset_device(sbdev);
+		}
+		mutex_lock(&ctrl->m_ctrl);
+	}
+	mutex_unlock(&ctrl->m_ctrl);
+}
+EXPORT_SYMBOL(slim_framer_booted);
+
+/*
  * slim_msg_response: Deliver Message response received from a device to the
  *	framework.
  * @ctrl: Controller handle
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index bc328e0..e3284d5 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -223,7 +223,9 @@
 	if (opc < SPMI_CMD_RESET || opc > SPMI_CMD_WAKEUP)
 		return -EINVAL;
 
-	cmd = ((opc | 0x40) << 27) | ((sid & 0xf) << 20);
+	opc -= SPMI_CMD_RESET - PMIC_ARB_OP_RESET;
+
+	cmd = (opc << 27) | ((sid & 0xf) << 20);
 
 	spin_lock_irqsave(&pmic_arb->lock, flags);
 	pmic_arb_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd);
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..efb87a9 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;
@@ -1886,7 +1902,7 @@
 			pr_debug("thermal node%x\n", btm_channel_num);
 			chip->sensor[sen_idx].mode = THERMAL_DEVICE_DISABLED;
 			chip->sensor[sen_idx].thermal_node = true;
-			snprintf(name, sizeof(name),
+			snprintf(name, sizeof(name), "%s",
 				chip->adc->adc_channels[sen_idx].name);
 			chip->sensor[sen_idx].meas_interval =
 				QPNP_ADC_TM_MEAS_INTERVAL;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 1be2550..4e84b94 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -631,6 +631,7 @@
 
 	u8			epnum;
 	struct dwc3_trb		*trb;
+	struct dwc3_trb		*ztrb;
 	dma_addr_t		trb_dma;
 
 	unsigned		direction:1;
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index ad3a3a9..7439c45 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -294,6 +294,15 @@
 		if (((dep->busy_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
 				usb_endpoint_xfer_isoc(dep->endpoint.desc))
 			dep->busy_slot++;
+
+		if (req->request.zero && req->ztrb) {
+			dep->busy_slot++;
+			req->ztrb = NULL;
+			if (((dep->busy_slot & DWC3_TRB_MASK) ==
+				DWC3_TRB_NUM - 1) &&
+				usb_endpoint_xfer_isoc(dep->endpoint.desc))
+				dep->busy_slot++;
+		}
 	}
 	list_del(&req->list);
 	req->trb = NULL;
@@ -864,6 +873,7 @@
 		req->trb_dma = dwc3_trb_dma_offset(dep, trb);
 	}
 
+update_trb:
 	trb->size = DWC3_TRB_SIZE_LENGTH(length);
 	trb->bpl = lower_32_bits(dma);
 	trb->bph = upper_32_bits(dma);
@@ -898,15 +908,31 @@
 	} else {
 		if (chain)
 			trb->ctrl |= DWC3_TRB_CTRL_CHN;
-
-		if (last)
-			trb->ctrl |= DWC3_TRB_CTRL_LST;
 	}
 
 	if (usb_endpoint_xfer_bulk(dep->endpoint.desc) && dep->stream_capable)
 		trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(req->request.stream_id);
 
 	trb->ctrl |= DWC3_TRB_CTRL_HWO;
+
+	if (req->request.zero && length &&
+			(length % usb_endpoint_maxp(dep->endpoint.desc) == 0)) {
+		trb = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
+		dep->free_slot++;
+
+		/* Skip the LINK-TRB on ISOC */
+		if (((dep->free_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
+			usb_endpoint_xfer_isoc(dep->endpoint.desc))
+			dep->free_slot++;
+
+		req->ztrb = trb;
+		length = 0;
+
+		goto update_trb;
+	}
+
+	if (!usb_endpoint_xfer_isoc(dep->endpoint.desc) && last)
+		trb->ctrl |= DWC3_TRB_CTRL_LST;
 }
 
 /*
@@ -1007,12 +1033,25 @@
 			}
 			dbg_queue(dep->number, &req->request, 0);
 		} else {
+			struct dwc3_request	*req1;
+			int maxpkt_size = usb_endpoint_maxp(dep->endpoint.desc);
+
 			dma = req->request.dma;
 			length = req->request.length;
 			trbs_left--;
 
-			if (!trbs_left)
+			if (req->request.zero && length &&
+						(length % maxpkt_size == 0))
+				trbs_left--;
+
+			if (!trbs_left) {
 				last_one = 1;
+			} else if (dep->direction && (trbs_left <= 1)) {
+				req1 = next_request(&req->list);
+				if (req1->request.zero && req1->request.length
+				 && (req1->request.length % maxpkt_size == 0))
+					last_one = 1;
+			}
 
 			/* Is this the last request? */
 			if (list_is_last(&req->list, &dep->request_list))
@@ -2052,6 +2091,8 @@
 				s_pkt = 1;
 		}
 
+		if (req->ztrb)
+			trb = req->ztrb;
 		/*
 		 * We assume here we will always receive the entire data block
 		 * which we should receive. Meaning, if we program RX to
diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c
index 6d7dd3d..88ebd80 100644
--- a/drivers/usb/gadget/f_mtp.c
+++ b/drivers/usb/gadget/f_mtp.c
@@ -899,7 +899,10 @@
 				dev->rx_done || dev->state != STATE_BUSY);
 			if (dev->state == STATE_CANCELED
 					|| dev->state == STATE_OFFLINE) {
-				r = -ECANCELED;
+				if (dev->state == STATE_OFFLINE)
+					r = -EIO;
+				else
+					r = -ECANCELED;
 				if (!dev->rx_done)
 					usb_ep_dequeue(dev->ep_out, read_req);
 				break;
diff --git a/drivers/usb/gadget/f_uac1.c b/drivers/usb/gadget/f_uac1.c
index e8c9667..883c5fa 100644
--- a/drivers/usb/gadget/f_uac1.c
+++ b/drivers/usb/gadget/f_uac1.c
@@ -1,7 +1,7 @@
 /*
  * f_audio.c -- USB Audio class function driver
  *
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  * Copyright (C) 2008 Bryan Wu <cooloney@kernel.org>
  * Copyright (C) 2008 Analog Devices, Inc
  *
@@ -438,8 +438,8 @@
 {
 	if (audio_buf) {
 		kfree(audio_buf->buf);
-		kfree(audio_buf);
 		audio_buf->buf = NULL;
+		kfree(audio_buf);
 		audio_buf = NULL;
 	}
 }
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index 299f620c..95b6fbc7 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -689,18 +689,20 @@
 }
 
 static int gs_alloc_requests(struct usb_ep *ep, struct list_head *head,
-		int num, int size, void (*fn)(struct usb_ep *, struct usb_request *),
+		int queue_size, int req_size,
+		void (*fn)(struct usb_ep *, struct usb_request *),
 		int *allocated)
 {
 	int			i;
 	struct usb_request	*req;
+	int n = allocated ? queue_size - *allocated : queue_size;
 
 	/* Pre-allocate up to QUEUE_SIZE transfers, but if we can't
 	 * do quite that many this time, don't fail ... we just won't
 	 * be as speedy as we might otherwise be.
 	 */
-	for (i = 0; i < num; i++) {
-		req = gs_alloc_req(ep, size, GFP_ATOMIC);
+	for (i = 0; i < n; i++) {
+		req = gs_alloc_req(ep, req_size, GFP_ATOMIC);
 		if (!req)
 			return list_empty(head) ? -ENOMEM : 0;
 		req->complete = fn;
@@ -941,22 +943,6 @@
 			port->port_num, tty, file);
 
 	wake_up_interruptible(&port->close_wait);
-
-	/*
-	 * Freeing the previously queued requests as they are
-	 * allocated again as a part of gs_open()
-	 */
-	if (port->port_usb) {
-		spin_unlock_irq(&port->port_lock);
-		usb_ep_fifo_flush(gser->out);
-		usb_ep_fifo_flush(gser->in);
-		spin_lock_irq(&port->port_lock);
-		gs_free_requests(gser->out, &port->read_queue, NULL);
-		gs_free_requests(gser->out, &port->read_pool, NULL);
-		gs_free_requests(gser->in, &port->write_pool, NULL);
-	}
-	port->read_allocated = port->read_started =
-		port->write_allocated = port->write_started = 0;
 exit:
 	spin_unlock_irq(&port->port_lock);
 }
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 5f20ad1..1030664 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -1,6 +1,6 @@
 /* ehci-msm-hsic.c - HSUSB Host Controller Driver Implementation
  *
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
  *
  * Partly derived from ehci-fsl.c and ehci-hcd.c
  * Copyright (c) 2000-2004 by David Brownell
@@ -2263,6 +2263,9 @@
 	iounmap(hcd->regs);
 	usb_put_hcd(hcd);
 
+	if (pdev->dev.of_node)
+		pdev->dev.platform_data = NULL;
+
 	return 0;
 }
 
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/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.h b/drivers/video/msm/mdss/mdp3.h
index 28997ec..f1f0455 100644
--- a/drivers/video/msm/mdss/mdp3.h
+++ b/drivers/video/msm/mdss/mdp3.h
@@ -26,6 +26,7 @@
 #include "mdss_fb.h"
 
 #define MDP_VSYNC_CLK_RATE	19200000
+#define KOFF_TIMEOUT msecs_to_jiffies(84)
 
 enum  {
 	MDP3_CLK_AHB,
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index 6219737..b204493 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -28,7 +28,10 @@
 #define MDP_CORE_CLK_RATE	100000000
 #define VSYNC_EXPIRE_TICK	4
 
-static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd);
+static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd,
+					struct mdp_overlay *req,
+					int image_size,
+					int *pipe_ndx);
 static int mdp3_overlay_unset(struct msm_fb_data_type *mfd, int ndx);
 static int mdp3_histogram_stop(struct mdp3_session_data *session,
 					u32 block);
@@ -91,6 +94,36 @@
 	return bufq->count;
 }
 
+void mdp3_ctrl_notifier_register(struct mdp3_session_data *ses,
+	struct notifier_block *notifier)
+{
+	blocking_notifier_chain_register(&ses->notifier_head, notifier);
+}
+
+void mdp3_ctrl_notifier_unregister(struct mdp3_session_data *ses,
+	struct notifier_block *notifier)
+{
+	blocking_notifier_chain_unregister(&ses->notifier_head, notifier);
+}
+
+int mdp3_ctrl_notify(struct mdp3_session_data *ses, int event)
+{
+	return blocking_notifier_call_chain(&ses->notifier_head, event, ses);
+}
+
+static void mdp3_dispatch_dma_done(struct work_struct *work)
+{
+	struct mdp3_session_data *session;
+
+	pr_debug("%s\n", __func__);
+	session = container_of(work, struct mdp3_session_data,
+				dma_done_work);
+	if (!session)
+		return;
+
+	mdp3_ctrl_notify(session, MDP_NOTIFY_FRAME_DONE);
+}
+
 static void mdp3_dispatch_clk_off(struct work_struct *work)
 {
 	struct mdp3_session_data *session;
@@ -121,6 +154,12 @@
 	sysfs_notify_dirent(session->vsync_event_sd);
 }
 
+void dma_done_notify_handler(void *arg)
+{
+	struct mdp3_session_data *session = (struct mdp3_session_data *)arg;
+	schedule_work(&session->dma_done_work);
+}
+
 void vsync_count_down(void *arg)
 {
 	struct mdp3_session_data *session = (struct mdp3_session_data *)arg;
@@ -140,8 +179,8 @@
 static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable)
 {
 	struct mdp3_session_data *mdp3_session;
-	struct mdp3_vsync_notification vsync_client;
-	struct mdp3_vsync_notification *arg = NULL;
+	struct mdp3_notification vsync_client;
+	struct mdp3_notification *arg = NULL;
 
 	pr_debug("mdp3_ctrl_vsync_enable =%d\n", enable);
 	mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
@@ -178,7 +217,8 @@
 	 * active or when dsi clocks are currently off
 	 */
 	if (enable && mdp3_session->status == 1
-			&& mdp3_session->vsync_before_commit) {
+			&& (mdp3_session->vsync_before_commit ||
+			!mdp3_session->intf->active)) {
 		mod_timer(&mdp3_session->vsync_timer,
 			jiffies + msecs_to_jiffies(mdp3_session->vsync_period));
 	} else if (enable && !mdp3_session->clk_on) {
@@ -194,7 +234,8 @@
 void mdp3_vsync_timer_func(unsigned long arg)
 {
 	struct mdp3_session_data *session = (struct mdp3_session_data *)arg;
-	if (session->status == 1 && session->vsync_before_commit) {
+	if (session->status == 1 && (session->vsync_before_commit ||
+			!session->intf->active)) {
 		pr_debug("mdp3_vsync_timer_func trigger\n");
 		vsync_notify_handler(session);
 		mod_timer(&session->vsync_timer,
@@ -366,10 +407,10 @@
 	return type;
 }
 
-static int mdp3_ctrl_get_source_format(struct msm_fb_data_type *mfd)
+static int mdp3_ctrl_get_source_format(u32 imgType)
 {
 	int format;
-	switch (mfd->fb_imgType) {
+	switch (imgType) {
 	case MDP_RGB_565:
 		format = MDP3_DMA_IBUF_FORMAT_RGB565;
 		break;
@@ -464,6 +505,7 @@
 	int frame_rate = mfd->panel_info->mipi.frame_rate;
 	int vbp, vfp, vspw;
 	int vtotal, vporch;
+	struct mdp3_notification dma_done_callback;
 
 	vbp = panel_info->lcdc.v_back_porch;
 	vfp = panel_info->lcdc.v_front_porch;
@@ -474,7 +516,7 @@
 	fix = &fbi->fix;
 	var = &fbi->var;
 
-	sourceConfig.format = mdp3_ctrl_get_source_format(mfd);
+	sourceConfig.format = mdp3_ctrl_get_source_format(mfd->fb_imgType);
 	sourceConfig.width = panel_info->xres;
 	sourceConfig.height = panel_info->yres;
 	sourceConfig.x = 0;
@@ -499,6 +541,13 @@
 		rc = dma->dma_config(dma, &sourceConfig, &outputConfig);
 	else
 		rc = -EINVAL;
+
+	if (outputConfig.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) {
+		dma_done_callback.handler = dma_done_notify_handler;
+		dma_done_callback.arg = mfd->mdp.private1;
+		dma->dma_done_notifier(dma, &dma_done_callback);
+	}
+
 	return rc;
 }
 
@@ -527,6 +576,8 @@
 	}
 
 	mdp3_batfet_ctrl(true);
+	mdp3_ctrl_notifier_register(mdp3_session,
+		&mdp3_session->mfd->mdp_sync_pt_data.notifier);
 
 	rc = mdp3_iommu_enable(MDP3_CLIENT_DMA_P);
 	if (rc) {
@@ -613,9 +664,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;
@@ -661,6 +709,8 @@
 	if (rc)
 		pr_err("fail to dettach MDP DMA SMMU\n");
 
+	mdp3_ctrl_notifier_unregister(mdp3_session,
+		&mdp3_session->mfd->mdp_sync_pt_data.notifier);
 	mdp3_batfet_ctrl(false);
 	mdp3_session->vsync_enabled = 0;
 	atomic_set(&mdp3_session->vsync_countdown, 0);
@@ -680,7 +730,7 @@
 	struct mdp3_session_data *mdp3_session;
 	struct mdp3_dma *mdp3_dma;
 	struct mdss_panel_data *panel;
-	struct mdp3_vsync_notification vsync_client;
+	struct mdp3_notification vsync_client;
 
 	pr_debug("mdp3_ctrl_reset_cmd\n");
 	mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
@@ -730,7 +780,7 @@
 	struct mdp3_session_data *mdp3_session;
 	struct mdp3_dma *mdp3_dma;
 	struct mdss_panel_data *panel;
-	struct mdp3_vsync_notification vsync_client;
+	struct mdp3_notification vsync_client;
 
 	pr_debug("mdp3_ctrl_reset\n");
 	mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
@@ -838,6 +888,15 @@
 {
 	int rc = 0;
 	struct mdp3_session_data *mdp3_session = mfd->mdp.private1;
+	struct mdp3_dma *dma = mdp3_session->dma;
+	struct fb_fix_screeninfo *fix;
+	struct fb_info *fbi = mfd->fbi;
+	int stride;
+	int format;
+
+	fix = &fbi->fix;
+	stride = req->src.width * ppp_bpp(req->src.format);
+	format = mdp3_ctrl_get_source_format(req->src.format);
 
 	mutex_lock(&mdp3_session->lock);
 
@@ -846,6 +905,18 @@
 
 	mdp3_session->overlay = *req;
 	if (req->id == MSMFB_NEW_REQUEST) {
+		if (dma->source_config.stride != stride ||
+				dma->source_config.width != req->src.width ||
+				dma->source_config.height != req->src.height ||
+				dma->source_config.format != format) {
+			dma->source_config.width = req->src.width;
+			dma->source_config.height = req->src.height,
+			dma->source_config.format = format;
+			dma->source_config.stride = stride;
+			mdp3_clk_enable(1, 0);
+			mdp3_session->dma->dma_config_source(dma);
+			mdp3_clk_enable(0, 0);
+		}
 		mdp3_session->overlay.id = 1;
 		req->id = 1;
 	}
@@ -859,10 +930,24 @@
 {
 	int rc = 0;
 	struct mdp3_session_data *mdp3_session = mfd->mdp.private1;
+	struct fb_info *fbi = mfd->fbi;
+	struct fb_fix_screeninfo *fix;
+	struct mdss_panel_info *panel_info = mfd->panel_info;
+	int format;
 
+	fix = &fbi->fix;
+	format = mdp3_ctrl_get_source_format(mfd->fb_imgType);
 	mutex_lock(&mdp3_session->lock);
 
 	if (mdp3_session->overlay.id == ndx && ndx == 1) {
+		struct mdp3_dma *dma = mdp3_session->dma;
+		dma->source_config.width = panel_info->xres,
+		dma->source_config.height = panel_info->yres,
+		dma->source_config.format = format;
+		dma->source_config.stride = fix->line_length;
+		mdp3_clk_enable(1, 0);
+		mdp3_session->dma->dma_config_source(dma);
+		mdp3_clk_enable(0, 0);
 		mdp3_session->overlay.id = MSMFB_NEW_REQUEST;
 		mdp3_bufq_deinit(&mdp3_session->bufq_in);
 	} else {
@@ -956,17 +1041,31 @@
 		return -EPERM;
 	}
 
+	mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_BEGIN);
 	data = mdp3_bufq_pop(&mdp3_session->bufq_in);
 	if (data) {
 		mdp3_ctrl_reset_countdown(mdp3_session, mfd);
 		mdp3_ctrl_clk_enable(mfd, 1);
-		mdp3_session->dma->update(mdp3_session->dma,
+		rc = mdp3_session->dma->update(mdp3_session->dma,
 			(void *)data->addr,
 			mdp3_session->intf);
+		/* This is for the previous frame */
+		if (rc < 0) {
+			mdp3_ctrl_notify(mdp3_session,
+				MDP_NOTIFY_FRAME_TIMEOUT);
+		} else {
+			if (mdp3_ctrl_get_intf_type(mfd) ==
+						MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) {
+				mdp3_ctrl_notify(mdp3_session,
+					MDP_NOTIFY_FRAME_DONE);
+			}
+		}
+
+		mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_FLUSHED);
 		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);
 	}
@@ -985,16 +1084,20 @@
 
 	mdss_fb_update_notify_update(mfd);
 
-	return rc;
+	return 0;
 }
 
-static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd)
+static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd,
+					struct mdp_overlay *req,
+					int image_size,
+					int *pipe_ndx)
 {
 	struct fb_info *fbi;
 	struct mdp3_session_data *mdp3_session;
 	u32 offset;
 	int bpp;
 	struct mdss_panel_info *panel_info = mfd->panel_info;
+	int rc;
 
 	pr_debug("mdp3_ctrl_pan_display\n");
 	if (!mfd || !mfd->mdp.private1)
@@ -1031,10 +1134,23 @@
 
 	if (mfd->fbi->screen_base) {
 		mdp3_ctrl_reset_countdown(mdp3_session, mfd);
+		mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_BEGIN);
 		mdp3_ctrl_clk_enable(mfd, 1);
-		mdp3_session->dma->update(mdp3_session->dma,
-				(void *)mfd->iova + offset,
+		rc = mdp3_session->dma->update(mdp3_session->dma,
+				(void *)(mfd->iova + offset),
 				mdp3_session->intf);
+		/* This is for the previous frame */
+		if (rc < 0) {
+			mdp3_ctrl_notify(mdp3_session,
+				MDP_NOTIFY_FRAME_TIMEOUT);
+		} else {
+			if (mdp3_ctrl_get_intf_type(mfd) ==
+						MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) {
+				mdp3_ctrl_notify(mdp3_session,
+					MDP_NOTIFY_FRAME_DONE);
+			}
+		}
+		mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_FLUSHED);
 	} else {
 		pr_debug("mdp3_ctrl_pan_display no memory, stop interface");
 		mdp3_clk_enable(1, 0);
@@ -1526,7 +1642,8 @@
 
 	req = &mdp3_session->req_overlay;
 
-	if (!mdp3_session->status && cmd != MSMFB_METADATA_GET) {
+	if (!mdp3_session->status && cmd != MSMFB_METADATA_GET &&
+		cmd != MSMFB_HISTOGRAM_STOP) {
 		pr_err("mdp3_ctrl_ioctl_handler, display off!\n");
 		return -EPERM;
 	}
@@ -1645,6 +1762,7 @@
 	memset(mdp3_session, 0, sizeof(struct mdp3_session_data));
 	mutex_init(&mdp3_session->lock);
 	INIT_WORK(&mdp3_session->clk_off_work, mdp3_dispatch_clk_off);
+	INIT_WORK(&mdp3_session->dma_done_work, mdp3_dispatch_dma_done);
 	atomic_set(&mdp3_session->vsync_countdown, 0);
 	mutex_init(&mdp3_session->histo_lock);
 	mdp3_session->dma = mdp3_get_dma_pipe(MDP3_DMA_CAP_ALL);
@@ -1680,6 +1798,7 @@
 	mdp3_bufq_init(&mdp3_session->bufq_out);
 	mdp3_session->histo_status = 0;
 	mdp3_session->lut_sel = 0;
+	BLOCKING_INIT_NOTIFIER_HEAD(&mdp3_session->notifier_head);
 
 	init_timer(&mdp3_session->vsync_timer);
 	mdp3_session->vsync_timer.function = mdp3_vsync_timer_func;
@@ -1708,14 +1827,17 @@
 	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;
+		mdp3_ctrl_notifier_register(mdp3_session,
+			&mdp3_session->mfd->mdp_sync_pt_data.notifier);
+	}
+
 	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_ctrl.h b/drivers/video/msm/mdss/mdp3_ctrl.h
index f2484ef..cfad1d3 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.h
+++ b/drivers/video/msm/mdss/mdp3_ctrl.h
@@ -49,6 +49,7 @@
 	struct mdp3_buffer_queue bufq_in;
 	struct mdp3_buffer_queue bufq_out;
 	struct work_struct clk_off_work;
+	struct work_struct dma_done_work;
 	int histo_status;
 	struct mutex histo_lock;
 	int lut_sel;
@@ -56,6 +57,7 @@
 	bool vsync_before_commit;
 	bool first_commit;
 	int clk_on;
+	struct blocking_notifier_head notifier_head;
 
 	int vsync_enabled;
 	atomic_t vsync_countdown; /* Used to count down  */
diff --git a/drivers/video/msm/mdss/mdp3_dma.c b/drivers/video/msm/mdss/mdp3_dma.c
index 3a2c94b..36d5cf1 100644
--- a/drivers/video/msm/mdss/mdp3_dma.c
+++ b/drivers/video/msm/mdss/mdp3_dma.c
@@ -27,26 +27,38 @@
 static void mdp3_vsync_intr_handler(int type, void *arg)
 {
 	struct mdp3_dma *dma = (struct mdp3_dma *)arg;
-	struct mdp3_vsync_notification vsync_client;
+	struct mdp3_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)
 {
 	struct mdp3_dma *dma = (struct mdp3_dma *)arg;
+	struct mdp3_notification dma_client;
 
 	pr_debug("mdp3_dma_done_intr_handler\n");
+	spin_lock(&dma->dma_lock);
+	dma_client = dma->dma_notifier_client;
 	complete(&dma->dma_comp);
+	spin_unlock(&dma->dma_lock);
 	mdp3_irq_disable_nosync(type);
+	if (dma_client.handler)
+		dma_client.handler(dma_client.arg);
 }
 
 static void mdp3_hist_done_intr_handler(int type, void *arg)
@@ -189,7 +201,7 @@
 }
 
 static void mdp3_dma_vsync_enable(struct mdp3_dma *dma,
-				struct mdp3_vsync_notification *vsync_client)
+				struct mdp3_notification *vsync_client)
 {
 	unsigned long flag;
 	int updated = 0;
@@ -220,6 +232,21 @@
 	}
 }
 
+static void mdp3_dma_done_notifier(struct mdp3_dma *dma,
+				struct mdp3_notification *dma_client)
+{
+	unsigned long flag;
+
+	spin_lock_irqsave(&dma->dma_lock, flag);
+	if (dma_client) {
+		dma->dma_notifier_client = *dma_client;
+	} else {
+		dma->dma_notifier_client.handler = NULL;
+		dma->dma_notifier_client.arg = NULL;
+	}
+	spin_unlock_irqrestore(&dma->dma_lock, flag);
+}
+
 static void mdp3_dma_clk_auto_gating(struct mdp3_dma *dma, int enable)
 {
 	u32 cgc;
@@ -304,6 +331,22 @@
 	return 0;
 }
 
+static void mdp3_dmap_config_source(struct mdp3_dma *dma)
+{
+	struct mdp3_dma_source *source_config = &dma->source_config;
+	u32 dma_p_cfg_reg, dma_p_size;
+
+	dma_p_cfg_reg = MDP3_REG_READ(MDP3_REG_DMA_P_CONFIG);
+	dma_p_cfg_reg &= ~MDP3_DMA_IBUF_FORMAT_MASK;
+	dma_p_cfg_reg |= source_config->format << 25;
+
+	dma_p_size = source_config->width | (source_config->height << 16);
+
+	MDP3_REG_WRITE(MDP3_REG_DMA_P_CONFIG, dma_p_cfg_reg);
+	MDP3_REG_WRITE(MDP3_REG_DMA_P_SIZE, dma_p_size);
+	MDP3_REG_WRITE(MDP3_REG_DMA_P_IBUF_Y_STRIDE, source_config->stride);
+}
+
 static int mdp3_dmas_config(struct mdp3_dma *dma,
 			struct mdp3_dma_source *source_config,
 			struct mdp3_dma_output_config *output_config)
@@ -339,6 +382,22 @@
 	return 0;
 }
 
+static void mdp3_dmas_config_source(struct mdp3_dma *dma)
+{
+	struct mdp3_dma_source *source_config = &dma->source_config;
+	u32 dma_s_cfg_reg, dma_s_size;
+
+	dma_s_cfg_reg = MDP3_REG_READ(MDP3_REG_DMA_S_CONFIG);
+	dma_s_cfg_reg &= ~MDP3_DMA_IBUF_FORMAT_MASK;
+	dma_s_cfg_reg |= source_config->format << 25;
+
+	dma_s_size = source_config->width | (source_config->height << 16);
+
+	MDP3_REG_WRITE(MDP3_REG_DMA_S_CONFIG, dma_s_cfg_reg);
+	MDP3_REG_WRITE(MDP3_REG_DMA_S_SIZE, dma_s_size);
+	MDP3_REG_WRITE(MDP3_REG_DMA_S_IBUF_Y_STRIDE, source_config->stride);
+}
+
 static int mdp3_dmap_cursor_config(struct mdp3_dma *dma,
 				struct mdp3_dma_cursor *cursor)
 {
@@ -529,13 +588,20 @@
 {
 	unsigned long flag;
 	int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC;
+	int rc = 0;
 
 	pr_debug("mdp3_dmap_update\n");
 
 	if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) {
 		cb_type = MDP3_DMA_CALLBACK_TYPE_DMA_DONE;
-		if (intf->active)
-			wait_for_completion_killable(&dma->dma_comp);
+		if (intf->active) {
+			rc = wait_for_completion_timeout(&dma->dma_comp,
+				KOFF_TIMEOUT);
+			if (rc <= 0) {
+				WARN(1, "cmd kickoff timed out (%d)\n", rc);
+				rc = -1;
+			}
+		}
 	}
 	spin_lock_irqsave(&dma->dma_lock, flag);
 	MDP3_REG_WRITE(MDP3_REG_DMA_P_IBUF_ADDR, (u32)buf);
@@ -550,16 +616,22 @@
 		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);
 
 	mdp3_dma_callback_enable(dma, cb_type);
 	pr_debug("mdp3_dmap_update wait for vsync_comp in\n");
-	if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO)
-		wait_for_completion_killable(&dma->vsync_comp);
+	if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) {
+		rc = wait_for_completion_timeout(&dma->vsync_comp,
+			KOFF_TIMEOUT);
+		if (rc <= 0)
+			rc = -1;
+	}
 	pr_debug("mdp3_dmap_update wait for vsync_comp out\n");
-	return 0;
+	return rc;
 }
 
 static int mdp3_dmas_update(struct mdp3_dma *dma, void *buf,
@@ -844,6 +916,7 @@
 	switch (dma->dma_sel) {
 	case MDP3_DMA_P:
 		dma->dma_config = mdp3_dmap_config;
+		dma->dma_config_source = mdp3_dmap_config_source;
 		dma->config_cursor = mdp3_dmap_cursor_config;
 		dma->config_ccs = mdp3_dmap_ccs_config;
 		dma->config_histo = mdp3_dmap_histo_config;
@@ -853,11 +926,13 @@
 		dma->get_histo = mdp3_dmap_histo_get;
 		dma->histo_op = mdp3_dmap_histo_op;
 		dma->vsync_enable = mdp3_dma_vsync_enable;
+		dma->dma_done_notifier = mdp3_dma_done_notifier;
 		dma->start = mdp3_dma_start;
 		dma->stop = mdp3_dma_stop;
 		break;
 	case MDP3_DMA_S:
 		dma->dma_config = mdp3_dmas_config;
+		dma->dma_config_source = mdp3_dmas_config_source;
 		dma->config_cursor = NULL;
 		dma->config_ccs = NULL;
 		dma->config_histo = NULL;
diff --git a/drivers/video/msm/mdss/mdp3_dma.h b/drivers/video/msm/mdss/mdp3_dma.h
index 6983e55..207168f 100644
--- a/drivers/video/msm/mdss/mdp3_dma.h
+++ b/drivers/video/msm/mdss/mdp3_dma.h
@@ -14,6 +14,7 @@
 #ifndef MDP3_DMA_H
 #define MDP3_DMA_H
 
+#include <linux/notifier.h>
 #include <linux/sched.h>
 
 #define MDP_HISTOGRAM_BL_SCALE_MAX 1024
@@ -227,7 +228,7 @@
 	u32 extra[2];
 };
 
-struct mdp3_vsync_notification {
+struct mdp3_notification {
 	void (*handler)(void *arg);
 	void *arg;
 };
@@ -245,7 +246,8 @@
 	struct completion vsync_comp;
 	struct completion dma_comp;
 	struct completion histo_comp;
-	struct mdp3_vsync_notification vsync_client;
+	struct mdp3_notification vsync_client;
+	struct mdp3_notification dma_notifier_client;
 
 	struct mdp3_dma_output_config output_config;
 	struct mdp3_dma_source source_config;
@@ -256,11 +258,14 @@
 	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,
 			struct mdp3_dma_output_config *output_config);
 
+	void (*dma_config_source)(struct mdp3_dma *dma);
+
 	int (*start)(struct mdp3_dma *dma, struct mdp3_intf *intf);
 
 	int (*stop)(struct mdp3_dma *dma, struct mdp3_intf *intf);
@@ -288,7 +293,10 @@
 	int (*histo_op)(struct mdp3_dma *dma, u32 op);
 
 	void (*vsync_enable)(struct mdp3_dma *dma,
-			struct mdp3_vsync_notification *vsync_client);
+			struct mdp3_notification *vsync_client);
+
+	void (*dma_done_notifier)(struct mdp3_dma *dma,
+			struct mdp3_notification *dma_client);
 };
 
 struct mdp3_video_intf_cfg {
diff --git a/drivers/video/msm/mdss/mdp3_hwio.h b/drivers/video/msm/mdss/mdp3_hwio.h
index b457c10..5205b42 100644
--- a/drivers/video/msm/mdss/mdp3_hwio.h
+++ b/drivers/video/msm/mdss/mdp3_hwio.h
@@ -118,6 +118,9 @@
 #define MDP3_REG_DMA_S_IBUF_Y_STRIDE			0xA000C
 #define MDP3_REG_DMA_S_OUT_XY				0xA0010
 
+/*DMA MASK*/
+#define MDP3_DMA_IBUF_FORMAT_MASK 0x06000000
+
 /*MISR*/
 #define MDP3_REG_MODE_CLK				0x000D0000
 #define MDP3_REG_MISR_RESET_CLK			0x000D0004
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..b89a935 100644
--- a/drivers/video/msm/mdss/mdss_dsi.h
+++ b/drivers/video/msm/mdss/mdss_dsi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -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;
@@ -330,13 +330,14 @@
 void mdss_dsi_phy_enable(struct mdss_dsi_ctrl_pdata *ctrl, int on);
 void mdss_dsi_phy_init(struct mdss_panel_data *pdata);
 void mdss_dsi_phy_sw_reset(unsigned char *ctrl_base);
-void mdss_dsi_cmd_test_pattern(struct mdss_panel_data *pdata);
+void mdss_dsi_cmd_test_pattern(struct mdss_dsi_ctrl_pdata *ctrl);
+void mdss_dsi_video_test_pattern(struct mdss_dsi_ctrl_pdata *ctrl);
 void mdss_dsi_panel_pwm_cfg(struct mdss_dsi_ctrl_pdata *ctrl);
 
 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 37ccd4f..bd156fc 100644
--- a/drivers/video/msm/mdss/mdss_dsi_host.c
+++ b/drivers/video/msm/mdss/mdss_dsi_host.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -200,28 +200,34 @@
 	spin_unlock(&ctrl->irq_lock);
 }
 
-void mdss_dsi_cmd_test_pattern(struct mdss_panel_data *pdata)
+void mdss_dsi_video_test_pattern(struct mdss_dsi_ctrl_pdata *ctrl)
 {
-	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 	int i;
 
-	if (pdata == NULL) {
-		pr_err("%s: Invalid input data\n", __func__);
-		return;
-	}
-
-	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
-				panel_data);
-
-	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x015c, 0x201);
-	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x016c, 0xff0000); /* red */
+	MIPI_OUTP((ctrl->ctrl_base) + 0x015c, 0x021);
+	MIPI_OUTP((ctrl->ctrl_base) + 0x0164, 0xff0000); /* red */
 	i = 0;
 	while (i++ < 50) {
-		MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0184, 0x1);
+		MIPI_OUTP((ctrl->ctrl_base) + 0x0180, 0x1);
 		/* Add sleep to get ~50 fps frame rate*/
 		msleep(20);
 	}
-	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x015c, 0x0);
+	MIPI_OUTP((ctrl->ctrl_base) + 0x015c, 0x0);
+}
+
+void mdss_dsi_cmd_test_pattern(struct mdss_dsi_ctrl_pdata *ctrl)
+{
+	int i;
+
+	MIPI_OUTP((ctrl->ctrl_base) + 0x015c, 0x201);
+	MIPI_OUTP((ctrl->ctrl_base) + 0x016c, 0xff0000); /* red */
+	i = 0;
+	while (i++ < 50) {
+		MIPI_OUTP((ctrl->ctrl_base) + 0x0184, 0x1);
+		/* Add sleep to get ~50 fps frame rate*/
+		msleep(20);
+	}
+	MIPI_OUTP((ctrl->ctrl_base) + 0x015c, 0x0);
 }
 
 void mdss_dsi_host_init(struct mipi_panel_info *pinfo,
@@ -1155,38 +1161,55 @@
 				__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);
@@ -1211,9 +1234,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);
@@ -1224,6 +1247,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)
@@ -1313,6 +1337,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 06f6959..8c3e470 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;
 	}
 
@@ -459,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;
@@ -695,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);
@@ -762,6 +767,8 @@
 			ctrl_pdata->bklt_ctrl = BL_DCS_CMD;
 		}
 	}
+	rc = of_property_read_u32(np, "qcom,mdss-brightness-max-level", &tmp);
+	pinfo->brightness_max = (!rc ? tmp : MDSS_MAX_BL_BRIGHTNESS);
 	rc = of_property_read_u32(np, "qcom,mdss-dsi-bl-min-level", &tmp);
 	pinfo->bl_min = (!rc ? tmp : 0);
 	rc = of_property_read_u32(np, "qcom,mdss-dsi-bl-max-level", &tmp);
diff --git a/drivers/video/msm/mdss/mdss_edp.c b/drivers/video/msm/mdss/mdss_edp.c
index bb27e6b..95c746e 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;
 		}
@@ -697,10 +697,15 @@
 static int mdss_edp_device_register(struct mdss_edp_drv_pdata *edp_drv)
 {
 	int ret;
+	u32 tmp;
 
 	mdss_edp_edid2pinfo(edp_drv);
 	edp_drv->panel_data.panel_info.bl_min = 1;
 	edp_drv->panel_data.panel_info.bl_max = 255;
+	ret = of_property_read_u32(edp_drv->pdev->dev.of_node,
+		"qcom,mdss-brightness-max-level", &tmp);
+	edp_drv->panel_data.panel_info.brightness_max =
+		(!ret ? tmp : MDSS_MAX_BL_BRIGHTNESS);
 
 	edp_drv->panel_data.event_handler = mdss_edp_event_handler;
 	edp_drv->panel_data.set_backlight = mdss_edp_set_backlight;
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index c15c02b..77080e8 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -126,6 +126,10 @@
 		ret = wait_for_completion_interruptible_timeout(
 						&mfd->update.comp, 4 * HZ);
 		to_user = (unsigned int)mfd->update.value;
+		if (mfd->update.type == NOTIFY_TYPE_SUSPEND) {
+			to_user = (unsigned int)mfd->update.type;
+			ret = 1;
+		}
 	} else if (notify == NOTIFY_UPDATE_STOP) {
 		INIT_COMPLETION(mfd->no_update.comp);
 		ret = wait_for_completion_interruptible_timeout(
@@ -146,6 +150,47 @@
 	return ret;
 }
 
+static int mdss_fb_splash_thread(void *data)
+{
+	struct msm_fb_data_type *mfd = data;
+	int ret = -EINVAL;
+	struct fb_info *fbi = NULL;
+	int ov_index[2];
+
+	if (!mfd || !mfd->fbi || !mfd->mdp.splash_fnc) {
+		pr_err("Invalid input parameter\n");
+		goto end;
+	}
+
+	fbi = mfd->fbi;
+
+	ret = mdss_fb_open(fbi, current->tgid);
+	if (ret) {
+		pr_err("fb_open failed\n");
+		goto end;
+	}
+
+	mfd->bl_updated = true;
+	mdss_fb_set_backlight(mfd, mfd->panel_info->bl_max >> 1);
+
+	ret = mfd->mdp.splash_fnc(mfd, ov_index, MDP_CREATE_SPLASH_OV);
+	if (ret) {
+		pr_err("Splash image failed\n");
+		goto splash_err;
+	}
+
+	do {
+		schedule_timeout_interruptible(SPLASH_THREAD_WAIT_TIMEOUT * HZ);
+	} while (!kthread_should_stop());
+
+	mfd->mdp.splash_fnc(mfd, ov_index, MDP_REMOVE_SPLASH_OV);
+
+splash_err:
+	mdss_fb_release(fbi, current->tgid);
+end:
+	return ret;
+}
+
 static int lcd_backlight_registered;
 
 static void mdss_fb_set_bl_brightness(struct led_classdev *led_cdev,
@@ -154,13 +199,13 @@
 	struct msm_fb_data_type *mfd = dev_get_drvdata(led_cdev->dev->parent);
 	int bl_lvl;
 
-	if (value > MDSS_MAX_BL_BRIGHTNESS)
-		value = MDSS_MAX_BL_BRIGHTNESS;
+	if (value > mfd->panel_info->brightness_max)
+		value = mfd->panel_info->brightness_max;
 
 	/* This maps android backlight level 0 to 255 into
 	   driver backlight level 0 to bl_max with rounding */
 	MDSS_BRIGHT_TO_BL(bl_lvl, value, mfd->panel_info->bl_max,
-						MDSS_MAX_BL_BRIGHTNESS);
+				mfd->panel_info->brightness_max);
 
 	if (!bl_lvl && value)
 		bl_lvl = 1;
@@ -374,6 +419,9 @@
 
 	/* android supports only one lcd-backlight/lcd for now */
 	if (!lcd_backlight_registered) {
+
+		backlight_led.brightness = mfd->panel_info->brightness_max;
+		backlight_led.max_brightness = mfd->panel_info->brightness_max;
 		if (led_classdev_register(&pdev->dev, &backlight_led))
 			pr_err("led_classdev_register failed\n");
 		else
@@ -403,6 +451,16 @@
 	else
 		mfd->mdp_sync_pt_data.threshold = 2;
 
+	if (mfd->index == 0) {
+		mfd->splash_thread = kthread_run(mdss_fb_splash_thread, mfd,
+				"mdss_fb_splash");
+		if (IS_ERR(mfd->splash_thread)) {
+			pr_err("unable to start splash thread %d\n",
+				mfd->index);
+			mfd->splash_thread = NULL;
+		}
+	}
+
 	return rc;
 }
 
@@ -1188,6 +1246,12 @@
 	pinfo->ref_cnt++;
 	mfd->ref_cnt++;
 
+	/* Stop the splash thread once userspace open the fb node */
+	if (mfd->splash_thread && mfd->ref_cnt > 1) {
+		kthread_stop(mfd->splash_thread);
+		mfd->splash_thread = NULL;
+	}
+
 	return 0;
 
 blank_error:
@@ -1565,7 +1629,7 @@
 		(var->yoffset / info->fix.ypanstep) * info->fix.ypanstep;
 
 	if (mfd->mdp.dma_fnc)
-		mfd->mdp.dma_fnc(mfd);
+		mfd->mdp.dma_fnc(mfd, NULL, 0, NULL);
 	else
 		pr_warn("dma function not set for panel type=%d\n",
 				mfd->panel.type);
@@ -1836,11 +1900,11 @@
 
 int mdss_fb_dcm(struct msm_fb_data_type *mfd, int req_state)
 {
-	int ret = -EINVAL;
+	int ret = 0;
 
 	if (req_state == mfd->dcm_state) {
-		pr_warn("Already in correct DCM state");
-		ret = 0;
+		pr_warn("Already in correct DCM/DTM state");
+		return ret;
 	}
 
 	switch (req_state) {
@@ -1856,11 +1920,12 @@
 		break;
 	case DCM_ENTER:
 		if (mfd->dcm_state == DCM_UNBLANK) {
-			/* Keep unblank path available for only
-			DCM operation */
+			/*
+			 * Keep unblank path available for only
+			 * DCM operation
+			 */
 			mfd->panel_power_on = false;
 			mfd->dcm_state = DCM_ENTER;
-			ret = 0;
 		}
 		break;
 	case DCM_EXIT:
@@ -1868,7 +1933,6 @@
 			/* Release the unblank path for exit */
 			mfd->panel_power_on = true;
 			mfd->dcm_state = DCM_EXIT;
-			ret = 0;
 		}
 		break;
 	case DCM_BLANK:
@@ -1882,7 +1946,16 @@
 			}
 		}
 		break;
+	case DTM_ENTER:
+		if (mfd->dcm_state == DCM_UNINIT)
+			mfd->dcm_state = DTM_ENTER;
+		break;
+	case DTM_EXIT:
+		if (mfd->dcm_state == DTM_ENTER)
+			mfd->dcm_state = DCM_UNINIT;
+		break;
 	}
+
 	return ret;
 }
 
@@ -2187,6 +2260,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");
@@ -2214,6 +2288,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,
@@ -2221,7 +2297,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_fb.h b/drivers/video/msm/mdss/mdss_fb.h
index e245dd3..e796fc6 100644
--- a/drivers/video/msm/mdss/mdss_fb.h
+++ b/drivers/video/msm/mdss/mdss_fb.h
@@ -33,6 +33,8 @@
 #define WAIT_DISP_OP_TIMEOUT ((WAIT_FENCE_FIRST_TIMEOUT + \
 		WAIT_FENCE_FINAL_TIMEOUT) * MDP_MAX_FENCE_FD)
 
+#define SPLASH_THREAD_WAIT_TIMEOUT 3
+
 #ifndef MAX
 #define  MAX(x, y) (((x) > (y)) ? (x) : (y))
 #endif
@@ -67,6 +69,11 @@
 	MDP_NOTIFY_FRAME_TIMEOUT,
 };
 
+enum mdp_splash_event {
+	MDP_CREATE_SPLASH_OV = 0,
+	MDP_REMOVE_SPLASH_OV,
+};
+
 struct disp_info_type_suspend {
 	int op_enable;
 	int panel_power_on;
@@ -110,7 +117,8 @@
 	int (*kickoff_fnc)(struct msm_fb_data_type *mfd,
 					struct mdp_display_commit *data);
 	int (*ioctl_handler)(struct msm_fb_data_type *mfd, u32 cmd, void *arg);
-	void (*dma_fnc)(struct msm_fb_data_type *mfd);
+	void (*dma_fnc)(struct msm_fb_data_type *mfd, struct mdp_overlay *req,
+				int image_len, int *pipe_ndx);
 	int (*cursor_update)(struct msm_fb_data_type *mfd,
 				struct fb_cursor *cursor);
 	int (*lut_update)(struct msm_fb_data_type *mfd, struct fb_cmap *cmap);
@@ -119,6 +127,7 @@
 	int (*update_ad_input)(struct msm_fb_data_type *mfd);
 	int (*panel_register_done)(struct mdss_panel_data *pdata);
 	u32 (*fb_stride)(u32 fb_index, u32 xres, int bpp);
+	int (*splash_fnc) (struct msm_fb_data_type *mfd, int *index, int req);
 	struct msm_sync_pt_data *(*get_sync_fnc)(struct msm_fb_data_type *mfd,
 				const struct mdp_buf_sync *buf_sync);
 	void *private1;
@@ -201,6 +210,8 @@
 	wait_queue_head_t idle_wait_q;
 	bool shutdown_pending;
 
+	struct task_struct *splash_thread;
+
 	struct msm_fb_backup_type msm_fb_backup;
 	struct completion power_set_comp;
 	u32 is_power_setting;
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index b45a446..99f45ed 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -70,6 +70,24 @@
 #define MSM_HDMI_AUDIO_CHANNEL_7	7
 #define MSM_HDMI_AUDIO_CHANNEL_8	8
 
+#define NUM_MODES_AVI 20
+
+/* AVI Infoframe data byte 3, bit 7 (msb) represents ITC bit */
+#define SET_ITC_BIT(byte)  (byte = (byte | BIT(7)))
+#define CLR_ITC_BIT(byte)  (byte = (byte & ~BIT(7)))
+
+/*
+ * CN represents IT content type, if ITC bit in infoframe data byte 3
+ * is set, CN bits will represent content type as below:
+ * 0b00 Graphics
+ * 0b01 Photo
+ * 0b10 Cinema
+ * 0b11 Game
+*/
+#define CONFIG_CN_BITS(bits, byte) \
+		(byte = (byte & ~(BIT(4) | BIT(5))) |\
+			((bits & (BIT(0) | BIT(1))) << 4))
+
 enum msm_hdmi_supported_audio_sample_rates {
 	AUDIO_SAMPLE_RATE_32KHZ,
 	AUDIO_SAMPLE_RATE_44_1KHZ,
@@ -137,12 +155,6 @@
 	}
 } /* hdmi_pm_name */
 
-static DEFINE_MUTEX(avi_iframe_lut_lock);
-#define NUM_MODES_AVI 20
-#define SET_ITC_BIT(byte)  (byte | 0x80)
-#define CLR_ITC_BIT(byte)  (byte & 0x7F)
-#define CONFIG_CN_BITS(bits, byte)  ((byte & ~(0x03 << 4)) | (bits << 4))
-
 static u8 hdmi_tx_avi_iframe_lut[][NUM_MODES_AVI] = {
 	{0x10,	0x10,	0x10,	0x10,	0x10,	0x10,	0x10,	0x10,	0x10,
 	 0x10,	0x10,	0x10,	0x10,	0x10,	0x10,	0x10,	0x10,	0x10,
@@ -210,55 +222,6 @@
 		{20480, 247500} } },
 };
 
-/* To statically config ITC bit from sysfs attribute */
-static int hdmi_tx_config_itc_bit(int itc)
-{
-	int ret = 0, loop = NUM_MODES_AVI;
-
-	if (mutex_lock_interruptible(&avi_iframe_lut_lock)) {
-		ret = -ERESTARTSYS;
-		goto signal_intr;
-	}
-
-	do {
-		--loop;
-		if (itc == 0)
-			hdmi_tx_avi_iframe_lut[2][loop] =
-				CLR_ITC_BIT(hdmi_tx_avi_iframe_lut[2][loop]);
-		if (itc == 1)
-			hdmi_tx_avi_iframe_lut[2][loop] =
-				SET_ITC_BIT(hdmi_tx_avi_iframe_lut[2][loop]);
-	} while (loop);
-
-	mutex_unlock(&avi_iframe_lut_lock);
-
-signal_intr:
-	return ret;
-}
-
-/* To configure CN0_1 bits from sysfs attribute */
-static int hdmi_tx_config_cn_bits(int cns)
-{
-	int ret = 0, loop = NUM_MODES_AVI;
-
-	if (mutex_lock_interruptible(&avi_iframe_lut_lock)) {
-		ret = -ERESTARTSYS;
-		goto signal_intr;
-	}
-
-	do {
-		--loop;
-		hdmi_tx_avi_iframe_lut[4][loop] =
-			CONFIG_CN_BITS(cns, hdmi_tx_avi_iframe_lut[4][loop]);
-	} while (loop);
-
-	mutex_unlock(&avi_iframe_lut_lock);
-
-signal_intr:
-	return ret;
-}
-
-
 static bool hdmi_tx_is_cea_format(int mode)
 {
 	bool cea_fmt;
@@ -682,53 +645,80 @@
 	struct device_attribute *attr, const char *buf, size_t count)
 {
 	ssize_t ret = strnlen(buf, PAGE_SIZE);
-	int err = 0;
-	int itc = 0, rc = 0;
+	u8 *avi_byte3 = hdmi_tx_avi_iframe_lut[2];
+	struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
+	int loop = 0, itc = 0, rc = 0;
+
+	hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev);
+
+	if (!hdmi_ctrl) {
+		DEV_ERR("%s: invalid input\n", __func__);
+		return -EINVAL;
+	}
 
 	rc = kstrtoint(buf, 10, &itc);
 	if (rc) {
-		DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, rc);
+		DEV_ERR("%s: kstrtoint failed. rc =%d\n", __func__, rc);
 		return rc;
 	}
 
-	if (itc == 0 || itc == 1) {
-		if (hdmi_tx_config_itc_bit(itc))
-			ret = err;
-		else
-			DEV_DBG("%s: '%d is configured'!\n", __func__, itc);
-	} else {
-		DEV_ERR("%s: unknown ITC '%d', should be either 0 or 1\n",
-				__func__, itc);
+	if (itc < 0 || itc > 1) {
+		DEV_ERR("%s: Invalid ITC %d\n", __func__, itc);
+		return ret;
 	}
 
+	if (mutex_lock_interruptible(&hdmi_ctrl->lut_lock))
+		return -ERESTARTSYS;
+
+	for (loop = 0; loop < NUM_MODES_AVI; loop++) {
+		if (itc)
+			SET_ITC_BIT(avi_byte3[loop]);
+		else
+			CLR_ITC_BIT(avi_byte3[loop]);
+	}
+
+	mutex_unlock(&hdmi_ctrl->lut_lock);
+
 	return ret;
 } /* hdmi_tx_sysfs_wta_avi_itc */
 
-static ssize_t hdmi_tx_sysfs_wta_avi_cn0_1(struct device *dev,
+static ssize_t hdmi_tx_sysfs_wta_avi_cn_bits(struct device *dev,
 	struct device_attribute *attr, const char *buf, size_t count)
 {
 	ssize_t ret = strnlen(buf, PAGE_SIZE);
-	int err = 0;
-	int cns = 0, rc = 0;
+	u8 *avi_byte5 = hdmi_tx_avi_iframe_lut[4];
+	struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
+	int loop = 0, cn_bits = 0, rc = 0;
 
-	rc = kstrtoint(buf, 10, &cns);
+	hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev);
+
+	if (!hdmi_ctrl) {
+		DEV_ERR("%s: invalid input\n", __func__);
+		return -EINVAL;
+	}
+
+	rc = kstrtoint(buf, 10, &cn_bits);
 	if (rc) {
 		DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, rc);
 		return rc;
 	}
 
-	if (cns == 0 || cns == 1 || cns == 2 || cns == 3) {
-		if (hdmi_tx_config_cn_bits(cns))
-			ret = err;
-		else
-			DEV_DBG("%s: '%d is configured'!\n", __func__, cns);
-	} else {
-		DEV_ERR("%s: unknown CN '%d' should be either 0 or 1, 2 ,3\n",
-				__func__, cns);
+	/* As per CEA-861-E, CN is a positive number and can be max 3 */
+	if (cn_bits < 0 || cn_bits > 3) {
+		DEV_ERR("%s: Invalid CN %d\n", __func__, cn_bits);
+		return ret;
 	}
 
+	if (mutex_lock_interruptible(&hdmi_ctrl->lut_lock))
+		return -ERESTARTSYS;
+
+	for (loop = 0; loop < NUM_MODES_AVI; loop++)
+		CONFIG_CN_BITS(cn_bits, avi_byte5[loop]);
+
+	mutex_unlock(&hdmi_ctrl->lut_lock);
+
 	return ret;
-} /* hdmi_tx_sysfs_wta_avi_cn0_1 */
+} /* hdmi_tx_sysfs_wta_cn_bits */
 
 static DEVICE_ATTR(connected, S_IRUGO, hdmi_tx_sysfs_rda_connected, NULL);
 static DEVICE_ATTR(hpd, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_hpd,
@@ -739,7 +729,7 @@
 	hdmi_tx_sysfs_rda_product_description,
 	hdmi_tx_sysfs_wta_product_description);
 static DEVICE_ATTR(avi_itc, S_IWUSR, NULL, hdmi_tx_sysfs_wta_avi_itc);
-static DEVICE_ATTR(avi_cn0_1, S_IWUSR, NULL, hdmi_tx_sysfs_wta_avi_cn0_1);
+static DEVICE_ATTR(avi_cn0_1, S_IWUSR, NULL, hdmi_tx_sysfs_wta_avi_cn_bits);
 
 static struct attribute *hdmi_tx_fs_attrs[] = {
 	&dev_attr_connected.attr,
@@ -2844,6 +2834,7 @@
 	switch_dev_unregister(&hdmi_ctrl->sdev);
 	if (hdmi_ctrl->workq)
 		destroy_workqueue(hdmi_ctrl->workq);
+	mutex_destroy(&hdmi_ctrl->lut_lock);
 	mutex_destroy(&hdmi_ctrl->mutex);
 
 	hdmi_tx_hw.ptr = NULL;
@@ -2872,6 +2863,7 @@
 
 	hdmi_setup_video_mode_lut();
 	mutex_init(&hdmi_ctrl->mutex);
+	mutex_init(&hdmi_ctrl->lut_lock);
 	hdmi_ctrl->workq = create_workqueue("hdmi_tx_workq");
 	if (!hdmi_ctrl->workq) {
 		DEV_ERR("%s: hdmi_tx_workq creation failed.\n", __func__);
@@ -2920,6 +2912,7 @@
 fail_create_workq:
 	if (hdmi_ctrl->workq)
 		destroy_workqueue(hdmi_ctrl->workq);
+	mutex_destroy(&hdmi_ctrl->lut_lock);
 	mutex_destroy(&hdmi_ctrl->mutex);
 fail_no_hdmi:
 	return rc;
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.h b/drivers/video/msm/mdss/mdss_hdmi_tx.h
index 66071e9..0787dee 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.h
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.h
@@ -54,6 +54,7 @@
 	struct hdmi_audio audio_data;
 
 	struct mutex mutex;
+	struct mutex lut_lock;
 	struct kobject *kobj;
 	struct switch_dev sdev;
 	struct switch_dev audio_sdev;
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index b218b1e..131744c 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -546,6 +546,8 @@
 	if (clk) {
 		pr_debug("clk=%d en=%d\n", clk_idx, enable);
 		if (enable) {
+			if (clk_idx == MDSS_CLK_MDP_VSYNC)
+				clk_set_rate(clk, 19200000);
 			ret = clk_prepare_enable(clk);
 		} else {
 			clk_disable_unprepare(clk);
@@ -1316,7 +1318,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 +1355,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 +1467,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);
@@ -2108,7 +2118,7 @@
 	int rc;
 
 	if (!mdss_res || !mdss_res->pan_cfg.init_done)
-		rc = -EPROBE_DEFER;
+		return -EPROBE_DEFER;
 	if (mdss_res->pan_cfg.lk_cfg)
 		rc = 1;
 	else
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index 769f9b2..8918df8 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -274,7 +274,6 @@
 	u32 hist_cnt_sent;
 	u32 hist_cnt_time;
 	u32 frame_cnt;
-	u32 is_kick_ready;
 	struct completion comp;
 	u32 data[HIST_V_SIZE];
 	struct mutex hist_mutex;
@@ -289,6 +288,7 @@
 struct mdss_ad_info {
 	u8 num;
 	u8 calc_hw_num;
+	u32 ops;
 	u32 sts;
 	u32 reg_sts;
 	u32 state;
@@ -516,7 +516,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 bad4d06..d57e4fb 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -1062,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;
@@ -1108,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();
@@ -1123,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;
@@ -1141,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) {
@@ -1900,8 +1913,10 @@
 	if (ctl->wait_pingpong)
 		ctl->wait_pingpong(ctl, NULL);
 
-	/* postprocessing setup, including dspp */
-	mdss_mdp_pp_setup_locked(ctl);
+	if (ctl->mfd && ctl->mfd->dcm_state != DTM_ENTER)
+		/* postprocessing setup, including dspp */
+		mdss_mdp_pp_setup_locked(ctl);
+
 	mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_FLUSH, ctl->flush_bits);
 	if (sctl) {
 		mdss_mdp_ctl_write(sctl, MDSS_MDP_REG_CTL_FLUSH,
diff --git a/drivers/video/msm/mdss/mdss_mdp_hwio.h b/drivers/video/msm/mdss/mdss_mdp_hwio.h
index b6f94d0..5d3e841 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -20,7 +20,6 @@
 #define GC_LUT_SEGMENTS	16
 #define ENHIST_LUT_ENTRIES 256
 #define HIST_V_SIZE	256
-#define SIX_ZONE_LUT_ENTRIES 384
 
 #define MDSS_MDP_HW_REV_100		0x10000000
 #define MDSS_MDP_HW_REV_102		0x10020000
@@ -108,7 +107,9 @@
 	MDSS_MDP_MAX_CTL
 };
 
-#define MDSS_MDP_REG_CTL_OFFSET(ctl) (0x00600 + ((ctl) * 0x100))
+#define MDSS_MDP_CTL_ADDRESS_OFFSET			0x100
+#define MDSS_MDP_REG_CTL_OFFSET(ctl) (0x00600 + ((ctl) * \
+					 MDSS_MDP_CTL_ADDRESS_OFFSET))
 
 #define MDSS_MDP_REG_CTL_LAYER(lm)			((lm) * 0x004)
 #define MDSS_MDP_REG_CTL_TOP				0x014
@@ -159,7 +160,10 @@
 	MDSS_MDP_CHROMA_420
 };
 
-#define MDSS_MDP_REG_SSPP_OFFSET(pipe) (0x01200 + ((pipe) * 0x400))
+
+#define MDSS_MDP_SSPP_ADDRESS_OFFSET			0x400
+#define MDSS_MDP_REG_SSPP_OFFSET(pipe) (0x01200 + ((pipe) * \
+					MDSS_MDP_SSPP_ADDRESS_OFFSET))
 
 #define MDSS_MDP_REG_SSPP_SRC_SIZE			0x000
 #define MDSS_MDP_REG_SSPP_SRC_IMG_SIZE			0x004
@@ -175,6 +179,7 @@
 #define MDSS_MDP_REG_SSPP_STILE_FRAME_SIZE		0x02C
 #define MDSS_MDP_REG_SSPP_SRC_FORMAT			0x030
 #define MDSS_MDP_REG_SSPP_SRC_UNPACK_PATTERN		0x034
+#define MDSS_MDP_REG_SSPP_SRC_CONSTANT_COLOR		0x03C
 #define MDSS_MDP_REG_SSPP_REQPRIO_FIFO_WM_0		0x050
 #define MDSS_MDP_REG_SSPP_REQPRIO_FIFO_WM_1		0x054
 #define MDSS_MDP_REG_SSPP_REQPRIO_FIFO_WM_2		0x058
@@ -280,8 +285,9 @@
 	MDSS_MDP_MAX_STAGE
 };
 
-#define MDSS_MDP_REG_LM_OFFSET(lm) (0x03200 + ((lm) * 0x400))
-
+#define MDSS_MDP_LM_ADDRESS_OFFSET			0x400
+#define MDSS_MDP_REG_LM_OFFSET(lm) (0x03200 + ((lm) * \
+					MDSS_MDP_LM_ADDRESS_OFFSET))
 #define MDSS_MDP_REG_LM_OP_MODE				0x000
 #define MDSS_MDP_REG_LM_OUT_SIZE			0x004
 #define MDSS_MDP_REG_LM_BORDER_COLOR_0			0x008
@@ -423,13 +429,16 @@
 	MDSS_MDP_MAX_DSPP
 };
 
-#define MDSS_MDP_REG_DSPP_OFFSET(pipe)	(0x4600 + ((pipe) * 0x400))
+#define MDSS_MDP_DSPP_ADDRESS_OFFSET			0x400
+#define MDSS_MDP_REG_DSPP_OFFSET(pipe)	(0x4600 + ((pipe) * \
+					MDSS_MDP_DSPP_ADDRESS_OFFSET))
 #define MDSS_MDP_REG_DSPP_OP_MODE			0x000
 #define MDSS_MDP_REG_DSPP_PCC_BASE			0x030
 #define MDSS_MDP_REG_DSPP_DITHER_DEPTH			0x150
 #define MDSS_MDP_REG_DSPP_HIST_CTL_BASE			0x210
 #define MDSS_MDP_REG_DSPP_HIST_LUT_BASE			0x230
 #define MDSS_MDP_REG_DSPP_PA_BASE			0x238
+#define MDSS_MDP_REG_DSPP_SIX_ZONE_BASE			0x248
 #define MDSS_MDP_REG_DSPP_GAMUT_BASE			0x2DC
 #define MDSS_MDP_REG_DSPP_GC_BASE			0x2B0
 
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
index bd1c3eb..f8c59d7 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
@@ -62,6 +62,7 @@
 
 	atomic_t vsync_ref;
 	spinlock_t vsync_lock;
+	struct mutex vsync_mtx;
 	struct list_head vsync_handlers;
 };
 
@@ -216,19 +217,23 @@
 {
 	struct mdss_mdp_video_ctx *ctx = ctl->priv_data;
 
+	mutex_lock(&ctx->vsync_mtx);
 	if (atomic_inc_return(&ctx->vsync_ref) == 1)
 		mdss_mdp_irq_enable(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num);
 	else if (clear)
 		mdss_mdp_irq_clear(ctl->mdata, MDSS_MDP_IRQ_INTF_VSYNC,
 				ctl->intf_num);
+	mutex_unlock(&ctx->vsync_mtx);
 }
 
 static inline void video_vsync_irq_disable(struct mdss_mdp_ctl *ctl)
 {
 	struct mdss_mdp_video_ctx *ctx = ctl->priv_data;
 
+	mutex_lock(&ctx->vsync_mtx);
 	if (atomic_dec_return(&ctx->vsync_ref) == 0)
 		mdss_mdp_irq_disable(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num);
+	mutex_unlock(&ctx->vsync_mtx);
 }
 
 static int mdss_mdp_video_add_vsync_handler(struct mdss_mdp_ctl *ctl,
@@ -684,6 +689,7 @@
 	ctx->intf_type = ctl->intf_type;
 	init_completion(&ctx->vsync_comp);
 	spin_lock_init(&ctx->vsync_lock);
+	mutex_init(&ctx->vsync_mtx);
 	atomic_set(&ctx->vsync_ref, 0);
 
 	mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num,
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 14b486a..572af1c 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -34,6 +34,8 @@
 #include "mdss_mdp.h"
 #include "mdss_mdp_rotator.h"
 
+#include "splash.h"
+
 #define VSYNC_PERIOD 16
 #define BORDERFILL_NDX	0x0BF000BF
 #define CHECK_BOUNDS(offset, size, max_size) \
@@ -44,6 +46,8 @@
 
 #define MEM_PROTECT_SD_CTRL 0xF
 
+#define INVALID_PIPE_INDEX 0xFFFF
+
 struct sd_ctrl_req {
 	unsigned int enable;
 } __attribute__ ((__packed__));
@@ -859,7 +863,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);
 
@@ -1375,18 +1379,18 @@
 
 static int mdss_mdp_overlay_get_fb_pipe(struct msm_fb_data_type *mfd,
 					struct mdss_mdp_pipe **ppipe,
-					int mixer_mux)
+					int mixer_mux,
+					struct mdp_overlay *req_ov)
 {
 	struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
 	struct mdss_mdp_pipe *pipe;
+	int ret;
 
 	pipe = mdss_mdp_mixer_stage_pipe(mdp5_data->ctl, mixer_mux,
 					 MDSS_MDP_STAGE_BASE);
+
 	if (pipe == NULL) {
-		struct mdp_overlay req;
-		struct fb_info *fbi = mfd->fbi;
 		struct mdss_mdp_mixer *mixer;
-		int ret, bpp;
 
 		mixer = mdss_mdp_mixer_get(mdp5_data->ctl,
 					MDSS_MDP_MIXER_MUX_LEFT);
@@ -1395,49 +1399,73 @@
 			return -ENODEV;
 		}
 
-		memset(&req, 0, sizeof(req));
+		if (req_ov == NULL) {
+			struct mdp_overlay req;
+			struct fb_info *fbi = mfd->fbi;
+			int bpp;
 
-		bpp = fbi->var.bits_per_pixel / 8;
-		req.id = MSMFB_NEW_REQUEST;
-		req.src.format = mfd->fb_imgType;
-		req.src.height = fbi->var.yres;
-		req.src.width = fbi->fix.line_length / bpp;
-		if (mixer_mux == MDSS_MDP_MIXER_MUX_RIGHT) {
-			if (req.src.width <= mixer->width) {
-				pr_warn("right fb pipe not needed\n");
-				return -EINVAL;
+			memset(&req, 0, sizeof(req));
+
+			bpp = fbi->var.bits_per_pixel / 8;
+			req.id = MSMFB_NEW_REQUEST;
+			req.src.format = mfd->fb_imgType;
+			req.src.height = fbi->var.yres;
+			req.src.width = fbi->fix.line_length / bpp;
+			if (mixer_mux == MDSS_MDP_MIXER_MUX_RIGHT) {
+				if (req.src.width <= mixer->width) {
+					pr_warn("right fb pipe not needed\n");
+					return -EINVAL;
+				}
+
+				req.flags |= MDSS_MDP_RIGHT_MIXER;
+				req.src_rect.x = mixer->width;
+				req.src_rect.w = fbi->var.xres - mixer->width;
+			} else {
+				req.src_rect.x = 0;
+				req.src_rect.w = MIN(fbi->var.xres,
+								mixer->width);
 			}
 
-			req.flags |= MDSS_MDP_RIGHT_MIXER;
-			req.src_rect.x = mixer->width;
-			req.src_rect.w = fbi->var.xres - mixer->width;
+			req.src_rect.y = 0;
+			req.src_rect.h = req.src.height;
+			req.dst_rect.x = 0;
+			req.dst_rect.y = 0;
+			req.dst_rect.w = req.src_rect.w;
+			req.dst_rect.h = req.src_rect.h;
+			req.z_order = MDSS_MDP_STAGE_BASE;
+
+			pr_debug("allocating base pipe mux=%d\n", mixer_mux);
+
+			ret = mdss_mdp_overlay_pipe_setup(mfd, &req, &pipe);
+			if (ret)
+				return ret;
 		} else {
-			req.src_rect.x = 0;
-			req.src_rect.w = MIN(fbi->var.xres, mixer->width);
+			if (mixer_mux == MDSS_MDP_MIXER_MUX_RIGHT) {
+				req_ov->id = MSMFB_NEW_REQUEST;
+				req_ov->flags |= MDSS_MDP_RIGHT_MIXER;
+				req_ov->src_rect.w = MIN(mixer->width,
+						req_ov->src_rect.w >> 1);
+				req_ov->dst_rect.w = req_ov->src_rect.w;
+				req_ov->src_rect.x = req_ov->src_rect.w;
+				req_ov->dst_rect.x = 0;
+			}
+
+			ret = mdss_mdp_overlay_pipe_setup(mfd, req_ov, &pipe);
+			if (ret)
+				return ret;
 		}
-
-		req.src_rect.y = 0;
-		req.src_rect.h = req.src.height;
-		req.dst_rect.x = 0;
-		req.dst_rect.y = 0;
-		req.dst_rect.w = req.src_rect.w;
-		req.dst_rect.h = req.src_rect.h;
-		req.z_order = MDSS_MDP_STAGE_BASE;
-
-		pr_debug("allocating base pipe mux=%d\n", mixer_mux);
-
-		ret = mdss_mdp_overlay_pipe_setup(mfd, &req, &pipe);
-		if (ret)
-			return ret;
-
-		pr_debug("ctl=%d pnum=%d\n", mdp5_data->ctl->num, pipe->num);
 	}
 
+	pr_debug("ctl=%d pnum=%d\n", mdp5_data->ctl->num, pipe->num);
+
 	*ppipe = pipe;
 	return 0;
 }
 
-static void mdss_mdp_overlay_pan_display(struct msm_fb_data_type *mfd)
+static void mdss_mdp_overlay_pan_display(struct msm_fb_data_type *mfd,
+					struct mdp_overlay *req,
+					int image_size,
+					int *pipe_ndx)
 {
 	struct mdss_mdp_data *buf;
 	struct mdss_mdp_pipe *pipe;
@@ -1485,8 +1513,8 @@
 		goto pan_display_error;
 	}
 
-
-	ret = mdss_mdp_overlay_get_fb_pipe(mfd, &pipe, MDSS_MDP_MIXER_MUX_LEFT);
+	ret = mdss_mdp_overlay_get_fb_pipe(mfd, &pipe,
+					MDSS_MDP_MIXER_MUX_LEFT, req);
 	if (ret) {
 		pr_err("unable to allocate base pipe\n");
 		goto pan_display_error;
@@ -1496,12 +1524,14 @@
 		pr_err("unable to map base pipe\n");
 		goto pan_display_error;
 	}
+	if (pipe_ndx)
+		pipe_ndx[0] = pipe->ndx;
 
 	buf = &pipe->back_buf;
 	if (is_mdss_iommu_attached()) {
 		if (!mfd->iova) {
 			pr_err("mfd iova is zero\n");
-			goto pan_display_error;
+			goto attach_err;
 		}
 		buf->p[0].addr = mfd->iova;
 	} else {
@@ -1509,22 +1539,28 @@
 	}
 
 	buf->p[0].addr += offset;
-	buf->p[0].len = fbi->fix.smem_len - offset;
+	if (image_size)
+		buf->p[0].len = image_size;
+	else
+		buf->p[0].len = fbi->fix.smem_len - offset;
 	buf->num_planes = 1;
 	pipe->has_buf = 1;
 	mdss_mdp_pipe_unmap(pipe);
 
 	if (fbi->var.xres > MAX_MIXER_WIDTH || mfd->split_display) {
 		ret = mdss_mdp_overlay_get_fb_pipe(mfd, &pipe,
-						   MDSS_MDP_MIXER_MUX_RIGHT);
+					   MDSS_MDP_MIXER_MUX_RIGHT, req);
 		if (ret) {
 			pr_err("unable to allocate right base pipe\n");
-			goto pan_display_error;
+			goto attach_err;
 		}
 		if (mdss_mdp_pipe_map(pipe)) {
 			pr_err("unable to map right base pipe\n");
-			goto pan_display_error;
+			goto attach_err;
 		}
+		if (pipe_ndx)
+			pipe_ndx[1] = pipe->ndx;
+
 		pipe->back_buf = *buf;
 		pipe->has_buf = 1;
 		mdss_mdp_pipe_unmap(pipe);
@@ -1537,6 +1573,12 @@
 
 	return;
 
+attach_err:
+	mutex_unlock(&mdp5_data->ov_lock);
+	mdss_mdp_overlay_unset(mfd, pipe->ndx);
+	if (pipe_ndx)
+		pipe_ndx[0] = INVALID_PIPE_INDEX;
+	return;
 pan_display_error:
 	mutex_unlock(&mdp5_data->ov_lock);
 }
@@ -1580,8 +1622,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 +1740,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 +2579,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);
@@ -2596,6 +2646,63 @@
 	return rc;
 }
 
+static int mdss_mdp_overlay_splash_image(struct msm_fb_data_type *mfd,
+						int *pipe_ndx, int splash_event)
+{
+	struct mdp_overlay req;
+	int rc = 0;
+	struct fb_info *fbi = NULL;
+	int image_len = 0;
+
+	if (!mfd || !mfd->fbi || !mfd->fbi->screen_base || !pipe_ndx) {
+		pr_err("Invalid input parameter\n");
+		return -EINVAL;
+	}
+
+	fbi = mfd->fbi;
+	image_len = SPLASH_IMAGE_WIDTH * SPLASH_IMAGE_HEIGHT * SPLASH_IMAGE_BPP;
+
+	if (SPLASH_IMAGE_WIDTH > fbi->var.xres ||
+			SPLASH_IMAGE_HEIGHT > fbi->var.yres ||
+			SPLASH_IMAGE_BPP > fbi->var.bits_per_pixel / 8 ||
+			image_len > fbi->fix.smem_len) {
+		pr_err("Invalid splash parameter configuration\n");
+		return -EINVAL;
+	}
+
+	if (splash_event == MDP_CREATE_SPLASH_OV) {
+		pipe_ndx[0] = INVALID_PIPE_INDEX;
+		pipe_ndx[1] = INVALID_PIPE_INDEX;
+
+		memset(&req, 0, sizeof(struct mdp_overlay));
+		req.src.width = req.dst_rect.w = req.src_rect.w =
+				SPLASH_IMAGE_WIDTH;
+		req.src.height = req.dst_rect.h = req.src_rect.h =
+				SPLASH_IMAGE_HEIGHT;
+		req.src.format = SPLASH_IMAGE_FORMAT;
+		req.id = MSMFB_NEW_REQUEST;
+		req.z_order = MDSS_MDP_STAGE_0;
+		req.is_fg = 1;
+		req.alpha = 0xff;
+		req.transp_mask = MDP_TRANSP_NOP;
+		req.dst_rect.x =
+			(fbi->var.xres >> 1) - (SPLASH_IMAGE_WIDTH >> 1);
+		req.dst_rect.y =
+			(fbi->var.yres >> 1) - (SPLASH_IMAGE_HEIGHT >> 1);
+
+		memcpy(fbi->screen_base, splash_bgr888_image, image_len);
+		mdss_mdp_overlay_pan_display(mfd, &req, image_len, pipe_ndx);
+
+	} else if (splash_event == MDP_REMOVE_SPLASH_OV) {
+		if (pipe_ndx[0] != INVALID_PIPE_INDEX)
+			mdss_mdp_overlay_unset(mfd, pipe_ndx[0]);
+		if (pipe_ndx[1] != INVALID_PIPE_INDEX)
+			mdss_mdp_overlay_unset(mfd, pipe_ndx[1]);
+	}
+
+	return rc;
+}
+
 int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd)
 {
 	struct device *dev = mfd->fbi->dev;
@@ -2613,6 +2720,7 @@
 	mdp5_interface->panel_register_done = mdss_panel_register_done;
 	mdp5_interface->kickoff_fnc = mdss_mdp_overlay_kickoff;
 	mdp5_interface->get_sync_fnc = mdss_mdp_rotator_sync_pt_get;
+	mdp5_interface->splash_fnc = mdss_mdp_overlay_splash_image;
 
 	mdp5_data = kmalloc(sizeof(struct mdss_overlay_private), GFP_KERNEL);
 	if (!mdp5_data) {
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index 0dc61d0..e99fa49 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -173,6 +173,15 @@
 	GAMUT_T2_SIZE + GAMUT_T3_SIZE + GAMUT_T4_SIZE + \
 	GAMUT_T5_SIZE + GAMUT_T6_SIZE + GAMUT_T7_SIZE)
 
+#define MDSS_MDP_PA_SIZE		0xC
+#define MDSS_MDP_SIX_ZONE_SIZE		0xC
+#define MDSS_MDP_MEM_COL_SIZE		0x3C
+#define MDSS_MDP_GC_SIZE		0x28
+#define MDSS_MDP_PCC_SIZE		0xB8
+#define MDSS_MDP_GAMUT_SIZE		0x5C
+#define MDSS_MDP_IGC_DSPP_COLORS	0x3
+#define TOTAL_BLEND_STAGES		0x4
+
 #define PP_FLAGS_DIRTY_PA	0x1
 #define PP_FLAGS_DIRTY_PCC	0x2
 #define PP_FLAGS_DIRTY_IGC	0x4
@@ -205,6 +214,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
@@ -282,8 +295,8 @@
 	u32 enhist_lut[MDSS_BLOCK_DISP_NUM][ENHIST_LUT_ENTRIES];
 	struct mdp_pa_cfg pa_disp_cfg[MDSS_BLOCK_DISP_NUM];
 	struct mdp_pa_v2_data pa_v2_disp_cfg[MDSS_BLOCK_DISP_NUM];
-	u32 six_zone_lut_curve_p0[MDSS_BLOCK_DISP_NUM][SIX_ZONE_LUT_ENTRIES];
-	u32 six_zone_lut_curve_p1[MDSS_BLOCK_DISP_NUM][SIX_ZONE_LUT_ENTRIES];
+	u32 six_zone_lut_curve_p0[MDSS_BLOCK_DISP_NUM][MDP_SIX_ZONE_LUT_SIZE];
+	u32 six_zone_lut_curve_p1[MDSS_BLOCK_DISP_NUM][MDP_SIX_ZONE_LUT_SIZE];
 	struct mdp_pcc_cfg_data pcc_disp_cfg[MDSS_BLOCK_DISP_NUM];
 	struct mdp_igc_lut_data igc_disp_cfg[MDSS_BLOCK_DISP_NUM];
 	struct mdp_pgc_lut_data argc_disp_cfg[MDSS_BLOCK_DISP_NUM];
@@ -293,15 +306,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 +353,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 +389,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 +529,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,
@@ -626,7 +645,7 @@
 				data, addr);
 
 		/* Remove Index Update */
-		for (i = 1; i < SIX_ZONE_LUT_ENTRIES; i++) {
+		for (i = 1; i < MDP_SIX_ZONE_LUT_SIZE; i++) {
 			addr += 4;
 			writel_relaxed(pa_v2_config->six_zone_curve_p1[i],
 					addr);
@@ -679,6 +698,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 +713,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 +741,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);
 	}
 }
 
@@ -1069,7 +1091,7 @@
 
 		/*program pixel extn values for the SSPP*/
 		mdss_mdp_pipe_program_pixel_extn(pipe);
-	} else {
+	} else if (pipe->type == MDSS_MDP_PIPE_TYPE_VIG) {
 		writel_relaxed(phasex_step, pipe->base +
 		   MDSS_MDP_REG_SCALE_PHASE_STEP_X);
 		writel_relaxed(phasey_step, pipe->base +
@@ -1078,6 +1100,11 @@
 			MDSS_MDP_REG_SCALE_INIT_PHASE_X);
 		writel_relaxed(init_phasey, pipe->base +
 			MDSS_MDP_REG_SCALE_INIT_PHASE_Y);
+	} else {
+		writel_relaxed(phasex_step, pipe->base +
+		   MDSS_MDP_REG_SCALE_PHASE_STEP_X);
+		writel_relaxed(phasey_step, pipe->base +
+		   MDSS_MDP_REG_SCALE_PHASE_STEP_Y);
 	}
 
 	writel_relaxed(scale_config, pipe->base +
@@ -1282,10 +1309,7 @@
 		mutex_lock(&hist_info->hist_mutex);
 		spin_lock_irqsave(&hist_info->hist_lock, flag);
 		col_state = hist_info->col_state;
-		if (hist_info->is_kick_ready &&
-			((col_state == HIST_IDLE) ||
-			((false == hist_info->read_request) &&
-				col_state == HIST_READY))) {
+		if (col_state == HIST_IDLE) {
 			/* Kick off collection */
 			writel_relaxed(1, base + kick_base);
 			hist_info->col_state = HIST_START;
@@ -1324,12 +1348,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 +1389,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 +1400,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,8 +1513,12 @@
 			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);
 	}
 
+	pp_dspp_opmode_config(ctl, dspp_num, pp_sts, mdata->mdp_rev, &opmode);
+
+flush_exit:
 	if (ad_hw) {
 		mutex_lock(&ad->lock);
 		ad_flags = ad->reg_sts;
@@ -1492,13 +1528,11 @@
 			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);
-flush_exit:
 	writel_relaxed(opmode, base + MDSS_MDP_REG_DSPP_OP_MODE);
 	ctl->flush_bits |= BIT(13 + dspp_num);
 	wmb();
@@ -1705,11 +1739,13 @@
 		if (mdss_pp_res == NULL) {
 			pr_err("%s mdss_pp_res allocation failed!", __func__);
 			ret = -ENOMEM;
-		}
-
-		for (i = 0; i < MDSS_MDP_MAX_DSPP; i++) {
-			mutex_init(&mdss_pp_res->dspp_hist[i].hist_mutex);
-			spin_lock_init(&mdss_pp_res->dspp_hist[i].hist_lock);
+		} else {
+			for (i = 0; i < MDSS_MDP_MAX_DSPP; i++) {
+				mutex_init(
+					&mdss_pp_res->dspp_hist[i].hist_mutex);
+				spin_lock_init(
+					&mdss_pp_res->dspp_hist[i].hist_lock);
+			}
 		}
 	}
 	if (mdata) {
@@ -1836,6 +1872,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;
 
@@ -1903,10 +1945,13 @@
 
 	/* Six zone LUT and thresh data */
 	if (pa_v2_config->flags & MDP_PP_PA_SIX_ZONE_ENABLE) {
+		if (pa_v2_config->six_zone_len != MDP_SIX_ZONE_LUT_SIZE)
+			return -EINVAL;
+
 		data = (3 << 25);
 		writel_relaxed(data, addr);
 
-		for (i = 0; i < SIX_ZONE_LUT_ENTRIES; i++) {
+		for (i = 0; i < MDP_SIX_ZONE_LUT_SIZE; i++) {
 			addr += 4;
 			mdss_pp_res->six_zone_lut_curve_p1[disp_num][i] =
 				readl_relaxed(addr);
@@ -1917,13 +1962,13 @@
 
 		if (copy_to_user(pa_v2_config->six_zone_curve_p0,
 			&mdss_pp_res->six_zone_lut_curve_p0[disp_num][0],
-			SIX_ZONE_LUT_ENTRIES * sizeof(u32))) {
+			pa_v2_config->six_zone_len * sizeof(u32))) {
 			return -EFAULT;
 		}
 
 		if (copy_to_user(pa_v2_config->six_zone_curve_p1,
 			&mdss_pp_res->six_zone_lut_curve_p1[disp_num][0],
-			SIX_ZONE_LUT_ENTRIES * sizeof(u32))) {
+			pa_v2_config->six_zone_len * sizeof(u32))) {
 			return -EFAULT;
 		}
 
@@ -1968,14 +2013,17 @@
 static int pp_copy_pa_six_zone_lut(struct mdp_pa_v2_cfg_data *pa_v2_config,
 				u32 disp_num)
 {
+	if (pa_v2_config->pa_v2_data.six_zone_len != MDP_SIX_ZONE_LUT_SIZE)
+		return -EINVAL;
+
 	if (copy_from_user(&mdss_pp_res->six_zone_lut_curve_p0[disp_num][0],
 			pa_v2_config->pa_v2_data.six_zone_curve_p0,
-			SIX_ZONE_LUT_ENTRIES * sizeof(u32))) {
+			pa_v2_config->pa_v2_data.six_zone_len * sizeof(u32))) {
 		return -EFAULT;
 	}
 	if (copy_from_user(&mdss_pp_res->six_zone_lut_curve_p1[disp_num][0],
 			pa_v2_config->pa_v2_data.six_zone_curve_p1,
-			SIX_ZONE_LUT_ENTRIES * sizeof(u32))) {
+			pa_v2_config->pa_v2_data.six_zone_len * sizeof(u32))) {
 		return -EFAULT;
 	}
 
@@ -2119,6 +2167,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 +2291,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 +2495,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 +2671,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 +2725,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 +2846,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 */
@@ -2811,11 +2892,10 @@
 	hist_info->hist_cnt_sent = 0;
 	hist_info->hist_cnt_time = 0;
 	spin_lock_irqsave(&hist_info->hist_lock, flag);
-	hist_info->read_request = false;
+	hist_info->read_request = 0;
 	hist_info->col_state = HIST_RESET;
 	hist_info->col_en = true;
 	spin_unlock_irqrestore(&hist_info->hist_lock, flag);
-	hist_info->is_kick_ready = true;
 	mdss_mdp_hist_intr_req(&mdata->hist_intr, 3 << shift_bit, true);
 	writel_relaxed(req->frame_cnt, ctl_base + 8);
 	/* Kick out reset start */
@@ -2936,7 +3016,6 @@
 	hist_info->col_en = false;
 	hist_info->col_state = HIST_UNKNOWN;
 	spin_unlock_irqrestore(&hist_info->hist_lock, flag);
-	hist_info->is_kick_ready = false;
 	mdss_mdp_hist_intr_req(&mdata->hist_intr, done_bit, false);
 	writel_relaxed(BIT(1), ctl_base);/* cancel */
 	ret = 0;
@@ -3168,10 +3247,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;
@@ -3186,7 +3265,6 @@
 	spin_lock_irqsave(&hist_info->hist_lock, flag);
 	/* wait for hist done if cache has no data */
 	if (hist_info->col_state != HIST_READY) {
-		hist_info->read_request = true;
 		spin_unlock_irqrestore(&hist_info->hist_lock, flag);
 		timeout = HIST_WAIT_TIMEOUT(hist_info->frame_cnt);
 		mutex_unlock(&hist_info->hist_mutex);
@@ -3226,9 +3304,11 @@
 		}
 		if (hist_info->col_state != HIST_READY) {
 			ret = -ENODATA;
+			spin_lock_irqsave(&hist_info->hist_lock, flag);
+			hist_info->col_state = HIST_READY;
+			spin_unlock_irqrestore(&hist_info->hist_lock, flag);
 			pr_debug("%s: state is not ready: %d",
 					__func__, hist_info->col_state);
-			goto hist_collect_exit;
 		}
 	} else {
 		spin_unlock_irqrestore(&hist_info->hist_lock, flag);
@@ -3238,10 +3318,11 @@
 		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)
+			ret = -ENODATA;
 		hist_info->col_state = HIST_IDLE;
 	}
 	spin_unlock_irqrestore(&hist_info->hist_lock, flag);
@@ -3252,8 +3333,9 @@
 
 int mdss_mdp_hist_collect(struct mdp_histogram_data *hist)
 {
-	int i, j, off, ret = 0;
+	int i, j, off, ret = 0, temp_ret = 0;
 	struct pp_hist_col_info *hist_info;
+	struct pp_hist_col_info *hists[MDSS_MDP_INTF_MAX_LAYERMIXER];
 	u32 dspp_num, disp_num;
 	char __iomem *ctl_base;
 	u32 hist_cnt, mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];
@@ -3261,8 +3343,10 @@
 	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();
+	unsigned long flag;
 
 	if ((PP_BLOCK(hist->block) < MDP_LOGICAL_BLOCK_DISP_0) ||
 		(PP_BLOCK(hist->block) >= MDP_BLOCK_MAX))
@@ -3283,17 +3367,41 @@
 		ret = -EPERM;
 		goto hist_collect_exit;
 	}
+
 	if (PP_LOCAT(hist->block) == MDSS_PP_DSPP_CFG) {
-		hist_info = &mdss_pp_res->dspp_hist[disp_num];
 		for (i = 0; i < hist_cnt; i++) {
 			dspp_num = mixer_id[i];
-			hist_info = &mdss_pp_res->dspp_hist[dspp_num];
+			hists[i] = &mdss_pp_res->dspp_hist[dspp_num];
+		}
+		for (i = 0; i < hist_cnt; i++) {
+			spin_lock_irqsave(&hists[i]->hist_lock, flag);
+			/* mark that collect is ready to handle completions */
+			hists[i]->read_request = 1;
+			spin_unlock_irqrestore(&hists[i]->hist_lock, flag);
+		}
+		for (i = 0; i < hist_cnt; i++) {
+			dspp_num = mixer_id[i];
 			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);
 			if (ret)
-				goto hist_collect_exit;
+				temp_ret = ret;
+			ret = pp_hist_collect(hist, hists[i], ctl_base,
+								exp_sum);
 		}
+		for (i = 0; i < hist_cnt; i++) {
+			/* reset read requests and re-intialize completions */
+			spin_lock_irqsave(&hists[i]->hist_lock, flag);
+			hists[i]->read_request = 0;
+			INIT_COMPLETION(hists[i]->comp);
+			spin_unlock_irqrestore(&hists[i]->hist_lock, flag);
+		}
+		if (ret || temp_ret) {
+			ret = ret ? ret : temp_ret;
+			goto hist_collect_exit;
+		}
+
 		if (hist->bin_cnt != HIST_V_SIZE) {
 			pr_err("User not expecting size %d output",
 							HIST_V_SIZE);
@@ -3309,19 +3417,19 @@
 			}
 			memset(hist_concat, 0, HIST_V_SIZE * sizeof(u32));
 			for (i = 0; i < hist_cnt; i++) {
-				dspp_num = mixer_id[i];
-				hist_info = &mdss_pp_res->dspp_hist[dspp_num];
-				mutex_lock(&hist_info->hist_mutex);
+				mutex_lock(&hists[i]->hist_mutex);
 				for (j = 0; j < HIST_V_SIZE; j++)
-					hist_concat[j] += hist_info->data[j];
-				mutex_unlock(&hist_info->hist_mutex);
+					hist_concat[j] += hists[i]->data[j];
+				mutex_unlock(&hists[i]->hist_mutex);
 			}
 			hist_data_addr = hist_concat;
 		} else {
-			hist_data_addr = hist_info->data;
+			hist_data_addr = hists[0]->data;
 		}
-		hist_info = &mdss_pp_res->dspp_hist[disp_num];
-		hist_info->hist_cnt_sent++;
+
+		for (i = 0; i < hist_cnt; i++)
+			hists[i]->hist_cnt_sent++;
+
 	} else if (PP_LOCAT(hist->block) == MDSS_PP_SSPP_CFG) {
 
 		hist_cnt = MDSS_PP_ARG_MASK & hist->block;
@@ -3357,13 +3465,50 @@
 				continue;
 			}
 			hist_info = &pipe->pp_res.hist;
+			spin_lock_irqsave(&hist_info->hist_lock, flag);
+			hist_info->read_request = 1;
+			spin_unlock_irqrestore(&hist_info->hist_lock, flag);
+		}
+		for (i = pipe_num; i < MDSS_PP_ARG_NUM; i++) {
+			if (!PP_ARG(i, hist->block))
+				continue;
+			pipe_cnt++;
+			pipe = mdss_mdp_pipe_get(mdata, BIT(i));
+			if (IS_ERR_OR_NULL(pipe) ||
+					pipe->num > MDSS_MDP_SSPP_VIG2) {
+				pr_warn("Invalid Hist pipe (%d)", i);
+				continue;
+			}
+			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);
-			mdss_mdp_pipe_unmap(pipe);
 			if (ret)
-				goto hist_collect_exit;
+				temp_ret = ret;
+			ret = pp_hist_collect(hist, hist_info, ctl_base,
+								exp_sum);
+			mdss_mdp_pipe_unmap(pipe);
 		}
+		for (i = pipe_num; i < MDSS_PP_ARG_NUM; i++) {
+			if (!PP_ARG(i, hist->block))
+				continue;
+			pipe_cnt++;
+			pipe = mdss_mdp_pipe_get(mdata, BIT(i));
+			if (IS_ERR_OR_NULL(pipe) ||
+					pipe->num > MDSS_MDP_SSPP_VIG2) {
+				pr_warn("Invalid Hist pipe (%d)", i);
+				continue;
+			}
+			hist_info = &pipe->pp_res.hist;
+			spin_lock_irqsave(&hist_info->hist_lock, flag);
+			hist_info->read_request = 0;
+			INIT_COMPLETION(hist_info->comp);
+			spin_unlock_irqrestore(&hist_info->hist_lock, flag);
+		}
+		if (ret || temp_ret) {
+			ret = ret ? ret : temp_ret;
+			goto hist_collect_exit;
+		}
+
 		if (pipe_cnt != 0 &&
 			(hist->bin_cnt != (HIST_V_SIZE * pipe_cnt))) {
 			pr_err("User not expecting size %d output",
@@ -3461,8 +3606,10 @@
 			spin_lock(&hist_info->hist_lock);
 			hist_info->col_state = HIST_READY;
 			spin_unlock(&hist_info->hist_lock);
-			if (hist_info->read_request)
+			if (hist_info->read_request == 1) {
 				complete(&hist_info->comp);
+				hist_info->read_request++;
+			}
 		}
 		/* Histogram Reset Done Interrupt */
 		if ((isr_blk & 0x2) &&
@@ -3490,6 +3637,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];
@@ -3583,10 +3777,9 @@
 			struct mdss_ad_init_cfg *init_cfg)
 {
 	struct mdss_ad_info *ad;
-	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 +3792,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,
@@ -3606,10 +3804,12 @@
 		if (init_cfg->params.init.bl_lin_len == AD_BL_LIN_LEN) {
 			lin_ret = copy_from_user(&ad->bl_lin,
 				init_cfg->params.init.bl_lin,
-				AD_BL_LIN_LEN * sizeof(uint32_t));
+				init_cfg->params.init.bl_lin_len *
+				sizeof(uint32_t));
 			inv_ret = copy_from_user(&ad->bl_lin_inv,
 				init_cfg->params.init.bl_lin_inv,
-				AD_BL_LIN_LEN * sizeof(uint32_t));
+				init_cfg->params.init.bl_lin_len *
+				sizeof(uint32_t));
 			if (lin_ret || inv_ret)
 				ret = -ENOMEM;
 			ratio_temp =  mfd->panel_info->bl_max / AD_BL_LIN_LEN;
@@ -3618,13 +3818,14 @@
 				shift++;
 			}
 			ad->bl_bright_shift = shift;
-		} else if (init_cfg->params.init.bl_lin_len) {
+		} else {
 			ret = -EINVAL;
 		}
-		if (!lin_ret && !inv_ret)
+		if (ret) {
+			ad->state &= ~PP_AD_STATE_BL_LIN;
+			goto ad_config_exit;
+		} else
 			ad->state |= PP_AD_STATE_BL_LIN;
-		else
-			ad->state &= !PP_AD_STATE_BL_LIN;
 
 		ad->sts |= PP_AD_STS_DIRTY_INIT;
 	} else if (init_cfg->ops & MDP_PP_AD_CFG) {
@@ -3638,6 +3839,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);
@@ -3650,8 +3867,8 @@
 		ad->mfd = mfd;
 		ad->bl_mfd = bl_mfd;
 	}
+ad_config_exit:
 	mutex_unlock(&ad->lock);
-	ctl = mfd_to_ctl(mfd);
 	return ret;
 }
 
@@ -3723,7 +3940,7 @@
 			mutex_unlock(&ad->lock);
 			mutex_lock(&mfd->bl_lock);
 			MDSS_BRIGHT_TO_BL(bl, bl, mfd->panel_info->bl_max,
-							MDSS_MAX_BL_BRIGHTNESS);
+					mfd->panel_info->brightness_max);
 			mdss_fb_set_backlight(mfd, bl);
 			mutex_unlock(&mfd->bl_lock);
 			mutex_lock(&ad->lock);
@@ -3792,8 +4009,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 +4022,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 +4048,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 +4063,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 +4097,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 +4167,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 +4192,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;
 }
 
@@ -4179,8 +4422,7 @@
 						MDSS_MDP_REG_AD_BL_OUT);
 				if (ad->state & PP_AD_STATE_BL_LIN) {
 					bl = bl >> ad->bl_bright_shift;
-					bl = min_t(u32, bl,
-						MDSS_MAX_BL_BRIGHTNESS);
+					bl = min_t(u32, bl, (AD_BL_LIN_LEN-1));
 					bl = ad->bl_lin_inv[bl];
 					bl = bl << ad->bl_bright_shift;
 				}
@@ -4258,6 +4500,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;
@@ -4270,71 +4513,298 @@
 	return rc;
 }
 
-static int is_valid_calib_addr(void *addr)
+static int is_valid_calib_ctrl_addr(char __iomem *ptr)
+{
+	char __iomem *base;
+	int ret = 0, counter = 0;
+	int stage = 0;
+	struct mdss_mdp_ctl *ctl;
+
+	/* Controller */
+	for (counter = 0; counter < mdss_res->nctl; counter++) {
+		ctl = mdss_res->ctl_off + counter;
+		base = ctl->base;
+
+		if (ptr == base + MDSS_MDP_REG_CTL_TOP) {
+			ret = MDP_PP_OPS_READ;
+			break;
+		} else if (ptr == base + MDSS_MDP_REG_CTL_FLUSH) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		}
+
+		for (stage = 0; stage < mdss_res->nmixers_intf; stage++)
+			if (ptr == base + MDSS_MDP_REG_CTL_LAYER(stage)) {
+				ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+				goto End;
+			}
+	}
+
+End:
+	return ret;
+}
+
+static int is_valid_calib_dspp_addr(char __iomem *ptr)
+{
+	char __iomem *base;
+	int ret = 0, counter = 0;
+	struct mdss_mdp_mixer *mixer;
+
+	for (counter = 0; counter < mdss_res->nmixers_intf; counter++) {
+		mixer = mdss_res->mixer_intf + counter;
+		base = mixer->dspp_base;
+
+		if (ptr == base) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		/* PA range */
+		} else if ((ptr >= base + MDSS_MDP_REG_DSPP_PA_BASE) &&
+				(ptr <= base + MDSS_MDP_REG_DSPP_PA_BASE +
+						MDSS_MDP_PA_SIZE)) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		/* PCC range */
+		} else if ((ptr >= base + MDSS_MDP_REG_DSPP_PCC_BASE) &&
+				(ptr <= base + MDSS_MDP_REG_DSPP_PCC_BASE +
+						MDSS_MDP_PCC_SIZE)) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		/* Gamut range */
+		} else if ((ptr >= base + MDSS_MDP_REG_DSPP_GAMUT_BASE) &&
+				(ptr <= base + MDSS_MDP_REG_DSPP_GAMUT_BASE +
+						MDSS_MDP_GAMUT_SIZE)) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		/* GC range */
+		} else if ((ptr >= base + MDSS_MDP_REG_DSPP_GC_BASE) &&
+				(ptr <= base + MDSS_MDP_REG_DSPP_GC_BASE +
+						MDSS_MDP_GC_SIZE)) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		/* Dither enable/disable */
+		} else if ((ptr == base + MDSS_MDP_REG_DSPP_DITHER_DEPTH)) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		/* Six zone and mem color */
+		} else if (mdss_res->mdp_rev >= MDSS_MDP_HW_REV_103 &&
+			(ptr >= base + MDSS_MDP_REG_DSPP_SIX_ZONE_BASE) &&
+			(ptr <= base + MDSS_MDP_REG_DSPP_SIX_ZONE_BASE +
+					MDSS_MDP_SIX_ZONE_SIZE +
+					MDSS_MDP_MEM_COL_SIZE)) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int is_valid_calib_vig_addr(char __iomem *ptr)
+{
+	char __iomem *base;
+	int ret = 0, counter = 0;
+	struct mdss_mdp_pipe *pipe;
+
+	for (counter = 0; counter < mdss_res->nvig_pipes; counter++) {
+		pipe = mdss_res->vig_pipes + counter;
+		base = pipe->base;
+
+		if (ptr == base + MDSS_MDP_REG_VIG_OP_MODE) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		} else if (ptr == base + MDSS_MDP_REG_SSPP_SRC_FORMAT) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		} else if (ptr == base + MDSS_MDP_REG_SSPP_SRC_CONSTANT_COLOR) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		} else if (ptr == base + MDSS_MDP_REG_SSPP_SRC_UNPACK_PATTERN) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		} else if (ptr == base + MDSS_MDP_REG_SSPP_SRC_OP_MODE) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		} else if ((ptr == base + MDSS_MDP_REG_VIG_QSEED2_SHARP)) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		/* PA range */
+		} else if ((ptr >= base + MDSS_MDP_REG_VIG_PA_BASE) &&
+				(ptr <= base + MDSS_MDP_REG_VIG_PA_BASE +
+						MDSS_MDP_PA_SIZE)) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		/* Mem color range */
+		} else if (mdss_res->mdp_rev >= MDSS_MDP_HW_REV_103 &&
+			(ptr >= base + MDSS_MDP_REG_VIG_MEM_COL_BASE) &&
+				(ptr <= base + MDSS_MDP_REG_VIG_MEM_COL_BASE +
+						MDSS_MDP_MEM_COL_SIZE)) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		/* IGC range */
+		} else if ((ptr >= base + MDSS_MDP_REG_IGC_VIG_BASE) &&
+				(ptr <= base + MDSS_MDP_REG_IGC_VIG_BASE +
+						MDSS_MDP_GC_SIZE)) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int is_valid_calib_rgb_addr(char __iomem *ptr)
+{
+	char __iomem *base;
+	int ret = 0, counter = 0;
+	struct mdss_mdp_pipe *pipe;
+
+	for (counter = 0; counter < mdss_res->nrgb_pipes; counter++) {
+		pipe = mdss_res->rgb_pipes + counter;
+		base = pipe->base;
+
+		if (ptr == base + MDSS_MDP_REG_SSPP_SRC_FORMAT) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		} else if (ptr == base + MDSS_MDP_REG_SSPP_SRC_CONSTANT_COLOR) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		} else if (ptr == base + MDSS_MDP_REG_SSPP_SRC_UNPACK_PATTERN) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		} else if (ptr == base + MDSS_MDP_REG_SSPP_SRC_OP_MODE) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		/* IGC range */
+		} else if ((ptr >= base + MDSS_MDP_REG_IGC_RGB_BASE) &&
+				(ptr <= base + MDSS_MDP_REG_IGC_RGB_BASE +
+						MDSS_MDP_GC_SIZE)) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int is_valid_calib_dma_addr(char __iomem *ptr)
+{
+	char __iomem *base;
+	int ret = 0, counter = 0;
+	struct mdss_mdp_pipe *pipe;
+
+	for (counter = 0; counter < mdss_res->ndma_pipes; counter++) {
+		pipe = mdss_res->dma_pipes + counter;
+		base = pipe->base;
+
+		if (ptr == base + MDSS_MDP_REG_SSPP_SRC_FORMAT) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		} else if (ptr == base + MDSS_MDP_REG_SSPP_SRC_CONSTANT_COLOR) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		} else if (ptr == base + MDSS_MDP_REG_SSPP_SRC_UNPACK_PATTERN) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		} else if (ptr == base + MDSS_MDP_REG_SSPP_SRC_OP_MODE) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		/* IGC range */
+		} else if ((ptr >= base + MDSS_MDP_REG_IGC_DMA_BASE) &&
+				(ptr <= base + MDSS_MDP_REG_IGC_DMA_BASE +
+						MDSS_MDP_GC_SIZE)) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int is_valid_calib_mixer_addr(char __iomem *ptr)
+{
+	char __iomem *base;
+	int ret = 0, counter = 0;
+	int stage = 0;
+	struct mdss_mdp_mixer *mixer;
+
+	for (counter = 0; counter < mdss_res->nmixers_intf; counter++) {
+		mixer = mdss_res->mixer_intf + counter;
+		base = mixer->base;
+
+		if (ptr == base + MDSS_MDP_REG_LM_OP_MODE) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		/* GC range */
+		} else if ((ptr >= base + MDSS_MDP_REG_LM_GC_LUT_BASE) &&
+			(ptr <= base + MDSS_MDP_REG_LM_GC_LUT_BASE +
+						MDSS_MDP_GC_SIZE)) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		}
+
+		for (stage = 0; stage < TOTAL_BLEND_STAGES; stage++)
+			if (ptr == base + MDSS_MDP_REG_LM_BLEND_OFFSET(stage) +
+						 MDSS_MDP_REG_LM_BLEND_OP) {
+				ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+				goto End;
+			} else if (ptr == base +
+					MDSS_MDP_REG_LM_BLEND_OFFSET(stage) +
+					MDSS_MDP_REG_LM_BLEND_FG_ALPHA) {
+				ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+				goto End;
+			} else if (ptr == base +
+					 MDSS_MDP_REG_LM_BLEND_OFFSET(stage) +
+					 MDSS_MDP_REG_LM_BLEND_BG_ALPHA) {
+				ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+				goto End;
+			}
+	}
+
+End:
+	return ret;
+}
+
+static int is_valid_calib_addr(void *addr, u32 operation)
 {
 	int ret = 0;
-	unsigned int ptr;
-	ptr = (unsigned int) addr;
-	/* if request is outside the MDP reg-map or is not aligned 4 */
-	if (ptr > 0x5138 || ptr % 0x4)
-		goto end;
-	if (ptr >= 0x100 && ptr <= 0x5138) {
-		/* if ptr is in dspp range */
-		if (ptr >= 0x4600 && ptr <= 0x5138) {
-			/* if ptr is in dspp0 range*/
-			if (ptr >= 0x4600 && ptr <= 0x4938)
-				ptr -= 0x4600;
-			/* if ptr is in dspp1 range */
-			else if (ptr >= 0x4a00 && ptr <= 0x4d38)
-				ptr -= 0x4a00;
-			/* if ptr is in dspp2 range */
-			else if (ptr >= 0x4e00 && ptr <= 0x5138)
-				ptr -= 0x4e00;
-			/* if ptr is in pcc plane rgb coeff.range */
-			if (ptr >= 0x30 && ptr <= 0xe8)
-				ret = 1;
-			/* if ptr is in ARLUT red range */
-			else if (ptr >= 0x2b0 && ptr <= 0x2b8)
-				ret = 1;
-			/* if ptr is in PA range */
-			else if (ptr >= 0x238 && ptr <= 0x244)
-				ret = 1;
-			 /* if ptr is in ARLUT green range */
-			else if (ptr >= 0x2c0 && ptr <= 0x2c8)
-				ret = 1;
-			/* if ptr is in ARLUT blue range or
-			    gamut map table range */
-			else if (ptr >= 0x2d0 && ptr <= 0x338)
-				ret = 1;
-			/* if ptr is dspp0,dspp1,dspp2 op mode
-						register */
-			else if (ptr == 0)
-				ret = 1;
-		} else if (ptr >= 0x600 && ptr <= 0x608)
-				ret = 1;
-		else if (ptr >= 0x400 && ptr <= 0x408)
-				ret = 1;
-		else if ((ptr == 0x1830) || (ptr == 0x1c30) ||
-				(ptr == 0x1430) || (ptr == 0x1e38))
-				ret = 1;
-		else if ((ptr == 0x1e3c) || (ptr == 0x1e30))
-				ret = 1;
-		else if (ptr >= 0x3220 && ptr <= 0x3228)
-				ret = 1;
-		else if (ptr == 0x3200 || ptr == 0x100)
-				ret = 1;
-		else if (ptr == 0x104 || ptr == 0x614 || ptr == 0x714 ||
-			ptr == 0x814 || ptr == 0x914 || ptr == 0xa14)
-				ret = 1;
-		else if (ptr == 0x618 || ptr == 0x718 || ptr == 0x818 ||
-				 ptr == 0x918 || ptr == 0xa18)
-				ret = 1;
-		else if (ptr == 0x2234 || ptr == 0x1e34 || ptr == 0x2634)
-				ret = 1;
-	} else if (ptr == 0x0)
-		ret = 1;
-end:
-	return ret;
+	char __iomem *ptr = addr;
+	char __iomem *mixer_base = mdss_res->mixer_intf->base;
+	char __iomem *rgb_base   = mdss_res->rgb_pipes->base;
+	char __iomem *dma_base   = mdss_res->dma_pipes->base;
+	char __iomem *vig_base   = mdss_res->vig_pipes->base;
+	char __iomem *ctl_base   = mdss_res->ctl_off->base;
+	char __iomem *dspp_base  = mdss_res->mixer_intf->dspp_base;
+
+	if ((unsigned int)addr % 4) {
+		ret = 0;
+	} else if (ptr == (mdss_res->mdp_base + MDSS_MDP_REG_HW_VERSION) ||
+	    ptr == (mdss_res->mdp_base + MDSS_MDP_REG_DISP_INTF_SEL)) {
+		ret = MDP_PP_OPS_READ;
+	} else if (ptr >= (mdss_res->mdp_base + MDSS_MDP_REG_IGC_DSPP_BASE) &&
+		    ptr < (mdss_res->mdp_base + MDSS_MDP_REG_IGC_DSPP_BASE +
+						MDSS_MDP_IGC_DSPP_COLORS)) {
+		ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+	} else if (ptr >= dspp_base && ptr < (dspp_base +
+		(mdss_res->nmixers_intf * MDSS_MDP_DSPP_ADDRESS_OFFSET))) {
+		ret = is_valid_calib_dspp_addr(ptr);
+	} else if (ptr >= ctl_base && ptr < (ctl_base + (mdss_res->nctl
+					* MDSS_MDP_CTL_ADDRESS_OFFSET))) {
+		ret = is_valid_calib_ctrl_addr(ptr);
+	} else if (ptr >= vig_base && ptr < (vig_base + (mdss_res->nvig_pipes
+					* MDSS_MDP_SSPP_ADDRESS_OFFSET))) {
+		ret = is_valid_calib_vig_addr(ptr);
+	} else if (ptr >= rgb_base && ptr < (rgb_base + (mdss_res->nrgb_pipes
+					* MDSS_MDP_SSPP_ADDRESS_OFFSET))) {
+		ret = is_valid_calib_rgb_addr(ptr);
+	} else if (ptr >= dma_base && ptr < (dma_base + (mdss_res->ndma_pipes
+					* MDSS_MDP_SSPP_ADDRESS_OFFSET))) {
+		ret = is_valid_calib_dma_addr(ptr);
+	} else if (ptr >= mixer_base && ptr < (mixer_base +
+		(mdss_res->nmixers_intf * MDSS_MDP_LM_ADDRESS_OFFSET))) {
+		ret = is_valid_calib_mixer_addr(ptr);
+	}
+
+	return ret & operation;
 }
 
 int mdss_mdp_calib_config(struct mdp_calib_config_data *cfg, u32 *copyback)
@@ -4342,11 +4812,12 @@
 	int ret = -1;
 	void *ptr = (void *) cfg->addr;
 
-	if (is_valid_calib_addr(ptr))
+	ptr = (void *)(((unsigned int) ptr) + (mdss_res->mdp_base));
+	if (is_valid_calib_addr(ptr, cfg->ops))
 		ret = 0;
 	else
 		return ret;
-	ptr = (void *)(((unsigned int) ptr) + (mdss_res->mdp_base));
+
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
 
 	if (cfg->ops & MDP_PP_OPS_READ) {
@@ -4381,65 +4852,50 @@
 	int i = 0;
 
 	if (!cfg) {
-		pr_err("Invalid buffer pointer");
+		pr_err("Invalid buffer pointer\n");
 		return ret;
 	}
 
-	if (cfg->size == 0 || cfg->size > PAGE_SIZE) {
-		pr_err("Invalid buffer size %d", cfg->size);
+	if (cfg->size == 0) {
+		pr_err("Invalid buffer size\n");
 		return ret;
 	}
 
 	counter = cfg->size / (sizeof(uint32_t) * 2);
 	buff_org = buff = kzalloc(cfg->size, GFP_KERNEL);
 	if (buff == NULL) {
-		pr_err("Allocation failed");
+		pr_err("Config buffer allocation failed\n");
 		return ret;
 	}
 
 	if (copy_from_user(buff, cfg->buffer, cfg->size)) {
 		kfree(buff);
-		pr_err("Copy failed");
+		pr_err("config buffer copy failed\n");
 		return ret;
 	}
 
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
 
-	if (cfg->ops & MDP_PP_OPS_READ) {
-		for (i = 0 ; i < counter ; i++) {
-			if (is_valid_calib_addr((void *) *buff)) {
-				ret = 0;
-			} else {
-				ret = -1;
-				pr_err("Address validation failed");
-				break;
-			}
+	for (i = 0; i < counter; i++) {
+		ptr = (void *) (((unsigned int) *buff) + mdss_res->mdp_base);
 
-			ptr = (void *)(((unsigned int) *buff) +
-					 (mdss_res->mdp_base));
-			buff++;
+		if (!is_valid_calib_addr(ptr, cfg->ops)) {
+			ret = -1;
+			pr_err("Address validation failed or access not permitted\n");
+			break;
+		}
+
+		buff++;
+		if (cfg->ops & MDP_PP_OPS_READ)
 			*buff = readl_relaxed(ptr);
-			buff++;
-		}
-		if (!ret)
-			ret = copy_to_user(cfg->buffer, buff_org, cfg->size);
-		*copyback = 1;
-	} else if (cfg->ops & MDP_PP_OPS_WRITE) {
-		for (i = 0 ; i < counter ; i++) {
-			if (is_valid_calib_addr((void *) *buff)) {
-				ret = 0;
-			} else {
-				ret = -1;
-				pr_err("Address validation failed");
-				break;
-			}
-
-			ptr = (void *)(((unsigned int) *buff) +
-					 (mdss_res->mdp_base));
-			buff++;
+		else if (cfg->ops & MDP_PP_OPS_WRITE)
 			writel_relaxed(*buff, ptr);
-			buff++;
-		}
+		buff++;
+	}
+
+	if (ret & MDP_PP_OPS_READ) {
+		ret = copy_to_user(cfg->buffer, buff_org, cfg->size);
+		*copyback = 1;
 	}
 
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
diff --git a/drivers/video/msm/mdss/mdss_mdp_rotator.c b/drivers/video/msm/mdss/mdss_mdp_rotator.c
index e2e41bb..883a728 100644
--- a/drivers/video/msm/mdss/mdss_mdp_rotator.c
+++ b/drivers/video/msm/mdss/mdss_mdp_rotator.c
@@ -202,7 +202,7 @@
 			   struct mdss_mdp_data *dst_data)
 {
 	struct mdss_mdp_pipe *rot_pipe = NULL;
-	struct mdss_mdp_ctl *ctl;
+	struct mdss_mdp_ctl *orig_ctl, *rot_ctl;
 	int ret;
 
 	if (!rot || !rot->ref_cnt)
@@ -218,20 +218,20 @@
 
 	pr_debug("queue rotator pnum=%d\n", rot_pipe->num);
 
-	ctl = rot_pipe->mixer->ctl;
-	if (ctl->shared_lock)
-		mutex_lock(ctl->shared_lock);
+	orig_ctl = rot_pipe->mixer->ctl;
+	if (orig_ctl->shared_lock)
+		mutex_lock(orig_ctl->shared_lock);
 
-	ctl = mdss_mdp_ctl_mixer_switch(ctl,
+	rot_ctl = mdss_mdp_ctl_mixer_switch(orig_ctl,
 			MDSS_MDP_WB_CTL_TYPE_BLOCK);
-	if (!ctl) {
+	if (!rot_ctl) {
 		ret = -EINVAL;
 		goto error;
 	} else {
-		rot->pipe->mixer = ctl->mixer_left;
+		rot->pipe->mixer = rot_ctl->mixer_left;
 	}
 
-	if (rot->params_changed || ctl->mdata->mixer_switched) {
+	if (rot->params_changed || rot_ctl->mdata->mixer_switched) {
 		rot->params_changed = 0;
 		rot_pipe->flags = rot->flags;
 		rot_pipe->src_fmt = mdss_mdp_get_format_params(rot->format);
@@ -257,12 +257,12 @@
 		goto error;
 	}
 
-	ret = mdss_mdp_rotator_kickoff(ctl, rot, dst_data);
+	ret = mdss_mdp_rotator_kickoff(rot_ctl, rot, dst_data);
 
 	return ret;
 error:
-	if (ctl->shared_lock)
-		mutex_unlock(ctl->shared_lock);
+	if (orig_ctl->shared_lock)
+		mutex_unlock(orig_ctl->shared_lock);
 	return ret;
 }
 
diff --git a/drivers/video/msm/mdss/mdss_panel.h b/drivers/video/msm/mdss/mdss_panel.h
index 65275db..a42ff1e 100644
--- a/drivers/video/msm/mdss/mdss_panel.h
+++ b/drivers/video/msm/mdss/mdss_panel.h
@@ -272,6 +272,7 @@
 	u32 type;
 	u32 wait_cycle;
 	u32 pdest;
+	u32 brightness_max;
 	u32 bl_max;
 	u32 bl_min;
 	u32 fb_num;
diff --git a/drivers/video/msm/mdss/splash.h b/drivers/video/msm/mdss/splash.h
new file mode 100644
index 0000000..dc8a473
--- /dev/null
+++ b/drivers/video/msm/mdss/splash.h
@@ -0,0 +1,5279 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __SPLASH_H_
+#define __SPLASH_H_
+
+#define SPLASH_IMAGE_WIDTH	113
+#define SPLASH_IMAGE_HEIGHT	124
+#define SPLASH_IMAGE_FORMAT	MDP_BGR_888
+#define SPLASH_IMAGE_BPP	3
+
+char splash_bgr888_image[] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10,
+	0x29, 0x19, 0x31, 0x31,
+	0x29, 0x31, 0x31, 0x29, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x08, 0x10, 0x31, 0x31,
+	0x29, 0x4a, 0x52, 0x4a, 0x6b, 0x5a, 0x73, 0x4a, 0x52, 0x4a, 0x10, 0x29,
+	0x19, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x08,
+	0x10, 0x31, 0x31, 0x29, 0x6b, 0x5a, 0x73, 0x6b, 0x7b, 0x73, 0x6b, 0x5a,
+	0x4a, 0x31, 0x31, 0x29,
+	0x3a, 0x10, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x08, 0x10, 0x10, 0x21, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x08, 0x10, 0x31, 0x31, 0x29, 0x6b, 0x5a, 0x4a, 0x6b, 0x5a,
+	0x73, 0x3a, 0x31, 0x4a,
+	0x31, 0x31, 0x29, 0x10, 0x29, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x31, 0x31, 0x29, 0x3a, 0x31,
+	0x4a, 0x31, 0x31, 0x29,
+	0x10, 0x29, 0x19, 0x08, 0x08, 0x10, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x10, 0x21, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x08, 0x08,
+	0x10, 0x08, 0x08, 0x10,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x08,
+	0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x21,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x10, 0x21, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x08, 0x10, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x21, 0x00, 0x08, 0x08, 0x10,
+	0x08, 0x08, 0x10, 0x10,
+	0x29, 0x19, 0x10, 0x29, 0x19, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x08,
+	0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0x10,
+	0x4a, 0x52, 0x4a, 0x08,
+	0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0x10,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0x10, 0x31, 0x31, 0x29, 0x08,
+	0x08, 0x10, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x10, 0x29, 0x19, 0x4a, 0x52, 0x4a, 0x3a, 0x31, 0x4a,
+	0x08, 0x00, 0x00, 0x08,
+	0x08, 0x10, 0x4a, 0x52, 0x4a, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x08, 0x10, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x4a,
+	0x52, 0x4a, 0x9c, 0xa5, 0x94, 0x9c, 0x7b, 0x94, 0x08, 0x08, 0x10, 0x08,
+	0x08, 0x10, 0x10, 0x29,
+	0x19, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+	0x10, 0x10, 0x21, 0x00,
+	0x08, 0x08, 0x10, 0x6b, 0x7b, 0x73, 0x9c, 0x7b, 0x94, 0x9c, 0xa5, 0x94,
+	0xce, 0xad, 0xad, 0xa5,
+	0xb5, 0xb5, 0x31, 0x31, 0x29, 0x08, 0x08, 0x10, 0x10, 0x29, 0x19, 0x08,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x4a,
+	0x52, 0x4a, 0xa5, 0x9c, 0xad, 0xce, 0xad, 0xad, 0xce, 0xde, 0xce, 0x9c,
+	0x7b, 0x94, 0x10, 0x29,
+	0x19, 0x3a, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x08, 0x10, 0x9c, 0x7b, 0x94, 0x9c, 0xa5, 0x94, 0xa5, 0xb5, 0xb5,
+	0xa5, 0xb5, 0xb5, 0xce,
+	0xde, 0xce, 0xc5, 0xad, 0xd6, 0x9c, 0xa5, 0x94, 0x3a, 0x10, 0x21, 0x00,
+	0x00, 0x00, 0x08, 0x08,
+	0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x08, 0x10, 0x9c, 0x7b, 0x94, 0xce, 0xad, 0xad, 0xce, 0xe6, 0xef, 0xce,
+	0xe6, 0xef, 0xe6, 0xde,
+	0xde, 0xa5, 0x9c, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x6b, 0x5a, 0x73, 0xce, 0xde, 0xce, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xce, 0xde, 0xce, 0x6b,
+	0x7b, 0x73, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x21, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x10, 0x29, 0x19, 0xef, 0xf7, 0xe6, 0xef, 0xf7, 0xff, 0x9c,
+	0xa5, 0x94, 0xce, 0xde,
+	0xce, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x10, 0x21, 0x00, 0xce, 0xde, 0xce, 0xff, 0xf7, 0xff,
+	0xff, 0xf7, 0xff, 0x9c,
+	0xa5, 0x94, 0x00, 0x00, 0x00, 0x31, 0x31, 0x29, 0xef, 0xf7, 0xe6, 0xff,
+	0xf7, 0xff, 0xef, 0xde,
+	0xef, 0x08, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x4a, 0x52, 0x4a, 0xff, 0xf7, 0xff, 0x10,
+	0x29, 0x19, 0x08, 0x08,
+	0x10, 0x4a, 0x52, 0x4a, 0xce, 0xad, 0xad, 0xff, 0xff, 0xff, 0x4a, 0x52,
+	0x4a, 0x08, 0x08, 0x10,
+	0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x08, 0x08, 0x10, 0xce, 0xad, 0xad,
+	0xef, 0xf7, 0xff, 0xce,
+	0xde, 0xce, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x9c, 0x7b, 0x94, 0x31,
+	0x31, 0x29, 0xef, 0xf7,
+	0xe6, 0xff, 0xff, 0xff, 0x4a, 0x52, 0x4a, 0x00, 0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x5a, 0x73, 0xef,
+	0xf7, 0xe6, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00, 0x6b, 0x7b, 0x73, 0x08, 0x08, 0x10, 0xff, 0xff,
+	0xff, 0x6b, 0x7b, 0x73,
+	0x08, 0x08, 0x10, 0x31, 0x31, 0x29, 0x4a, 0x52, 0x4a, 0x08, 0x08, 0x10,
+	0xce, 0xde, 0xce, 0xff,
+	0xff, 0xff, 0x10, 0x29, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+	0x31, 0x29, 0x4a, 0x52,
+	0x4a, 0xa5, 0xb5, 0xb5, 0xff, 0xff, 0xff, 0x9c, 0x7b, 0x94, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x4a,
+	0x52, 0x4a, 0xe6, 0xde,
+	0xde, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x31, 0x31, 0x29, 0x08, 0x08,
+	0x10, 0xff, 0xff, 0xff,
+	0x4a, 0x52, 0x4a, 0x08, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00,
+	0x08, 0x08, 0x10, 0x9c,
+	0x7b, 0x94, 0xff, 0xff, 0xff, 0x3a, 0x10, 0x21, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x08,
+	0x10, 0x08, 0x08, 0x10, 0x6b, 0x5a, 0x73, 0xff, 0xff, 0xff, 0xa5, 0xb5,
+	0xb5, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x4a, 0x52,
+	0x4a, 0xef, 0xf7, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0xe6, 0xde, 0xde, 0x08, 0x31, 0x5a, 0x10, 0x7b, 0x9c, 0x10, 0x7b, 0x9c,
+	0x10, 0x7b, 0x9c, 0x10,
+	0x52, 0x7b, 0x31, 0x31, 0x29, 0xef, 0xf7, 0xff, 0x08, 0x08, 0x10, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0xa5, 0x94, 0xff, 0xff,
+	0xff, 0xa5, 0x9c, 0xad,
+	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x10, 0x21, 0x00, 0x08,
+	0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x08, 0x08, 0x10, 0xff, 0xf7, 0xff, 0x4a, 0x52, 0x4a, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x31, 0x5a, 0x00, 0x84, 0xbd, 0x08, 0xad, 0xd6, 0x00, 0xbd, 0xef,
+	0x00, 0xbd, 0xef, 0x00,
+	0x9c, 0xd6, 0x08, 0xa5, 0xad, 0x08, 0xad, 0xd6, 0x10, 0xce, 0xce, 0x6b,
+	0x7b, 0x9c, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff,
+	0x6b, 0x5a, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0xce, 0xde, 0xce, 0xff, 0xf7,
+	0xff, 0x10, 0x29, 0x19,
+	0x10, 0x5a, 0x9c, 0x00, 0x9c, 0xd6, 0x19, 0x94, 0xce, 0x00, 0xbd, 0xf7,
+	0x10, 0xc5, 0xef, 0x08,
+	0xad, 0xd6, 0x08, 0xad, 0xd6, 0x08, 0xad, 0xd6, 0x08, 0xad, 0xd6, 0x10,
+	0xc5, 0xef, 0x00, 0xbd,
+	0xef, 0x08, 0xa5, 0xad, 0x08, 0x31, 0x5a, 0x10, 0x29, 0x19, 0xff, 0xf7,
+	0xff, 0xff, 0xff, 0xff,
+	0xe6, 0xde, 0xde, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x08, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x5a,
+	0x73, 0xef, 0xf7, 0xe6,
+	0x19, 0x7b, 0xbd, 0x19, 0x7b, 0xbd, 0x08, 0xad, 0xd6, 0x00, 0xbd, 0xef,
+	0x10, 0xc5, 0xef, 0x00,
+	0xbd, 0xef, 0x10, 0xc5, 0xef, 0x10, 0xc5, 0xef, 0x3a, 0xde, 0xef, 0x19,
+	0xbd, 0xf7, 0x3a, 0xde,
+	0xef, 0x3a, 0xde, 0xef, 0x10, 0xc5, 0xef, 0x10, 0xc5, 0xef, 0x08, 0xad,
+	0xd6, 0x19, 0x94, 0xce,
+	0xa5, 0xb5, 0xb5, 0x4a, 0x5a, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x08, 0x10,
+	0x10, 0x7b, 0x9c, 0x00, 0x84, 0xbd, 0x08, 0xad, 0xd6, 0x08, 0xad, 0xd6,
+	0x08, 0xad, 0xef, 0x10,
+	0xc5, 0xef, 0x08, 0xad, 0xd6, 0x10, 0xc5, 0xef, 0x10, 0xe6, 0xef, 0x19,
+	0xbd, 0xf7, 0x3a, 0xde,
+	0xef, 0x3a, 0xde, 0xef, 0x10, 0xc5, 0xef, 0x10, 0xe6, 0xef, 0x10, 0xe6,
+	0xef, 0x10, 0xc5, 0xef,
+	0x10, 0xe6, 0xef, 0x19, 0xbd, 0xf7, 0x08, 0xad, 0xd6, 0x08, 0x31, 0x3a,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x08, 0x10,
+	0x10, 0x7b, 0x9c, 0x00, 0x84, 0xbd, 0x19, 0x94, 0xce, 0x00, 0x9c, 0xd6,
+	0x10, 0xc5, 0xef, 0x08,
+	0xad, 0xef, 0x10, 0xc5, 0xef, 0x10, 0xc5, 0xef, 0x10, 0xc5, 0xef, 0x10,
+	0xc5, 0xef, 0x6b, 0xe6,
+	0xef, 0x3a, 0xde, 0xef, 0x10, 0xe6, 0xef, 0x10, 0xe6, 0xef, 0x10, 0xc5,
+	0xef, 0x10, 0xe6, 0xef,
+	0x10, 0xc5, 0xef, 0x10, 0xe6, 0xef, 0x10, 0xc5, 0xef, 0x19, 0xbd, 0xf7,
+	0x19, 0x7b, 0xbd, 0x00,
+	0x00, 0x00, 0x10, 0x21, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x31, 0x5a, 0x00, 0x84, 0xbd, 0x00, 0x84, 0xbd, 0x00, 0x9c, 0xd6,
+	0x08, 0xad, 0xef, 0x08,
+	0xad, 0xef, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xef, 0x10, 0xc5, 0xef, 0x10,
+	0xc5, 0xef, 0x10, 0xe6,
+	0xef, 0x3a, 0xde, 0xef, 0x19, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x10, 0xe6,
+	0xef, 0x10, 0xc5, 0xef,
+	0x10, 0xe6, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0x84, 0xbd, 0x10, 0x7b, 0x9c,
+	0x00, 0xbd, 0xef, 0x10,
+	0x73, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x08, 0x10, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x10, 0x52, 0x7b, 0x19, 0x7b, 0xbd, 0x00, 0x9c, 0xd6,
+	0x19, 0x94, 0xce, 0x08,
+	0xad, 0xef, 0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xd6, 0x10,
+	0xe6, 0xef, 0x19, 0xbd,
+	0xf7, 0x6b, 0xe6, 0xef, 0x19, 0xbd, 0xf7, 0x10, 0xe6, 0xef, 0x10, 0xe6,
+	0xef, 0x10, 0xe6, 0xef,
+	0x10, 0xc5, 0xef, 0x00, 0x9c, 0xd6, 0x00, 0x84, 0xbd, 0x00, 0x9c, 0xd6,
+	0x19, 0x94, 0xce, 0x00,
+	0x9c, 0xd6, 0x10, 0x52, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x08, 0x31, 0x5a,
+	0x08, 0xa5, 0xad, 0x08,
+	0xad, 0xef, 0x00, 0xbd, 0xef, 0x10, 0xc5, 0xef, 0x10, 0xc5, 0xef, 0x10,
+	0xc5, 0xef, 0x10, 0xc5,
+	0xef, 0x10, 0xe6, 0xef, 0x19, 0xbd, 0xf7, 0x10, 0xe6, 0xef, 0x10, 0xc5,
+	0xef, 0x10, 0xc5, 0xef,
+	0x19, 0xbd, 0xf7, 0x10, 0x7b, 0x9c, 0x00, 0x84, 0xbd, 0x19, 0x94, 0xce,
+	0x08, 0xad, 0xd6, 0x00,
+	0x9c, 0xd6, 0x19, 0x94, 0xce, 0x08, 0x31, 0x3a, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x08,
+	0x10, 0x31, 0x31, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+	0x10, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x31, 0x3a, 0x10,
+	0x52, 0x7b, 0x10, 0x7b, 0x9c, 0x08, 0xad, 0xef, 0x08, 0xad, 0xef, 0x10,
+	0xc5, 0xef, 0x10, 0xc5,
+	0xef, 0x3a, 0xde, 0xef, 0x10, 0xe6, 0xef, 0x10, 0xc5, 0xef, 0x10, 0xe6,
+	0xef, 0x08, 0xad, 0xd6,
+	0x10, 0x5a, 0x9c, 0x10, 0x5a, 0x9c, 0x00, 0x9c, 0xd6, 0x19, 0x94, 0xce,
+	0x00, 0x9c, 0xd6, 0x00,
+	0x9c, 0xd6, 0x19, 0x7b, 0xbd, 0x19, 0x7b, 0xbd, 0x08, 0x08, 0x10, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x08, 0x10, 0x9c, 0x7b, 0x73, 0x6b, 0x5a, 0x73, 0x10, 0x29,
+	0x19, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x08, 0x10, 0x73, 0xa5, 0xad, 0x10, 0x52, 0x7b, 0x10, 0x52, 0x7b, 0x00,
+	0x84, 0xbd, 0x08, 0xa5,
+	0xad, 0x08, 0xad, 0xd6, 0x19, 0x94, 0xce, 0x00, 0x84, 0xbd, 0x10, 0x73,
+	0x7b, 0x10, 0x5a, 0x9c,
+	0x00, 0x84, 0xbd, 0x00, 0x9c, 0xd6, 0x00, 0x9c, 0xd6, 0x00, 0x9c, 0xd6,
+	0x00, 0x9c, 0xd6, 0x00,
+	0x84, 0xbd, 0x3a, 0xa5, 0xce, 0xce, 0xad, 0xad, 0xce, 0xde, 0xce, 0x6b,
+	0x5a, 0x73, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x52, 0x4a, 0x6b, 0x7b,
+	0x9c, 0x9c, 0x7b, 0x73,
+	0x31, 0x31, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x31, 0x31, 0x29, 0xc5, 0xad, 0xd6, 0x52, 0xa5, 0xa5, 0x10,
+	0x5a, 0x9c, 0x10, 0x7b,
+	0x9c, 0x19, 0x94, 0xce, 0x08, 0xad, 0xd6, 0x08, 0xad, 0xd6, 0x19, 0x94,
+	0xce, 0x00, 0x9c, 0xd6,
+	0x00, 0x9c, 0xd6, 0x00, 0x84, 0xbd, 0x00, 0x84, 0xbd, 0x19, 0x94, 0xce,
+	0x00, 0x84, 0xbd, 0x19,
+	0x7b, 0xbd, 0xce, 0xad, 0xad, 0xce, 0xde, 0xce, 0xce, 0xde, 0xce, 0xa5,
+	0xb5, 0xb5, 0xa5, 0xb5,
+	0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x21,
+	0x00, 0x6b, 0x7b, 0x73,
+	0x9c, 0x7b, 0x94, 0x6b, 0x7b, 0x73, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x08, 0x10, 0x4a, 0x52, 0x4a, 0xa5, 0xd6, 0xad, 0xc5,
+	0xad, 0xd6, 0x4a, 0x7b,
+	0x9c, 0x10, 0x5a, 0x9c, 0x00, 0x84, 0xbd, 0x00, 0x9c, 0xd6, 0x00, 0x84,
+	0xbd, 0x00, 0x9c, 0xd6,
+	0x19, 0x94, 0xce, 0x00, 0x84, 0xbd, 0x19, 0x94, 0xce, 0x00, 0x84, 0xbd,
+	0x19, 0x7b, 0xbd, 0x73,
+	0xa5, 0xad, 0xa5, 0xb5, 0xb5, 0xc5, 0xad, 0xd6, 0xa5, 0xb5, 0xb5, 0xe6,
+	0xde, 0xde, 0xce, 0xde,
+	0xce, 0xce, 0xad, 0xad, 0x10, 0x29, 0x19, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x4a, 0x52, 0x4a, 0x6b, 0x7b, 0x73, 0x31, 0x31, 0x29, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x31, 0x4a, 0xce,
+	0xad, 0xad, 0xce, 0xde,
+	0xce, 0xa5, 0xb5, 0xb5, 0x73, 0xa5, 0xad, 0x10, 0x73, 0x7b, 0x10, 0x5a,
+	0x9c, 0x10, 0x7b, 0x9c,
+	0x10, 0x5a, 0xbd, 0x10, 0x7b, 0x9c, 0x10, 0x5a, 0x9c, 0x10, 0x5a, 0x9c,
+	0x19, 0x7b, 0xbd, 0xa5,
+	0xb5, 0xb5, 0xa5, 0xb5, 0xb5, 0xc5, 0xad, 0xd6, 0xa5, 0xd6, 0xad, 0xef,
+	0xde, 0xef, 0xef, 0xf7,
+	0xe6, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xa5, 0x9c, 0xad, 0x08, 0x08,
+	0x10, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x4a,
+	0x52, 0x4a, 0xe6, 0xde,
+	0xde, 0xc5, 0xad, 0xd6, 0xa5, 0xb5, 0xb5, 0xce, 0xad, 0xad, 0x9c, 0xad,
+	0xce, 0x52, 0xa5, 0xa5,
+	0x10, 0x5a, 0x9c, 0x10, 0x7b, 0x9c, 0x10, 0x5a, 0x9c, 0x52, 0xa5, 0xa5,
+	0x73, 0xa5, 0xad, 0xc5,
+	0xad, 0xd6, 0xa5, 0xb5, 0xb5, 0xce, 0xde, 0xce, 0xce, 0xde, 0xce, 0xef,
+	0xde, 0xef, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xef, 0xf7, 0xff, 0xef, 0xf7,
+	0xe6, 0x08, 0x08, 0x10,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xef, 0xf7,
+	0xe6, 0xef, 0xf7, 0xe6, 0xce, 0xde, 0xce, 0xce, 0xde, 0xce, 0xa5, 0xb5,
+	0xb5, 0xce, 0xde, 0xce,
+	0xce, 0xad, 0xad, 0xce, 0xde, 0xce, 0xa5, 0xb5, 0xb5, 0xce, 0xde, 0xce,
+	0xce, 0xad, 0xad, 0xc5,
+	0xad, 0xd6, 0xa5, 0xd6, 0xad, 0xce, 0xad, 0xad, 0xce, 0xde, 0xce, 0xe6,
+	0xde, 0xde, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xa5, 0xb5, 0xb5, 0x08, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x08, 0x08,
+	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x10, 0x21, 0x00, 0x00,
+	0x00, 0x00, 0x9c, 0xa5,
+	0x94, 0xff, 0xf7, 0xff, 0xff, 0xf7, 0xff, 0xef, 0xf7, 0xe6, 0xc5, 0xad,
+	0xd6, 0xa5, 0xb5, 0xb5,
+	0xce, 0xad, 0xad, 0xc5, 0xad, 0xd6, 0xa5, 0xb5, 0xb5, 0xce, 0xad, 0xad,
+	0xc5, 0xad, 0xd6, 0xa5,
+	0xd6, 0xad, 0xc5, 0xad, 0xd6, 0xce, 0xde, 0xce, 0xef, 0xde, 0xef, 0xef,
+	0xf7, 0xe6, 0xff, 0xf7,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x31, 0x31, 0x29, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x08, 0x08, 0x10, 0x08,
+	0x08, 0x10, 0x10, 0x29,
+	0x19, 0xef, 0xde, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6,
+	0xc5, 0xad, 0xd6, 0xa5, 0xd6, 0xad, 0xa5, 0xb5, 0xb5, 0xce, 0xde, 0xce,
+	0xa5, 0xb5, 0xb5, 0xce,
+	0xde, 0xce, 0xce, 0xad, 0xad, 0xce, 0xde, 0xce, 0xef, 0xf7, 0xe6, 0xef,
+	0xf7, 0xff, 0xff, 0xf7,
+	0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe6, 0xde, 0xde,
+	0x08, 0x08, 0x10, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x10, 0x21,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0xe6, 0xde, 0xde, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xe6, 0xe6, 0xde, 0xde, 0xce, 0xad, 0xad, 0xc5, 0xad, 0xd6,
+	0xa5, 0xb5, 0xb5, 0xce,
+	0xad, 0xad, 0xce, 0xde, 0xce, 0xce, 0xe6, 0xef, 0xff, 0xf7, 0xff, 0xff,
+	0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x08, 0x08,
+	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x4a, 0x52, 0x4a, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xef, 0xf7, 0xe6,
+	0xe6, 0xde, 0xde, 0xef,
+	0xf7, 0xe6, 0xce, 0xe6, 0xef, 0xff, 0xf7, 0xff, 0xff, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xa5, 0x9c, 0xad, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xe6, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xe6, 0xde, 0xde, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x4a, 0x52, 0x4a, 0xef, 0xf7, 0xe6, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08,
+	0x08, 0x10, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0x10, 0xce, 0xde, 0xce, 0xef, 0xde,
+	0xef, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xef,
+	0xf7, 0xff, 0x31, 0x31,
+	0x29, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0xce, 0xad,
+	0xad, 0xef, 0xf7, 0xe6,
+	0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xef,
+	0xf7, 0xe6, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xef, 0xf7, 0xe6, 0xef,
+	0xde, 0xef, 0xef, 0xf7,
+	0xe6, 0x9c, 0xa5, 0x94, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x21, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x31,
+	0x29, 0xa5, 0xb5, 0xb5,
+	0xce, 0xde, 0xce, 0xef, 0xf7, 0xe6, 0xef, 0xf7, 0xff, 0xff, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xe6, 0xef, 0xf7, 0xe6, 0xef, 0xde, 0xef, 0xef,
+	0xf7, 0xe6, 0xe6, 0xde,
+	0xde, 0xce, 0xe6, 0xef, 0xff, 0xf7, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xf7,
+	0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xef, 0xf7, 0xff, 0xef, 0xf7, 0xe6,
+	0xef, 0xf7, 0xe6, 0xef,
+	0xde, 0xef, 0xce, 0xe6, 0xef, 0xe6, 0xde, 0xde, 0xe6, 0xde, 0xde, 0xce,
+	0xde, 0xce, 0xce, 0xde,
+	0xce, 0xe6, 0xde, 0xde, 0xce, 0xad, 0xad, 0x08, 0x08, 0x10, 0x00, 0x00,
+	0x00, 0x10, 0x21, 0x00,
+	0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x08, 0x10, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+	0x10, 0x6b, 0x5a, 0x4a,
+	0x73, 0xa5, 0xad, 0xce, 0xad, 0xad, 0xc5, 0xad, 0xd6, 0xe6, 0xde, 0xde,
+	0xe6, 0xde, 0xde, 0xff,
+	0xf7, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xef,
+	0xde, 0xef, 0xce, 0xde,
+	0xce, 0xef, 0xde, 0xef, 0xef, 0xf7, 0xe6, 0xef, 0xf7, 0xe6, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xde, 0xef,
+	0xce, 0xde, 0xce, 0xc5,
+	0xad, 0xd6, 0xce, 0xde, 0xce, 0xce, 0xad, 0xad, 0xce, 0xde, 0xce, 0xa5,
+	0xb5, 0xb5, 0xc5, 0xad,
+	0xd6, 0xa5, 0xb5, 0xb5, 0xc5, 0xad, 0xd6, 0xef, 0xf7, 0xff, 0x4a, 0x52,
+	0x4a, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00,
+	0x00, 0x10, 0x29, 0x19,
+	0x6b, 0x5a, 0x73, 0xce, 0xad, 0xad, 0xce, 0xde, 0xce, 0xce, 0xde, 0xce,
+	0xef, 0xf7, 0xe6, 0xef,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xef, 0xde, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7,
+	0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xf7, 0xff, 0xef, 0xf7, 0xe6, 0xe6, 0xde, 0xde, 0xce, 0xde, 0xce, 0xc5,
+	0xad, 0xd6, 0xce, 0xde,
+	0xce, 0xce, 0xad, 0xad, 0xce, 0xde, 0xce, 0xa5, 0xb5, 0xb5, 0xce, 0xde,
+	0xce, 0xff, 0xf7, 0xff,
+	0x31, 0x31, 0x29, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x4a, 0x52, 0x4a,
+	0x31, 0x31, 0x29, 0x08,
+	0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x08, 0x08, 0x10, 0xa5, 0x9c, 0xad, 0xce, 0xde, 0xce, 0xce, 0xe6, 0xef,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xf7,
+	0xff, 0xef, 0xf7, 0xe6, 0xef, 0xf7, 0xe6, 0xef, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xce, 0xe6, 0xef, 0xe6, 0xde, 0xde, 0xce, 0xde, 0xce, 0xc5, 0xad,
+	0xd6, 0xce, 0xad, 0xad,
+	0xe6, 0xde, 0xde, 0xff, 0xf7, 0xff, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x08, 0x10, 0x31, 0x31, 0x29, 0x3a, 0x10, 0x21, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x31, 0x31,
+	0x29, 0x00, 0x00, 0x00,
+	0x10, 0x21, 0x00, 0x6b, 0x5a, 0x73, 0xce, 0xde, 0xce, 0xff, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xe6, 0xce, 0xde, 0xce,
+	0xce, 0xde, 0xce, 0x9c, 0xad, 0xce, 0xef, 0xf7, 0xe6, 0xa5, 0x9c, 0xad,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x3a, 0x31, 0x4a, 0x10,
+	0x29, 0x19, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x52,
+	0x4a, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0xe6, 0xde, 0xde, 0xef, 0xf7, 0xe6,
+	0xff, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xe6, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xf7, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xe6, 0xff, 0xf7, 0xff,
+	0xef, 0xf7, 0xff, 0xef, 0xde, 0xef, 0xce, 0xe6, 0xad, 0xc5, 0xad, 0xd6,
+	0xff, 0xff, 0xff, 0x10,
+	0x29, 0x19, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x31, 0x31,
+	0x29, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x10, 0x21, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x29,
+	0x19, 0x08, 0x08, 0x10,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x5a, 0x73, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xde, 0xef,
+	0xce, 0xde, 0xce, 0xce,
+	0xde, 0xce, 0xce, 0xad, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+	0x21, 0x00, 0x08, 0x08,
+	0x10, 0x08, 0x08, 0x10, 0x4a, 0x52, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00,
+	0x00, 0x4a, 0x52, 0x4a,
+	0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xf7, 0xe6,
+	0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xe6, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xef,
+	0xde, 0xef, 0xce, 0xde, 0xce, 0xef, 0xf7, 0xff, 0x08, 0x08, 0x10, 0x00,
+	0x00, 0x00, 0x3a, 0x10,
+	0x21, 0x31, 0x31, 0x29, 0x31, 0x31, 0x29, 0x08, 0x08, 0x10, 0x10, 0x29,
+	0x19, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x10, 0x29, 0x19,
+	0x3a, 0x10, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x7b, 0x94,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0x4a,
+	0x52, 0x4a, 0x00, 0x00,
+	0x00, 0x10, 0x29, 0x19, 0x4a, 0x52, 0x4a, 0x31, 0x31, 0x29, 0x08, 0x08,
+	0x10, 0x3a, 0x31, 0x4a,
+	0x08, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x4a, 0x52, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10,
+	0xef, 0xf7, 0xe6, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xce, 0xde,
+	0xce, 0x3a, 0x10, 0x21, 0x10, 0x29, 0x19, 0x3a, 0x31, 0x4a, 0x3a, 0x10,
+	0x21, 0x10, 0x21, 0x00,
+	0x08, 0x08, 0x10, 0x31, 0x31, 0x29, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x08, 0x10, 0x3a, 0x10, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x9c, 0x7b, 0x94, 0xef,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xe6, 0xde, 0xde, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x4a, 0x52, 0x4a, 0x08, 0x08, 0x10,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x4a, 0x52, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x08, 0x10, 0xef,
+	0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xe6, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xce, 0xe6, 0xef, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff,
+	0xf7, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0x3a, 0x10, 0x21, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x31, 0x29,
+	0x08, 0x08, 0x10, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x31, 0x31, 0x29, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x4a,
+	0x52, 0x4a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xe6, 0xde, 0xde,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xe6, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4a, 0x52,
+	0x4a, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x08, 0x10, 0x31,
+	0x31, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x31, 0x29, 0x08, 0x08, 0x10,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xe6, 0xde, 0xde, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6,
+	0xe6, 0xde, 0xde, 0xef,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xf7,
+	0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xef,
+	0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xf7, 0xff, 0xef, 0xf7,
+	0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xff, 0x9c, 0x7b, 0x94,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x08,
+	0x08, 0x10, 0x10, 0x29, 0x19, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x52, 0x4a,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x10, 0x29, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xe6, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xe6, 0xce,
+	0xe6, 0xef, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xef, 0xf7, 0xe6, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xe6, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xa5, 0xb5, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x08, 0x08, 0x10, 0x00,
+	0x00, 0x00, 0x08, 0x08, 0x10, 0x3a, 0x10, 0x21, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x10, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x31, 0x31, 0x29, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x52, 0x4a, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xf7, 0xff, 0xef,
+	0xf7, 0xe6, 0xe6, 0xde, 0xde, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xf7,
+	0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xce, 0xde, 0xce, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x29, 0x19, 0x08, 0x08, 0x10, 0x00,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x08, 0x08, 0x10, 0x31,
+	0x31, 0x29, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0xce, 0xad, 0xad, 0xef,
+	0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xe6, 0xef, 0xde, 0xef, 0xef, 0xf7, 0xe6, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x29, 0x19, 0x08,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x10,
+	0x21, 0x00, 0x3a, 0x31, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xce,
+	0xe6, 0xef, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xf7, 0xff, 0xce, 0xe6, 0xef, 0xe6, 0xde, 0xde, 0xef,
+	0xf7, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x3a,
+	0x31, 0x4a, 0x08, 0x08,
+	0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x08, 0x10, 0x4a, 0x52, 0x4a, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0xef, 0xf7,
+	0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xe6, 0xde, 0xde, 0xe6,
+	0xde, 0xde, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xe6, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x4a, 0x52,
+	0x4a, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x21, 0x4a, 0x52, 0x4a, 0x00,
+	0x00, 0x00, 0x08, 0x08,
+	0x10, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xce,
+	0xe6, 0xef, 0xe6, 0xde,
+	0xde, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x10, 0x29, 0x19, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x3a, 0x31, 0x4a, 0x6b,
+	0x7b, 0x73, 0x08, 0x00,
+	0x00, 0x10, 0x29, 0x19, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xe6, 0xde,
+	0xde, 0xef, 0xf7, 0xe6, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6,
+	0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x10, 0x29, 0x19, 0x08, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10,
+	0x29, 0x19, 0x6b, 0x5a,
+	0x73, 0x08, 0x00, 0x00, 0x10, 0x29, 0x19, 0xff, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xe6, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xe6, 0xde, 0xde, 0xe6, 0xde, 0xde, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xe6, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x08, 0x10, 0x31, 0x31, 0x29, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x31, 0x31, 0x29, 0x08, 0x00, 0x00, 0x31, 0x31, 0x29, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xf7,
+	0xff, 0xef, 0xf7, 0xff, 0xe6, 0xde, 0xde, 0xef, 0xf7, 0xe6, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xe6, 0xde, 0xde, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x10, 0x29, 0x19, 0x08, 0x08,
+	0x10, 0x08, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x31, 0x4a, 0x31, 0x31,
+	0x29, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xe6, 0xff,
+	0xff, 0xff, 0xff, 0xf7, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe6, 0xde, 0xde, 0xce, 0xe6,
+	0xef, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xef, 0xf7, 0xff, 0xff, 0xf7,
+	0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa5,
+	0xb5, 0xb5, 0x00, 0x00,
+	0x00, 0x10, 0x21, 0x00, 0x3a, 0x31, 0x4a, 0x10, 0x29, 0x19, 0x3a, 0x08,
+	0x00, 0x08, 0x08, 0x10,
+	0x08, 0x08, 0x10, 0x31, 0x31, 0x29, 0x31, 0x31, 0x29, 0x10, 0x29, 0x19,
+	0x08, 0x08, 0x10, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x10,
+	0x7b, 0x9c, 0x10, 0xc5,
+	0xef, 0x10, 0xc5, 0xef, 0x10, 0x7b, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x4a, 0x52, 0x4a,
+	0xef, 0xf7, 0xe6, 0xff, 0xf7, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xe6, 0xff, 0xf7,
+	0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe6, 0xde,
+	0xde, 0xef, 0xf7, 0xe6,
+	0xff, 0xf7, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0x6b, 0x5a,
+	0x4a, 0x08, 0x08, 0x10, 0x08, 0x08, 0x10, 0x08, 0x00, 0x00, 0x08, 0x00,
+	0x00, 0x08, 0x08, 0x10,
+	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00,
+	0x3a, 0x10, 0x21, 0x6b,
+	0x5a, 0x73, 0x10, 0x29, 0x19, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19,
+	0x94, 0xce, 0x08, 0xad,
+	0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x08, 0xad,
+	0xd6, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x4a, 0x5a, 0x73, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xe6, 0xde, 0xde,
+	0xef, 0xde, 0xef, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xe6, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xce, 0xe6, 0xef, 0xce,
+	0xe6, 0xef, 0xce, 0xe6,
+	0xef, 0x08, 0x10, 0x42, 0x10, 0x29, 0x19, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x31, 0x31, 0x29, 0x4a, 0x52, 0x4a, 0x08, 0x08, 0x10, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19,
+	0x7b, 0xbd, 0x00, 0x9c,
+	0xd6, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7,
+	0x00, 0x9c, 0xd6, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x4a, 0x52, 0x4a,
+	0xef, 0xde, 0xef, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xe6, 0xff, 0xff, 0xff,
+	0xe6, 0xde, 0xde, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xe6, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xff, 0xef, 0xf7, 0xff, 0x08, 0xad, 0xd6, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd,
+	0xef, 0x10, 0xc5, 0xef, 0x10, 0xc5, 0xef, 0x08, 0x08, 0x10, 0x08, 0x08,
+	0x10, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x08, 0x10, 0x31, 0x31, 0x29, 0x10, 0x29, 0x19, 0x3a,
+	0x10, 0x21, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x84,
+	0xbd, 0x08, 0xad, 0xd6, 0x08, 0xad, 0xef, 0x08, 0xad, 0xef, 0x10, 0xc5,
+	0xef, 0x00, 0xbd, 0xf7,
+	0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x19, 0x7b, 0xbd, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x31,
+	0x31, 0x29, 0xe6, 0xde, 0xde, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xce, 0xe6, 0xef, 0xef, 0xf7, 0xe6, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xce, 0xe6, 0xef, 0x08,
+	0xad, 0xef, 0x00, 0xbd,
+	0xf7, 0x10, 0xe6, 0xef, 0x10, 0xc5, 0xef, 0x10, 0xe6, 0xef, 0x08, 0x08,
+	0x10, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x29, 0x19, 0x10, 0x29, 0x19, 0x00,
+	0x00, 0x00, 0x00, 0x84,
+	0xbd, 0x10, 0xe6, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x19, 0x7b,
+	0xbd, 0x00, 0x9c, 0xd6, 0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x19, 0xbd,
+	0xf7, 0x00, 0xbd, 0xf7,
+	0x08, 0xad, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x10, 0xc5, 0xef,
+	0x10, 0x5a, 0x9c, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x29, 0x19, 0xce, 0xde, 0xce, 0xff,
+	0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xe6, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe6, 0xde, 0xde, 0xef, 0xde, 0xef,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xce,
+	0xe6, 0xef, 0x00, 0x9c,
+	0xd6, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x08, 0xad,
+	0xd6, 0x08, 0x08, 0x10,
+	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x08, 0x10, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0x10, 0x08, 0x00, 0x00, 0x08,
+	0x08, 0x10, 0x08, 0x31,
+	0x3a, 0x10, 0xc5, 0xef, 0x10, 0xc5, 0xef, 0x10, 0xc5, 0xef, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x84,
+	0xbd, 0x19, 0x94, 0xce, 0x08, 0xad, 0xef, 0x08, 0xad, 0xef, 0x08, 0xad,
+	0xef, 0x00, 0xbd, 0xef,
+	0x19, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7,
+	0x10, 0xc5, 0xef, 0x00,
+	0xbd, 0xef, 0x08, 0x31, 0x3a, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x9c, 0xa5,
+	0x94, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xe6, 0xef,
+	0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xce, 0xe6,
+	0xef, 0x08, 0xad, 0xd6, 0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd,
+	0xef, 0x19, 0x94, 0xce,
+	0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x19, 0x94, 0xce, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xef, 0x10, 0xc5,
+	0xef, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x84, 0xbd, 0x00,
+	0x84, 0xbd, 0x19, 0x94, 0xce, 0x08, 0xad, 0xef, 0x00, 0x84, 0xbd, 0x19,
+	0x94, 0xce, 0x00, 0x84,
+	0xbd, 0x08, 0xad, 0xd6, 0x00, 0x9c, 0xd6, 0x08, 0xad, 0xef, 0x10, 0xc5,
+	0xef, 0x19, 0xbd, 0xf7,
+	0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x00,
+	0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xd6, 0x08, 0x08, 0x10, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x4a, 0x52, 0x4a, 0xff, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xe6, 0xef, 0xde,
+	0xef, 0x9c, 0xde, 0xd6, 0x08, 0xad, 0xef, 0x08, 0xad, 0xef, 0x10, 0xc5,
+	0xef, 0x08, 0xad, 0xef,
+	0x00, 0x84, 0xbd, 0x08, 0x31, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x21, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x10, 0x5a, 0x9c, 0x08, 0xad, 0xd6, 0x00, 0xbd, 0xef, 0x10, 0xc5,
+	0xef, 0x10, 0xc5, 0xef,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x19,
+	0x94, 0xce, 0x08, 0xad, 0xef, 0x08, 0xad, 0xd6, 0x08, 0xad, 0xef, 0x08,
+	0xad, 0xef, 0x08, 0xad,
+	0xef, 0x08, 0xad, 0xef, 0x08, 0xad, 0xef, 0x08, 0xad, 0xef, 0x10, 0xc5,
+	0xef, 0x00, 0xbd, 0xf7,
+	0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7,
+	0x10, 0xc5, 0xef, 0x00,
+	0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x19,
+	0x7b, 0xbd, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x31,
+	0x29, 0xce, 0xe6, 0xef,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xce, 0xe6,
+	0xef, 0xce, 0xad, 0xad, 0x9c, 0xad, 0xce, 0x19, 0x94, 0xce, 0x08, 0xad,
+	0xef, 0x00, 0xbd, 0xef,
+	0x19, 0x94, 0xce, 0x00, 0x9c, 0xd6, 0x10, 0x5a, 0x9c, 0x08, 0x08, 0x10,
+	0x00, 0x00, 0x00, 0x08,
+	0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00,
+	0x00, 0x00, 0x08, 0x08,
+	0x10, 0x10, 0x73, 0x7b, 0x00, 0x9c, 0xd6, 0x00, 0xbd, 0xef, 0x10, 0xc5,
+	0xef, 0x08, 0xad, 0xef,
+	0x00, 0xbd, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x84, 0xbd, 0x00, 0x9c, 0xd6, 0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x08,
+	0xad, 0xef, 0x10, 0xc5,
+	0xef, 0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x19, 0xbd, 0xf7, 0x19, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7,
+	0x19, 0xbd, 0xf7, 0x00,
+	0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x19, 0xbd, 0xf7, 0x00,
+	0xbd, 0xef, 0x10, 0xce,
+	0xce, 0x08, 0x31, 0x3a, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x08, 0x10, 0xce, 0xde, 0xce, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xf7, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xe6, 0xc5, 0xad, 0xd6, 0xce, 0xde, 0xce, 0x9c, 0xad, 0xce, 0x08, 0xad,
+	0xd6, 0x08, 0xad, 0xef,
+	0x08, 0xad, 0xef, 0x08, 0xad, 0xef, 0x00, 0x9c, 0xd6, 0x19, 0x7b, 0xbd,
+	0x10, 0x7b, 0x9c, 0x08,
+	0x31, 0x5a, 0x08, 0x31, 0x3a, 0x08, 0x08, 0x10, 0x08, 0x31, 0x3a, 0x08,
+	0x31, 0x3a, 0x10, 0x5a,
+	0x9c, 0x00, 0x84, 0xbd, 0x00, 0x9c, 0xd6, 0x19, 0x94, 0xce, 0x00, 0xbd,
+	0xef, 0x08, 0xad, 0xef,
+	0x10, 0xc5, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x19, 0x7b, 0xbd, 0x19, 0x94, 0xce, 0x08, 0xad, 0xef, 0x08,
+	0xad, 0xef, 0x00, 0xbd,
+	0xef, 0x19, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x10, 0xc5,
+	0xef, 0x00, 0xbd, 0xf7,
+	0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x00, 0xbd, 0xf7,
+	0x19, 0xbd, 0xf7, 0x00,
+	0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00,
+	0xbd, 0xf7, 0x10, 0xc5,
+	0xef, 0x00, 0xbd, 0xf7, 0x19, 0x94, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x7b, 0x94,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xa5, 0xb5, 0xb5, 0xce, 0xde, 0xce, 0x9c, 0xad,
+	0xce, 0x19, 0x94, 0xce,
+	0x08, 0xad, 0xd6, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xd6, 0x00, 0x9c, 0xd6,
+	0x00, 0x9c, 0xd6, 0x00,
+	0x84, 0xbd, 0x00, 0x84, 0xbd, 0x00, 0x84, 0xbd, 0x00, 0x84, 0xbd, 0x19,
+	0x7b, 0xbd, 0x00, 0x84,
+	0xbd, 0x00, 0x84, 0xbd, 0x00, 0x84, 0xbd, 0x08, 0xad, 0xef, 0x08, 0xad,
+	0xef, 0x10, 0xc5, 0xef,
+	0x19, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x00, 0xbd, 0xef, 0x08, 0xad, 0xef,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0xbd, 0x08, 0xad, 0xd6, 0x08,
+	0xad, 0xef, 0x10, 0xc5,
+	0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x19, 0xbd,
+	0xf7, 0x00, 0xbd, 0xf7,
+	0x19, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xef, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x00,
+	0xbd, 0xf7, 0x19, 0xbd,
+	0xf7, 0x00, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xef, 0x10, 0x52,
+	0x7b, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x6b,
+	0x7b, 0x73, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xef, 0xf7,
+	0xe6, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xce, 0xad, 0xad, 0xce, 0xde,
+	0xce, 0xa5, 0xb5, 0xb5,
+	0x00, 0x9c, 0xd6, 0x08, 0xad, 0xef, 0x08, 0xad, 0xef, 0x08, 0xad, 0xef,
+	0x19, 0x94, 0xce, 0x00,
+	0x9c, 0xd6, 0x19, 0x94, 0xce, 0x00, 0x84, 0xbd, 0x19, 0x94, 0xce, 0x00,
+	0x84, 0xbd, 0x00, 0x84,
+	0xbd, 0x00, 0x84, 0xbd, 0x19, 0x94, 0xce, 0x08, 0xad, 0xef, 0x08, 0xad,
+	0xef, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x10, 0xc5, 0xef,
+	0x10, 0xc5, 0xef, 0x19,
+	0x94, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x7b, 0xbd, 0x19,
+	0x94, 0xce, 0x08, 0xad,
+	0xef, 0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x19, 0xbd,
+	0xf7, 0x00, 0xbd, 0xf7,
+	0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x00, 0xbd, 0xf7, 0x10, 0xc5, 0xef,
+	0x00, 0xbd, 0xf7, 0x08,
+	0xad, 0xef, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00,
+	0xbd, 0xf7, 0x19, 0xbd,
+	0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x10, 0xc5,
+	0xef, 0x08, 0xad, 0xd6,
+	0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0xde, 0xce, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xe6, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xef, 0xf7, 0xff, 0xce, 0xde,
+	0xce, 0xc5, 0xad, 0xd6,
+	0xa5, 0xb5, 0xb5, 0x19, 0x94, 0xce, 0x00, 0x9c, 0xd6, 0x08, 0xad, 0xd6,
+	0x08, 0xad, 0xef, 0x08,
+	0xad, 0xef, 0x08, 0xad, 0xef, 0x00, 0x9c, 0xd6, 0x00, 0x9c, 0xd6, 0x00,
+	0x9c, 0xd6, 0x00, 0x9c,
+	0xd6, 0x19, 0x94, 0xce, 0x08, 0xad, 0xef, 0x08, 0xad, 0xd6, 0x08, 0xad,
+	0xef, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7,
+	0x10, 0xc5, 0xef, 0x08,
+	0xad, 0xef, 0x08, 0xad, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x84, 0xbd, 0x00, 0x9c,
+	0xd6, 0x08, 0xad, 0xd6, 0x08, 0xad, 0xef, 0x19, 0xbd, 0xf7, 0x19, 0xbd,
+	0xf7, 0x00, 0xbd, 0xef,
+	0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x10,
+	0xc5, 0xef, 0x00, 0xbd,
+	0xf7, 0x10, 0xc5, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x00, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xef, 0x19, 0x7b, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x5a, 0x73, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xe6, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xe6, 0xce, 0xde, 0xce,
+	0xa5, 0xb5, 0xb5, 0x9c, 0xad, 0xce, 0x00, 0x84, 0xbd, 0x00, 0x9c, 0xd6,
+	0x08, 0xad, 0xef, 0x10,
+	0xc5, 0xef, 0x08, 0xad, 0xef, 0x08, 0xad, 0xd6, 0x08, 0xad, 0xef, 0x19,
+	0x94, 0xce, 0x08, 0xad,
+	0xef, 0x19, 0x94, 0xce, 0x08, 0xad, 0xef, 0x08, 0xad, 0xd6, 0x08, 0xad,
+	0xef, 0x00, 0xbd, 0xef,
+	0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x08, 0xad, 0xef,
+	0x19, 0xbd, 0xf7, 0x00,
+	0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x08, 0xad, 0xd6, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x10, 0x7b, 0xe6, 0x08, 0xad, 0xd6, 0x08, 0xad, 0xef, 0x00, 0xbd,
+	0xef, 0x00, 0xbd, 0xf7,
+	0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x08,
+	0xad, 0xef, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x08,
+	0xad, 0xef, 0x00, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x00, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7,
+	0x10, 0xc5, 0xef, 0x10, 0xe6, 0xef, 0x00, 0xbd, 0xef, 0x08, 0x31, 0x3a,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a,
+	0x52, 0x4a, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xe6, 0xff,
+	0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xf7, 0xff,
+	0xe6, 0xde, 0xde, 0xc5, 0xad, 0xd6, 0x29, 0x5a, 0x4a, 0x00, 0x84, 0xbd,
+	0x19, 0x94, 0xce, 0x08,
+	0xad, 0xd6, 0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x00,
+	0xbd, 0xef, 0x08, 0xad,
+	0xef, 0x08, 0xad, 0xef, 0x08, 0xad, 0xd6, 0x08, 0xad, 0xef, 0x08, 0xad,
+	0xef, 0x08, 0xad, 0xef,
+	0x19, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x00,
+	0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd,
+	0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x19, 0x94, 0xce, 0x08, 0xad, 0xd6, 0x08, 0xad,
+	0xef, 0x19, 0xbd, 0xf7,
+	0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7,
+	0x10, 0xc5, 0xef, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x10,
+	0xc5, 0xef, 0x19, 0xbd,
+	0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd,
+	0xf7, 0x00, 0xbd, 0xf7,
+	0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x00, 0xbd, 0xf7, 0x10, 0xc5, 0xef,
+	0x08, 0xad, 0xd6, 0x08,
+	0x08, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x9c, 0xa5,
+	0x94, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xf7,
+	0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xf7, 0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xe6, 0xff, 0xf7, 0xff,
+	0xef, 0xf7, 0xff, 0xce, 0xde, 0xce, 0x4a, 0x52, 0x4a, 0x08, 0x31, 0x5a,
+	0x00, 0x84, 0xbd, 0x00,
+	0x9c, 0xd6, 0x08, 0xad, 0xef, 0x08, 0xad, 0xef, 0x19, 0xbd, 0xf7, 0x10,
+	0xc5, 0xef, 0x08, 0xad,
+	0xef, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x00, 0xbd, 0xef, 0x10, 0xc5,
+	0xef, 0x08, 0xad, 0xef,
+	0x00, 0xbd, 0xef, 0x10, 0xc5, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7,
+	0x19, 0xbd, 0xf7, 0x00,
+	0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x00,
+	0xbd, 0xef, 0x00, 0xbd,
+	0xf7, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x08, 0xad, 0xef, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0xd6, 0x19, 0x94,
+	0xce, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7,
+	0x08, 0xad, 0xef, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x10,
+	0xc5, 0xef, 0x00, 0xbd,
+	0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19, 0xbd,
+	0xf7, 0x00, 0xbd, 0xf7,
+	0x08, 0xad, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7,
+	0x10, 0xc5, 0xef, 0x10,
+	0xc5, 0xef, 0x10, 0x5a, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x9c, 0x7b,
+	0x94, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xf7, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xe6, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4a, 0x52, 0x4a, 0x08, 0x00, 0x00,
+	0x08, 0x31, 0x5a, 0x00,
+	0x84, 0xbd, 0x19, 0x94, 0xce, 0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x08,
+	0xad, 0xef, 0x19, 0xbd,
+	0xf7, 0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x00, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x10, 0xc5, 0xef,
+	0x00, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x94,
+	0xce, 0x00, 0x9c, 0xd6,
+	0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xef,
+	0x19, 0xbd, 0xf7, 0x00,
+	0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x00, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x10, 0xc5, 0xef,
+	0x08, 0xad, 0xef, 0x00,
+	0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xd6, 0x10, 0x73, 0x7b, 0xe6,
+	0xde, 0xde, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0x31, 0x31, 0x29, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x10,
+	0x52, 0x7b, 0x00, 0x84, 0xbd, 0x08, 0xad, 0xd6, 0x08, 0xad, 0xef, 0x08,
+	0xad, 0xef, 0x00, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x08, 0xad,
+	0xef, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd,
+	0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x00, 0xbd, 0xf7, 0x19, 0xbd,
+	0xf7, 0x00, 0xbd, 0xf7,
+	0x00, 0xbd, 0xef, 0x08, 0xad, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x84, 0xbd,
+	0x00, 0x9c, 0xd6, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x08, 0xad, 0xef,
+	0x19, 0xbd, 0xf7, 0x00,
+	0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd,
+	0xf7, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xd6, 0x10, 0xc5, 0xef, 0x19,
+	0x94, 0xce, 0x9c, 0xad,
+	0xce, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xe6, 0xff,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xe6, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xef, 0xf7, 0xff, 0xef, 0xde, 0xef, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x10, 0x52, 0x7b, 0x00, 0x84, 0xbd, 0x19, 0x94, 0xce, 0x08,
+	0xad, 0xef, 0x08, 0xad,
+	0xef, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x10, 0xc5,
+	0xef, 0x00, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x10, 0xc5, 0xef,
+	0x00, 0xbd, 0xf7, 0x10,
+	0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x08,
+	0xad, 0xef, 0x10, 0xc5,
+	0xef, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x10, 0xc5,
+	0xef, 0x00, 0xbd, 0xf7,
+	0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x08, 0xad, 0xef, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x84, 0xbd,
+	0x00, 0x84, 0xbd, 0x08, 0xad, 0xef, 0x08, 0xad, 0xef, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x00,
+	0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd,
+	0xef, 0x19, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd,
+	0xf7, 0x10, 0xc5, 0xef,
+	0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x10, 0xc5, 0xef,
+	0x00, 0xbd, 0xf7, 0x10,
+	0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x10,
+	0xc5, 0xef, 0x08, 0xad,
+	0xd6, 0x10, 0x7b, 0x9c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff,
+	0xff, 0xef, 0xf7, 0xff,
+	0xff, 0xff, 0xff, 0x9c, 0xa5, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x08, 0x08, 0x10, 0x10, 0x52, 0x7b, 0x00, 0x84, 0xbd, 0x08,
+	0xad, 0xd6, 0x00, 0xbd,
+	0xef, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x19, 0xbd, 0xf7,
+	0x08, 0xad, 0xef, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7,
+	0x08, 0xad, 0xef, 0x08, 0xad, 0xef, 0x19, 0x94, 0xce, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x84, 0xbd, 0x19, 0x94, 0xce, 0x08, 0xad, 0xef, 0x08, 0xad, 0xef,
+	0x00, 0xbd, 0xef, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd,
+	0xf7, 0x10, 0xc5, 0xef,
+	0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7,
+	0x08, 0xad, 0xef, 0x00,
+	0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x00,
+	0xbd, 0xef, 0x10, 0xc5,
+	0xef, 0x08, 0xad, 0xd6, 0x00, 0x84, 0xbd, 0x10, 0x52, 0x7b, 0xef, 0xf7,
+	0xe6, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xff, 0xff, 0xf7, 0xff, 0xef, 0xf7, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xf7, 0xff,
+	0xce, 0xde, 0xce, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x52, 0x7b, 0x00,
+	0x84, 0xbd, 0x19, 0x94,
+	0xce, 0x08, 0xad, 0xef, 0x08, 0xad, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7,
+	0x19, 0xbd, 0xf7, 0x00,
+	0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd,
+	0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd,
+	0xef, 0x19, 0xbd, 0xf7,
+	0x08, 0xad, 0xef, 0x08, 0xad, 0xd6, 0x00, 0x9c, 0xd6, 0x19, 0x7b, 0xbd,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x84, 0xbd, 0x19, 0x94, 0xce, 0x00, 0xbd, 0xf7,
+	0x19, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd,
+	0xef, 0x00, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x10, 0xc5,
+	0xef, 0x08, 0xad, 0xef,
+	0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef,
+	0x00, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00,
+	0xbd, 0xf7, 0x19, 0xbd,
+	0xf7, 0x00, 0xbd, 0xef, 0x08, 0xad, 0xd6, 0x08, 0xad, 0xd6, 0x10, 0x52,
+	0x7b, 0x3a, 0x31, 0x4a,
+	0xef, 0xf7, 0xe6, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6,
+	0xff, 0xff, 0xff, 0xef,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xef, 0xf7, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xce, 0xde, 0xce,
+	0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x08, 0x08, 0x10, 0x10,
+	0x52, 0x7b, 0x00, 0x84,
+	0xbd, 0x00, 0x9c, 0xd6, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x00, 0xbd,
+	0xf7, 0x10, 0xc5, 0xef,
+	0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x00, 0xbd, 0xf7,
+	0x19, 0xbd, 0xf7, 0x00,
+	0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x00,
+	0xbd, 0xf7, 0x00, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd,
+	0xef, 0x08, 0xad, 0xef,
+	0x08, 0xad, 0xef, 0x19, 0x94, 0xce, 0x19, 0x94, 0xce, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x19, 0x7b, 0xbd, 0x00, 0x84, 0xbd, 0x08, 0xad, 0xef,
+	0x10, 0xc5, 0xef, 0x00,
+	0xbd, 0xef, 0x08, 0xad, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd,
+	0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x08, 0xad,
+	0xef, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x10,
+	0xc5, 0xef, 0x00, 0xbd,
+	0xf7, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x08, 0xad, 0xd6, 0x00, 0x9c,
+	0xd6, 0x10, 0x7b, 0x9c,
+	0x08, 0x31, 0x5a, 0x00, 0x00, 0x00, 0x4a, 0x5a, 0x73, 0xce, 0xde, 0xce,
+	0xef, 0xf7, 0xe6, 0xff,
+	0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xef, 0xf7,
+	0xe6, 0xef, 0xf7, 0xff, 0xef, 0xf7, 0xe6, 0xa5, 0xb5, 0xb5, 0x6b, 0x5a,
+	0x73, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x31, 0x3a, 0x10, 0x52,
+	0x7b, 0x19, 0x7b, 0xbd, 0x00, 0x9c, 0xd6, 0x08, 0xad, 0xef, 0x10, 0xc5,
+	0xef, 0x19, 0xbd, 0xf7,
+	0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7,
+	0x08, 0xad, 0xef, 0x10,
+	0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd,
+	0xef, 0x19, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x08, 0xad,
+	0xef, 0x08, 0xad, 0xef,
+	0x19, 0x94, 0xce, 0x00, 0x9c, 0xd6, 0x19, 0x7b, 0xbd, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0xbd, 0x00, 0x9c, 0xd6,
+	0x19, 0x94, 0xce, 0x08,
+	0xad, 0xef, 0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x00,
+	0xbd, 0xf7, 0x10, 0xc5,
+	0xef, 0x08, 0xad, 0xef, 0x00, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x00, 0xbd,
+	0xf7, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef,
+	0x00, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x19,
+	0xbd, 0xf7, 0x08, 0xad,
+	0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x08, 0xad,
+	0xd6, 0x19, 0x94, 0xce,
+	0x00, 0x84, 0xbd, 0x10, 0x52, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x08, 0x10, 0x10, 0x29, 0x19, 0x31, 0x31, 0x29, 0x31,
+	0x31, 0x29, 0x08, 0x08,
+	0x10, 0x08, 0x08, 0x10, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x31,
+	0x3a, 0x10, 0x52, 0x7b, 0x00, 0x84, 0xbd, 0x00, 0x9c, 0xd6, 0x08, 0xad,
+	0xef, 0x10, 0xc5, 0xef,
+	0x08, 0xad, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19,
+	0xbd, 0xf7, 0x08, 0xad,
+	0xef, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x08, 0xad,
+	0xef, 0x00, 0x84, 0xbd,
+	0x19, 0x94, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0xbd,
+	0x19, 0x94, 0xce, 0x00,
+	0x9c, 0xd6, 0x00, 0x9c, 0xd6, 0x08, 0xad, 0xef, 0x08, 0xad, 0xd6, 0x08,
+	0xad, 0xef, 0x08, 0xad,
+	0xef, 0x08, 0xad, 0xef, 0x08, 0xad, 0xef, 0x19, 0xbd, 0xf7, 0x08, 0xad,
+	0xef, 0x08, 0xad, 0xef,
+	0x19, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd,
+	0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x10, 0xc5, 0xef, 0x08, 0xad,
+	0xef, 0x08, 0xad, 0xef,
+	0x00, 0x9c, 0xd6, 0x10, 0x5a, 0x9c, 0x10, 0x52, 0x7b, 0x08, 0x31, 0x3a,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0x10, 0x08, 0x00, 0x00, 0x08,
+	0x08, 0x10, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x31, 0x5a, 0x10, 0x5a, 0x9c, 0x00, 0x84, 0xbd, 0x19, 0x94,
+	0xce, 0x08, 0xad, 0xef,
+	0x08, 0xad, 0xef, 0x00, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7,
+	0x00, 0xbd, 0xf7, 0x10,
+	0xc5, 0xef, 0x00, 0xbd, 0xf7, 0x19, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x10,
+	0xc5, 0xef, 0x00, 0xbd,
+	0xef, 0x08, 0xad, 0xef, 0x08, 0xad, 0xef, 0x19, 0x94, 0xce, 0x00, 0x9c,
+	0xd6, 0x00, 0x84, 0xbd,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x10, 0x7b, 0x9c, 0x00,
+	0x84, 0xbd, 0x00, 0x84, 0xbd, 0x19, 0x94, 0xce, 0x00, 0x84, 0xbd, 0x19,
+	0x94, 0xce, 0x00, 0x9c,
+	0xd6, 0x19, 0x94, 0xce, 0x00, 0x9c, 0xd6, 0x08, 0xad, 0xd6, 0x08, 0xad,
+	0xef, 0x08, 0xad, 0xd6,
+	0x08, 0xad, 0xef, 0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef,
+	0x10, 0xc5, 0xef, 0x08,
+	0xad, 0xef, 0x19, 0xbd, 0xf7, 0x00, 0xbd, 0xf7, 0x00, 0xbd, 0xef, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd,
+	0xef, 0x10, 0xc5, 0xef, 0x19, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x00, 0xbd,
+	0xf7, 0x08, 0xad, 0xd6,
+	0x19, 0x94, 0xce, 0x00, 0x84, 0xbd, 0x10, 0x7b, 0x9c, 0x10, 0x52, 0x7b,
+	0x08, 0x31, 0x5a, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x31, 0x3a, 0x10, 0x52, 0x7b, 0x00, 0x84,
+	0xbd, 0x00, 0x84, 0xbd,
+	0x08, 0xad, 0xd6, 0x08, 0xad, 0xef, 0x19, 0xbd, 0xf7, 0x10, 0xc5, 0xef,
+	0x00, 0xbd, 0xf7, 0x10,
+	0xc5, 0xef, 0x08, 0xad, 0xef, 0x19, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x00,
+	0xbd, 0xf7, 0x08, 0xad,
+	0xef, 0x19, 0x94, 0xce, 0x08, 0xad, 0xd6, 0x00, 0x9c, 0xd6, 0x00, 0x9c,
+	0xd6, 0x10, 0x5a, 0x9c,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x5a, 0x9c, 0x10, 0x5a, 0x9c, 0x10,
+	0x5a, 0x9c, 0x00, 0x84,
+	0xbd, 0x19, 0x7b, 0xbd, 0x00, 0x84, 0xbd, 0x00, 0x84, 0xbd, 0x19, 0x94,
+	0xce, 0x00, 0x84, 0xbd,
+	0x19, 0x94, 0xce, 0x00, 0x9c, 0xd6, 0x19, 0x94, 0xce, 0x08, 0xad, 0xef,
+	0x19, 0x94, 0xce, 0x08,
+	0xad, 0xef, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x00, 0xbd, 0xef, 0x19,
+	0xbd, 0xf7, 0x00, 0xbd,
+	0xef, 0x19, 0xbd, 0xf7, 0x08, 0xad, 0xef, 0x00, 0xbd, 0xf7, 0x10, 0xc5,
+	0xef, 0x08, 0xad, 0xef,
+	0x08, 0xad, 0xef, 0x00, 0x84, 0xbd, 0x00, 0x84, 0xbd, 0x10, 0x5a, 0x9c,
+	0x10, 0x52, 0x7b, 0x08,
+	0x31, 0x3a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x31, 0x5a, 0x10, 0x52,
+	0x7b, 0x00, 0x84, 0xbd,
+	0x00, 0x84, 0xbd, 0x19, 0x94, 0xce, 0x08, 0xad, 0xd6, 0x08, 0xad, 0xef,
+	0x19, 0xbd, 0xf7, 0x08,
+	0xad, 0xef, 0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x00,
+	0xbd, 0xef, 0x08, 0xad,
+	0xef, 0x19, 0x94, 0xce, 0x08, 0xad, 0xef, 0x00, 0x84, 0xbd, 0x00, 0x84,
+	0xbd, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x10, 0x73, 0x7b, 0x10, 0x5a, 0x9c, 0x10, 0x7b,
+	0x9c, 0x10, 0x5a, 0xbd,
+	0x00, 0x84, 0xbd, 0x10, 0x7b, 0x9c, 0x00, 0x84, 0xbd, 0x00, 0x84, 0xbd,
+	0x00, 0x84, 0xbd, 0x00,
+	0x84, 0xbd, 0x00, 0x84, 0xbd, 0x19, 0x94, 0xce, 0x00, 0x9c, 0xd6, 0x08,
+	0xad, 0xef, 0x08, 0xad,
+	0xef, 0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x08, 0xad,
+	0xef, 0x08, 0xad, 0xef,
+	0x08, 0xad, 0xd6, 0x19, 0x94, 0xce, 0x00, 0x84, 0xbd, 0x10, 0x5a, 0x9c,
+	0x10, 0x52, 0x7b, 0x10,
+	0x52, 0x7b, 0x08, 0x31, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x10, 0x21, 0x00, 0x08,
+	0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x31,
+	0x3a, 0x10, 0x52, 0x7b,
+	0x10, 0x5a, 0x9c, 0x00, 0x84, 0xbd, 0x00, 0x84, 0xbd, 0x08, 0xad, 0xef,
+	0x08, 0xad, 0xd6, 0x08,
+	0xad, 0xef, 0x08, 0xad, 0xef, 0x10, 0xc5, 0xef, 0x08, 0xad, 0xef, 0x08,
+	0xad, 0xef, 0x19, 0x94,
+	0xce, 0x00, 0x9c, 0xd6, 0x00, 0x84, 0xbd, 0x19, 0x7b, 0xbd, 0x10, 0x5a,
+	0x9c, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x10, 0x5a, 0x9c, 0x10, 0x52, 0x7b, 0x10, 0x5a, 0x9c,
+	0x10, 0x5a, 0x9c, 0x10,
+	0x5a, 0x9c, 0x10, 0x5a, 0x9c, 0x10, 0x7b, 0x9c, 0x00, 0x84, 0xbd, 0x00,
+	0x84, 0xbd, 0x19, 0x94,
+	0xce, 0x00, 0x9c, 0xd6, 0x19, 0x94, 0xce, 0x00, 0x9c, 0xd6, 0x08, 0xad,
+	0xef, 0x08, 0xad, 0xd6,
+	0x19, 0x94, 0xce, 0x00, 0x84, 0xbd, 0x00, 0x84, 0xbd, 0x10, 0x5a, 0x9c,
+	0x10, 0x52, 0x7b, 0x10,
+	0x52, 0x7b, 0x08, 0x31, 0x5a, 0x08, 0x08, 0x10, 0x08, 0x08, 0x10, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x31, 0x3a,
+	0x08, 0x31, 0x5a, 0x10, 0x5a, 0x9c, 0x10, 0x5a, 0x9c, 0x19, 0x7b, 0xbd,
+	0x00, 0x84, 0xbd, 0x00,
+	0x9c, 0xd6, 0x08, 0xad, 0xd6, 0x19, 0x94, 0xce, 0x00, 0x9c, 0xd6, 0x19,
+	0x94, 0xce, 0x00, 0x9c,
+	0xd6, 0x00, 0x84, 0xbd, 0x00, 0x84, 0xbd, 0x00, 0x84, 0xbd, 0x10, 0x5a,
+	0x9c, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x10, 0x52, 0x7b, 0x10, 0x52, 0x7b, 0x10, 0x5a, 0x9c, 0x10,
+	0x5a, 0x9c, 0x10, 0x5a,
+	0x9c, 0x10, 0x5a, 0x9c, 0x10, 0x7b, 0x9c, 0x00, 0x84, 0xbd, 0x19, 0x7b,
+	0xbd, 0x00, 0x84, 0xbd,
+	0x19, 0x7b, 0xbd, 0x00, 0x84, 0xbd, 0x00, 0x84, 0xbd, 0x10, 0x5a, 0x9c,
+	0x10, 0x52, 0x7b, 0x10,
+	0x52, 0x7b, 0x08, 0x31, 0x5a, 0x08, 0x31, 0x5a, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08, 0x31, 0x5a, 0x10, 0x5a, 0x9c, 0x10, 0x7b, 0x9c,
+	0x00, 0x84, 0xbd, 0x00,
+	0x84, 0xbd, 0x19, 0x7b, 0xbd, 0x00, 0x84, 0xbd, 0x00, 0x84, 0xbd, 0x00,
+	0x84, 0xbd, 0x00, 0x84,
+	0xbd, 0x19, 0x7b, 0xbd, 0x10, 0x7b, 0x9c, 0x10, 0x5a, 0x9c, 0x10, 0x52,
+	0x7b, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x31, 0x5a, 0x10, 0x52, 0x7b, 0x10, 0x52, 0x7b, 0x10, 0x5a,
+	0x9c, 0x10, 0x73, 0x7b,
+	0x10, 0x5a, 0x9c, 0x10, 0x5a, 0x9c, 0x10, 0x5a, 0x9c, 0x10, 0x52, 0x7b,
+	0x10, 0x52, 0x7b, 0x10,
+	0x52, 0x7b, 0x08, 0x31, 0x5a, 0x08, 0x31, 0x3a, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x31, 0x5a, 0x08, 0x31, 0x5a,
+	0x10, 0x52, 0x7b, 0x10,
+	0x5a, 0x9c, 0x10, 0x5a, 0x9c, 0x10, 0x7b, 0x9c, 0x10, 0x5a, 0x9c, 0x00,
+	0x84, 0xbd, 0x00, 0x84,
+	0xbd, 0x10, 0x7b, 0x9c, 0x10, 0x5a, 0x9c, 0x10, 0x5a, 0x9c, 0x08, 0x31,
+	0x5a, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x31,
+	0x5a, 0x10, 0x52, 0x7b,
+	0x08, 0x31, 0x5a, 0x10, 0x52, 0x7b, 0x10, 0x52, 0x7b, 0x08, 0x31, 0x5a,
+	0x10, 0x52, 0x7b, 0x08,
+	0x31, 0x5a, 0x08, 0x31, 0x5a, 0x08, 0x31, 0x3a, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x31, 0x5a, 0x08,
+	0x31, 0x5a, 0x10, 0x52, 0x7b, 0x10, 0x5a, 0x9c, 0x10, 0x5a, 0x9c, 0x10,
+	0x5a, 0x9c, 0x10, 0x5a,
+	0x9c, 0x10, 0x5a, 0x9c, 0x10, 0x52, 0x7b, 0x10, 0x52, 0x7b, 0x08, 0x31,
+	0x5a, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x31, 0x5a, 0x08, 0x31, 0x5a,
+	0x08, 0x31, 0x5a, 0x08,
+	0x31, 0x5a, 0x08, 0x31, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x31, 0x3a, 0x08, 0x31, 0x5a, 0x08,
+	0x31, 0x5a, 0x10, 0x52,
+	0x7b, 0x08, 0x31, 0x5a, 0x08, 0x31, 0x5a, 0x08, 0x31, 0x3a, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+};
+
+#endif
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index d9b1ef7..4640d3b 100755
--- 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
@@ -454,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..1740576 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -352,6 +352,9 @@
 #define MMC_QUIRK_INAND_DATA_TIMEOUT  (1<<8)    /* For incorrect data timeout */
 /* To avoid eMMC device getting broken permanently due to HPI feature */
 #define MMC_QUIRK_BROKEN_HPI (1 << 11)
+ /* Skip data-timeout advertised by card */
+#define MMC_QUIRK_BROKEN_DATA_TIMEOUT	(1<<12)
+
 
 	unsigned int		erase_size;	/* erase size in sectors */
  	unsigned int		erase_shift;	/* if erase unit is power 2 */
@@ -392,7 +395,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/msm_mdp.h b/include/linux/msm_mdp.h
index 724e573..121a00c 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -422,7 +422,7 @@
 	uint32_t val_region;
 };
 
-#define MDP_SIX_ZONE_TABLE_NUM		384
+#define MDP_SIX_ZONE_LUT_SIZE		384
 
 struct mdp_pa_v2_data {
 	/* Mask bits for PA features */
@@ -431,12 +431,13 @@
 	uint32_t global_sat_adj;
 	uint32_t global_val_adj;
 	uint32_t global_cont_adj;
-	uint32_t *six_zone_curve_p0;
-	uint32_t *six_zone_curve_p1;
-	uint32_t six_zone_thresh;
 	struct mdp_pa_mem_col_cfg skin_cfg;
 	struct mdp_pa_mem_col_cfg sky_cfg;
 	struct mdp_pa_mem_col_cfg fol_cfg;
+	uint32_t six_zone_len;
+	uint32_t six_zone_thresh;
+	uint32_t *six_zone_curve_p0;
+	uint32_t *six_zone_curve_p1;
 };
 
 struct mdp_igc_lut_data {
@@ -800,8 +801,14 @@
 	DCM_ENTER,
 	DCM_EXIT,
 	DCM_BLANK,
+	DTM_ENTER,
+	DTM_EXIT,
 };
 
+#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/qpnp/power-on.h b/include/linux/qpnp/power-on.h
index 772bf62..ae4e731 100644
--- a/include/linux/qpnp/power-on.h
+++ b/include/linux/qpnp/power-on.h
@@ -52,6 +52,7 @@
 int qpnp_pon_system_pwr_off(enum pon_power_off_type type);
 int qpnp_pon_is_warm_reset(void);
 int qpnp_pon_trigger_config(enum pon_trigger_source pon_src, bool enable);
+int qpnp_pon_wd_config(bool enable);
 #else
 static int qpnp_pon_system_pwr_off(enum pon_power_off_type type)
 {
@@ -63,6 +64,10 @@
 {
 	return -ENODEV;
 }
+int qpnp_pon_wd_config(bool enable)
+{
+	return -ENODEV;
+}
 #endif
 
 #endif
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/qpnp/qpnp-adc.h b/include/linux/qpnp/qpnp-adc.h
index 6e711c2..e6dcc3b 100644
--- a/include/linux/qpnp/qpnp-adc.h
+++ b/include/linux/qpnp/qpnp-adc.h
@@ -220,6 +220,8 @@
  *			btm parameters.
  * %SCALE_QRD_SKUAA_BATT_THERM: Conversion to temperature(decidegC) based on
  *          btm parametersi for SKUAA.
+ * %SCALE_QRD_SKUG_BATT_THERM: Conversion to temperature(decidegC) based on
+ * btm parametersi for SKUG.
  * %SCALE_NONE: Do not use this scaling type.
  */
 enum qpnp_adc_scale_fn_type {
@@ -231,6 +233,7 @@
 	SCALE_THERM_150K_PULLUP,
 	SCALE_QRD_BATT_THERM,
 	SCALE_QRD_SKUAA_BATT_THERM,
+	SCALE_QRD_SKUG_BATT_THERM = 9,
 	SCALE_NONE,
 };
 
@@ -1135,6 +1138,23 @@
 			const struct qpnp_vadc_chan_properties *chan_prop,
 			struct qpnp_vadc_result *chan_rslt);
 /**
+ * qpnp_adc_scale_qrd_skug_batt_therm() - Scales the pre-calibrated digital output
+ *		of an ADC to the ADC reference and compensates for the
+ *		gain and offset. Returns the temperature in decidegC.
+ * @dev:	Structure device for qpnp vadc
+ * @adc_code:	pre-calibrated digital ouput of the ADC.
+ * @adc_prop:	adc properties of the pm8xxx adc such as bit resolution,
+ *		reference voltage.
+ * @chan_prop:	individual channel properties to compensate the i/p scaling,
+ *		slope and offset.
+ * @chan_rslt:	physical result to be stored.
+ */
+int32_t qpnp_adc_scale_qrd_skug_batt_therm(struct qpnp_vadc_chip *dev,
+			int32_t adc_code,
+			const struct qpnp_adc_properties *adc_prop,
+			const struct qpnp_vadc_chan_properties *chan_prop,
+			struct qpnp_vadc_result *chan_rslt);
+/**
  * qpnp_adc_scale_batt_id() - Scales the pre-calibrated digital output
  *		of an ADC to the ADC reference and compensates for the
  *		gain and offset.
@@ -1388,6 +1408,12 @@
 			const struct qpnp_vadc_chan_properties *chan_prop,
 			struct qpnp_vadc_result *chan_rslt)
 { return -ENXIO; }
+static inline int32_t qpnp_adc_scale_qrd_skug_batt_therm(
+			struct qpnp_vadc_chip *vadc, int32_t adc_code,
+			const struct qpnp_adc_properties *adc_prop,
+			const struct qpnp_vadc_chan_properties *chan_prop,
+			struct qpnp_vadc_result *chan_rslt)
+{ return -ENXIO; }
 static inline int32_t qpnp_adc_scale_batt_id(struct qpnp_vadc_chip *vadc,
 			int32_t adc_code,
 			const struct qpnp_adc_properties *adc_prop,
diff --git a/include/linux/regulator/cpr-regulator.h b/include/linux/regulator/cpr-regulator.h
index 624860e..3b23d17 100644
--- a/include/linux/regulator/cpr-regulator.h
+++ b/include/linux/regulator/cpr-regulator.h
@@ -16,26 +16,57 @@
 
 #include <linux/regulator/machine.h>
 
-#define CPR_REGULATOR_DRIVER_NAME	"qti,cpr-regulator"
+#define CPR_REGULATOR_DRIVER_NAME	"qcom,cpr-regulator"
 
 #define CPR_PVS_EFUSE_BITS_MAX		5
 #define CPR_PVS_EFUSE_BINS_MAX		(1 << CPR_PVS_EFUSE_BITS_MAX)
 
 /**
+ * enum cpr_fuse_corner_enum - CPR fuse corner enum values
+ * %CPR_FUSE_CORNER_SVS:		Lowest voltage for APC
+ * %CPR_FUSE_CORNER_NORMAL:		Normal mode voltage
+ * %CPR_FUSE_CORNER_TURBO:		Turbo mode voltage
+ * %CPR_FUSE_CORNER_SUPER_TURBO:	Super Turbo mode voltage
+ *
+ */
+enum cpr_fuse_corner_enum {
+	CPR_FUSE_CORNER_SVS = 1,
+	CPR_FUSE_CORNER_NORMAL,
+	CPR_FUSE_CORNER_TURBO,
+	CPR_FUSE_CORNER_MAX,
+};
+
+/**
  * enum cpr_corner_enum - CPR corner enum values
- * %CPR_CORNER_SVS:		Lowest voltage for APC
- * %CPR_CORNER_NORMAL:		Normal mode voltage
- * %CPR_CORNER_TURBO:		Turbo mode voltage
- * %CPR_CORNER_SUPER_TURBO:	Super Turbo mode voltage
+ * %CPR_CORNER_1:		Lowest voltage for APC
+ * %CPR_CORNER_2:		Second lowest voltage for APC
+ * %CPR_CORNER_3:		Third lowest voltage for APC
+ * %CPR_CORNER_4:		Forth lowest voltage for APC
+ * %CPR_CORNER_5:		Fifth lowest voltage for APC
+ * %CPR_CORNER_6:		Sixth lowest voltage for APC
+ * %CPR_CORNER_7:		Seventh lowest voltage for APC
+ * %CPR_CORNER_8:		Eighth lowest voltage for APC
+ * %CPR_CORNER_9:		Ninth lowest voltage for APC
+ * %CPR_CORNER_10:		Tenth lowest voltage for APC
+ * %CPR_CORNER_11:		Eleventh lowest voltage for APC
+ * %CPR_CORNER_12:		Twelfth lowest voltage for APC
  *
  * These should be used in regulator_set_voltage() for CPR
  * regulator as if they had units of uV.
  */
 enum cpr_corner_enum {
-	CPR_CORNER_SVS = 1,
-	CPR_CORNER_NORMAL,
-	CPR_CORNER_TURBO,
-	CPR_CORNER_MAX,
+	CPR_CORNER_1 = 1,
+	CPR_CORNER_2,
+	CPR_CORNER_3,
+	CPR_CORNER_4,
+	CPR_CORNER_5,
+	CPR_CORNER_6,
+	CPR_CORNER_7,
+	CPR_CORNER_8,
+	CPR_CORNER_9,
+	CPR_CORNER_10,
+	CPR_CORNER_11,
+	CPR_CORNER_12,
 };
 
 /**
diff --git a/include/linux/sensors.h b/include/linux/sensors.h
index 3520034..96d2aa6 100644
--- a/include/linux/sensors.h
+++ b/include/linux/sensors.h
@@ -47,9 +47,37 @@
 #define SENSOR_TYPE_STEP_COUNTER		19
 #define SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR	20
 
+/**
+ * struct sensors_classdev - hold the sensor general parameters and APIs
+ * @dev:		The device to register.
+ * @node:		The list for the all the sensor drivers.
+ * @name:		Name of this sensor.
+ * @vendor:		The vendor of the hardware part.
+ * @handle:		The handle that identifies this sensors.
+ * @type:		The sensor type.
+ * @max_range:		The maximum range of this sensor's value in SI units.
+ * @resolution:		The smallest difference between two values reported by
+ *			this sensor.
+ * @sensor_power:	The rough estimate of this sensor's power consumption
+ *			in mA.
+ * @min_delay:		This value depends on the trigger mode:
+ *			continuous: minimum period allowed in microseconds
+ *			on-change : 0
+ *			one-shot :-1
+ *			special : 0, unless otherwise noted
+ * @fifo_reserved_event_count:	The number of events reserved for this sensor
+ *				in the batch mode FIFO.
+ * @fifo_max_event_count:	The maximum number of events of this sensor
+ *				that could be batched.
+ * @enabled:		Store the sensor driver enable status.
+ * @delay_msec:		Store the sensor driver delay value. The data unit is
+ *			millisecond.
+ * @sensors_enable:	The handle for enable and disable sensor.
+ * @sensors_poll_delay:	The handle for set the sensor polling delay time.
+ */
 struct sensors_classdev {
 	struct device		*dev;
-	struct list_head	 node;
+	struct list_head	node;
 	const char		*name;
 	const char		*vendor;
 	int			version;
@@ -61,6 +89,13 @@
 	int			min_delay;
 	int			fifo_reserved_event_count;
 	int			fifo_max_event_count;
+	unsigned int		enabled;
+	unsigned int		delay_msec;
+	/* enable and disable the sensor handle*/
+	int	(*sensors_enable)(struct sensors_classdev *sensors_cdev,
+					unsigned int enabled);
+	int	(*sensors_poll_delay)(struct sensors_classdev *sensors_cdev,
+					unsigned int delay_msec);
 };
 
 extern int sensors_classdev_register(struct device *parent,
diff --git a/include/linux/slimbus/slimbus.h b/include/linux/slimbus/slimbus.h
index c940091..67f4d8c 100644
--- a/include/linux/slimbus/slimbus.h
+++ b/include/linux/slimbus/slimbus.h
@@ -586,6 +586,9 @@
  * @device_down: This callback is called when device reports absent, or the
  *		bus goes down. Device will report present when bus is up and
  *		device_up callback will be called again when that happens
+ * @reset_device: This callback is called after framer is booted.
+ *		Driver should do the needful to reset the device,
+ *		so that device acquires sync and be operational.
  * @driver: Slimbus device drivers should initialize name and owner field of
  *	this structure
  * @id_table: List of slimbus devices supported by this driver
@@ -600,6 +603,8 @@
 	int				(*device_up)(struct slim_device *sldev);
 	int				(*device_down)
 						(struct slim_device *sldev);
+	int				(*reset_device)
+						(struct slim_device *sldev);
 
 	struct device_driver		driver;
 	const struct slim_device_id	*id_table;
@@ -1036,6 +1041,16 @@
 void slim_report_absent(struct slim_device *sbdev);
 
 /*
+ * slim_framer_booted: This function is called by controller after the active
+ * framer has booted (using Bus Reset sequence, or after it has shutdown and has
+ * come back up). Components, devices on the bus may be in undefined state,
+ * and this function triggers their drivers to do the needful
+ * to bring them back in Reset state so that they can acquire sync, report
+ * present and be operational again.
+ */
+void slim_framer_booted(struct slim_controller *ctrl);
+
+/*
  * slim_msg_response: Deliver Message response received from a device to the
  *	framework.
  * @ctrl: Controller handle
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 560accb..51ca67d 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1904,6 +1904,11 @@
 	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)
+#define V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR \
+		(V4L2_CID_MPEG_MSM_VIDC_BASE + 38)
+
 /*  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/linux/vmalloc.h b/include/linux/vmalloc.h
index 7675a5c..500421f 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -136,6 +136,12 @@
 extern __init void vm_area_add_early(struct vm_struct *vm);
 extern __init void vm_area_register_early(struct vm_struct *vm, size_t align);
 extern __init int vm_area_check_early(struct vm_struct *vm);
+#ifdef CONFIG_ENABLE_VMALLOC_SAVING
+extern void mark_vmalloc_reserved_area(void *addr, unsigned long size);
+#else
+static inline void mark_vmalloc_reserved_area(void *addr, unsigned long size)
+{ };
+#endif
 
 #ifdef CONFIG_SMP
 # ifdef CONFIG_MMU
diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h
index c48586e..38d3aab 100644
--- a/include/media/msm_cam_sensor.h
+++ b/include/media/msm_cam_sensor.h
@@ -482,6 +482,7 @@
 	int8_t sign_dir;
 	int16_t dest_step_pos;
 	int32_t num_steps;
+	uint16_t curr_lens_pos;
 	struct damping_params_t *ringing_params;
 };
 
@@ -571,7 +572,8 @@
 
 struct msm_camera_led_cfg_t {
 	enum msm_camera_led_config_t cfgtype;
-	uint32_t led_current;
+	uint32_t torch_current;
+	uint32_t flash_current[2];
 };
 
 #define VIDIOC_MSM_SENSOR_CFG \
diff --git a/include/media/msmb_generic_buf_mgr.h b/include/media/msmb_generic_buf_mgr.h
index efcb425..237380f 100644
--- a/include/media/msmb_generic_buf_mgr.h
+++ b/include/media/msmb_generic_buf_mgr.h
@@ -20,4 +20,10 @@
 #define VIDIOC_MSM_BUF_MNGR_BUF_DONE \
 	_IOWR('V', BASE_VIDIOC_PRIVATE + 35, struct msm_buf_mngr_info)
 
+#define VIDIOC_MSM_BUF_MNGR_INIT \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 36, struct msm_buf_mngr_info)
+
+#define VIDIOC_MSM_BUF_MNGR_DEINIT \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 37, struct msm_buf_mngr_info)
+
 #endif
diff --git a/include/media/msmb_isp.h b/include/media/msmb_isp.h
index 568a3fa..3ba0abe 100644
--- a/include/media/msmb_isp.h
+++ b/include/media/msmb_isp.h
@@ -228,6 +228,7 @@
 	VFE_READ_DMI_32BIT,
 	VFE_READ_DMI_64BIT,
 	GET_SOC_HW_VER,
+	GET_MAX_CLK_RATE,
 };
 
 struct msm_vfe_cfg_cmd2 {
diff --git a/include/media/radio-iris.h b/include/media/radio-iris.h
index d28a8c0..a69f3f1 100644
--- a/include/media/radio-iris.h
+++ b/include/media/radio-iris.h
@@ -32,6 +32,50 @@
 #include <linux/mutex.h>
 #include <linux/atomic.h>
 #include "radio-iris-commands.h"
+const unsigned char MIN_TX_TONE_VAL = 0x00;
+const unsigned char MAX_TX_TONE_VAL = 0x07;
+const unsigned char MIN_HARD_MUTE_VAL = 0x00;
+const unsigned char MAX_HARD_MUTE_VAL = 0x03;
+const unsigned char MIN_SRCH_MODE = 0x00;
+const unsigned char MAX_SRCH_MODE = 0x01;
+const unsigned char MIN_SCAN_DWELL = 0x00;
+const unsigned char MAX_SCAN_DWELL = 0x0F;
+const unsigned char MIN_SIG_TH = 0x00;
+const unsigned char MAX_SIG_TH = 0x03;
+const unsigned char MIN_PTY = 0X00;
+const unsigned char MAX_PTY = 0x1F;
+const unsigned short MIN_PI = 0x0000;
+const unsigned short MAX_PI = 0xFFFF;
+const unsigned char MIN_SRCH_STATIONS_CNT = 0x00;
+const unsigned char MAX_SRCH_STATIONS_CNT = 0x14;
+const unsigned char MIN_CHAN_SPACING = 0x00;
+const unsigned char MAX_CHAN_SPACING = 0x02;
+const unsigned char MIN_EMPHASIS = 0x00;
+const unsigned char MAX_EMPHASIS = 0x01;
+const unsigned char MIN_RDS_STD = 0x00;
+const unsigned char MAX_RDS_STD = 0x02;
+const unsigned char MIN_ANTENNA_VAL = 0x00;
+const unsigned char MAX_ANTENNA_VAL = 0x01;
+const unsigned char MIN_TX_PS_REPEAT_CNT = 0x01;
+const unsigned char MAX_TX_PS_REPEAT_CNT = 0x0F;
+const unsigned char MIN_SOFT_MUTE = 0x00;
+const unsigned char MAX_SOFT_MUTE = 0x01;
+const unsigned char MIN_PEEK_ACCESS_LEN = 0x01;
+const unsigned char MAX_PEEK_ACCESS_LEN = 0xF9;
+const unsigned char MIN_RESET_CNTR = 0x00;
+const unsigned char MAX_RESET_CNTR = 0x01;
+const unsigned char MIN_HLSI = 0x00;
+const unsigned char MAX_HLSI = 0x02;
+const unsigned char MIN_NOTCH_FILTER = 0x00;
+const unsigned char MAX_NOTCH_FILTER = 0x02;
+const unsigned char MIN_INTF_DET_OUT_LW_TH = 0x00;
+const unsigned char MAX_INTF_DET_OUT_LW_TH = 0xFF;
+const unsigned char MIN_INTF_DET_OUT_HG_TH = 0x00;
+const unsigned char MAX_INTF_DET_OUT_HG_TH = 0xFF;
+const signed char MIN_SINR_TH = -128;
+const signed char MAX_SINR_TH = 127;
+const unsigned char MIN_SINR_SAMPLES = 0x01;
+const unsigned char MAX_SINR_SAMPLES = 0xFF;
 
 /* ---- HCI Packet structures ---- */
 #define RADIO_HCI_COMMAND_HDR_SIZE sizeof(struct radio_hci_command_hdr)
@@ -630,6 +674,7 @@
 	FM_TURNING_OFF,
 	FM_RECV_TURNING_ON,
 	FM_TRANS_TURNING_ON,
+	FM_MAX_NO_STATES,
 };
 
 enum emphasis_type {
@@ -828,4 +873,209 @@
 int hci_fm_do_calibration(__u8 *arg, struct radio_hci_dev *hdev);
 int hci_fm_do_calibration(__u8 *arg, struct radio_hci_dev *hdev);
 
+static inline int is_valid_tone(int tone)
+{
+	if ((tone >= MIN_TX_TONE_VAL) &&
+		(tone <= MAX_TX_TONE_VAL))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_hard_mute(int hard_mute)
+{
+	if ((hard_mute >= MIN_HARD_MUTE_VAL) &&
+		(hard_mute <= MAX_HARD_MUTE_VAL))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_srch_mode(int srch_mode)
+{
+	if ((srch_mode >= MIN_SRCH_MODE) &&
+		(srch_mode <= MAX_SRCH_MODE))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_scan_dwell_prd(int scan_dwell_prd)
+{
+	if ((scan_dwell_prd >= MIN_SCAN_DWELL) &&
+		(scan_dwell_prd <= MAX_SCAN_DWELL))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_sig_th(int sig_th)
+{
+	if ((sig_th >= MIN_SIG_TH) &&
+		(sig_th <= MAX_SIG_TH))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_pty(int pty)
+{
+	if ((pty >= MIN_PTY) &&
+		(pty <= MAX_PTY))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_pi(int pi)
+{
+	if ((pi >= MIN_PI) &&
+		(pi <= MAX_PI))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_srch_station_cnt(int cnt)
+{
+	if ((cnt >= MIN_SRCH_STATIONS_CNT) &&
+		(cnt <= MAX_SRCH_STATIONS_CNT))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_chan_spacing(int spacing)
+{
+	if ((spacing >= MIN_CHAN_SPACING) &&
+		(spacing <= MAX_CHAN_SPACING))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_emphasis(int emphasis)
+{
+	if ((emphasis >= MIN_EMPHASIS) &&
+		(emphasis <= MAX_EMPHASIS))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_rds_std(int rds_std)
+{
+	if ((rds_std >= MIN_RDS_STD) &&
+		(rds_std <= MAX_RDS_STD))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_antenna(int antenna_type)
+{
+	if ((antenna_type >= MIN_ANTENNA_VAL) &&
+		(antenna_type <= MAX_ANTENNA_VAL))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_ps_repeat_cnt(int cnt)
+{
+	if ((cnt >= MIN_TX_PS_REPEAT_CNT) &&
+		(cnt <= MAX_TX_PS_REPEAT_CNT))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_soft_mute(int soft_mute)
+{
+	if ((soft_mute >= MIN_SOFT_MUTE) &&
+		(soft_mute <= MAX_SOFT_MUTE))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_peek_len(int len)
+{
+	if ((len >= MIN_PEEK_ACCESS_LEN) &&
+		(len <= MAX_PEEK_ACCESS_LEN))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_reset_cntr(int cntr)
+{
+	if ((cntr >= MIN_RESET_CNTR) &&
+		(cntr <= MAX_RESET_CNTR))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_hlsi(int hlsi)
+{
+	if ((hlsi >= MIN_HLSI) &&
+		(hlsi <= MAX_HLSI))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_notch_filter(int filter)
+{
+	if ((filter >= MIN_NOTCH_FILTER) &&
+		(filter <= MAX_NOTCH_FILTER))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_intf_det_low_th(int th)
+{
+	if ((th >= MIN_INTF_DET_OUT_LW_TH) &&
+		(th <= MAX_INTF_DET_OUT_LW_TH))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_intf_det_hgh_th(int th)
+{
+	if ((th >= MIN_INTF_DET_OUT_HG_TH) &&
+		(th <= MAX_INTF_DET_OUT_HG_TH))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_sinr_th(int th)
+{
+	if ((th >= MIN_SINR_TH) &&
+		(th <= MAX_SINR_TH))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_sinr_samples(int samples_cnt)
+{
+	if ((samples_cnt >= MIN_SINR_SAMPLES) &&
+		(samples_cnt <= MAX_SINR_SAMPLES))
+		return 1;
+	else
+		return 0;
+}
+
+static inline int is_valid_fm_state(int state)
+{
+	if ((state >= 0) && (state < FM_MAX_NO_STATES))
+		return 1;
+	else
+		return 0;
+}
 #endif /* __RADIO_HCI_CORE_H */
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/q6adm-v2.h b/include/sound/q6adm-v2.h
index 6f121b3..5941f71 100644
--- a/include/sound/q6adm-v2.h
+++ b/include/sound/q6adm-v2.h
@@ -31,7 +31,7 @@
 int srs_trumedia_open(int port_id, int srs_tech_id, void *srs_params);
 
 int adm_open(int port, int path, int rate, int mode, int topology,
-				bool perf_mode, uint16_t bits_per_sample);
+				int perf_mode, uint16_t bits_per_sample);
 
 int adm_get_params(int port_id, uint32_t module_id, uint32_t param_id,
 			uint32_t params_length, char *params);
@@ -40,7 +40,7 @@
 				 uint32_t params_length);
 
 int adm_multi_ch_copp_open(int port, int path, int rate, int mode,
-			int topology, bool perf_mode, uint16_t bits_per_sample);
+			int topology, int perf_mode, uint16_t bits_per_sample);
 
 int adm_unmap_cal_blocks(void);
 
@@ -53,10 +53,10 @@
 
 int adm_memory_unmap_regions(int port_id);
 
-int adm_close(int port, bool perf_mode);
+int adm_close(int port, int perf_mode);
 
 int adm_matrix_map(int session_id, int path, int num_copps,
-		unsigned int *port_id, int copp_id, bool perf_mode);
+		unsigned int *port_id, int copp_id, int perf_mode);
 
 int adm_connect_afe_port(int mode, int session_id, int port_id);
 
@@ -64,6 +64,8 @@
 
 int adm_get_copp_id(int port_id);
 
+int adm_get_lowlatency_copp_id(int port_id);
+
 void adm_set_multi_ch_map(char *channel_map);
 
 void adm_get_multi_ch_map(char *channel_map);
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index 9a459b8..a78c333 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
@@ -173,7 +175,7 @@
 	struct audio_port_data port[2];
 	wait_queue_head_t      cmd_wait;
 	wait_queue_head_t      time_wait;
-	bool                   perf_mode;
+	int                    perf_mode;
 	int					   stream_id;
 	/* audio cache operations fptr*/
 	int (*fptr_cache_ops)(struct audio_buffer *abuff, int cache_op);
@@ -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/q6audio-v2.h b/include/sound/q6audio-v2.h
index fd6a490..8ac835c 100644
--- a/include/sound/q6audio-v2.h
+++ b/include/sound/q6audio-v2.h
@@ -15,6 +15,13 @@
 
 #include <mach/qdsp6v2/apr.h>
 
+enum {
+	LEGACY_PCM_MODE = 0,
+	LOW_LATENCY_PCM_MODE,
+	ULTRA_LOW_LATENCY_PCM_MODE,
+};
+
+
 int q6audio_get_port_index(u16 port_id);
 
 int q6audio_convert_virtual_to_portid(u16 port_id);
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..2e074aa 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
+#define POSSIBLE_VMALLOC_START	PAGE_OFFSET
+
+#define VMALLOC_BITMAP_SIZE	((VMALLOC_END - PAGE_OFFSET) >> \
+					PAGE_SHIFT)
+#define VMALLOC_TO_BIT(addr)	((addr - PAGE_OFFSET) >> PAGE_SHIFT)
+#define BIT_TO_VMALLOC(i)	(PAGE_OFFSET + i * PAGE_SIZE)
+
+DECLARE_BITMAP(possible_areas, VMALLOC_BITMAP_SIZE);
+
+void mark_vmalloc_reserved_area(void *x, unsigned long size)
+{
+	unsigned long addr = (unsigned long)x;
+
+	bitmap_set(possible_areas, VMALLOC_TO_BIT(addr), size >> PAGE_SHIFT);
+}
+
+int is_vmalloc_addr(const void *x)
+{
+	unsigned long addr = (unsigned long)x;
+
+	if (addr < POSSIBLE_VMALLOC_START || addr >= VMALLOC_END)
+		return 0;
+
+	if (test_bit(VMALLOC_TO_BIT(addr), possible_areas))
+		return 0;
+
+	return 1;
+}
+#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/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index fd7a3f6..cfaaf13 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -271,6 +271,11 @@
 	local_bh_disable();
 	addend = xt_write_recseq_begin();
 	private = table->private;
+	/*
+	 * Ensure we load private-> members after we've fetched the base
+	 * pointer.
+	 */
+	smp_read_barrier_depends();
 	table_base = private->entries[smp_processor_id()];
 
 	e = get_entry(table_base, private->hook_entry[hook]);
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 24e556e..ed1468a 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -327,6 +327,11 @@
 	addend = xt_write_recseq_begin();
 	private = table->private;
 	cpu        = smp_processor_id();
+	/*
+	 * Ensure we load private-> members after we've fetched the base
+	 * pointer.
+	 */
+	smp_read_barrier_depends();
 	table_base = private->entries[cpu];
 	jumpstack  = (struct ipt_entry **)private->jumpstack[cpu];
 	stackptr   = per_cpu_ptr(private->stackptr, cpu);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 2628937..74a286c 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -485,14 +485,12 @@
 			 !tp->urg_data ||
 			 before(tp->urg_seq, tp->copied_seq) ||
 			 !before(tp->urg_seq, tp->rcv_nxt)) {
-			struct sk_buff *skb;
 
 			answ = tp->rcv_nxt - tp->copied_seq;
 
-			/* Subtract 1, if FIN is in queue. */
-			skb = skb_peek_tail(&sk->sk_receive_queue);
-			if (answ && skb)
-				answ -= tcp_hdr(skb)->fin;
+			/* Subtract 1, if FIN was received */
+			if (answ && sock_flag(sk, SOCK_DONE))
+				answ--;
 		} else
 			answ = tp->urg_seq - tp->copied_seq;
 		release_sock(sk);
@@ -3443,10 +3441,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/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index e641f8f..c30a20c 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -349,6 +349,11 @@
 	local_bh_disable();
 	addend = xt_write_recseq_begin();
 	private = table->private;
+	/*
+	 * Ensure we load private-> members after we've fetched the base
+	 * pointer.
+	 */
+	smp_read_barrier_depends();
 	cpu        = smp_processor_id();
 	table_base = private->entries[cpu];
 	jumpstack  = (struct ip6t_entry **)private->jumpstack[cpu];
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 8d987c3..5888e00 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -832,8 +832,13 @@
 		return NULL;
 	}
 
-	table->private = newinfo;
 	newinfo->initial_entries = private->initial_entries;
+	/*
+	 * Ensure contents of newinfo are visible before assigning to
+	 * private.
+	 */
+	smp_wmb();
+	table->private = newinfo;
 
 	/*
 	 * Even though table entries have now been swapped, other CPU's
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index bddb720..b094741 100755
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1510,8 +1510,8 @@
 	if (wiphy_idx_valid(reg_request->wiphy_idx))
 		wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx);
 
-	if (reg_initiator == NL80211_REGDOM_SET_BY_DRIVER &&
-	    !wiphy) {
+	if ((reg_initiator == NL80211_REGDOM_SET_BY_DRIVER ||
+	     reg_initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) && !wiphy) {
 		kfree(reg_request);
 		return;
 	}
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/wcd9306.c b/sound/soc/codecs/wcd9306.c
index 4912cf04a..27ea648 100644
--- a/sound/soc/codecs/wcd9306.c
+++ b/sound/soc/codecs/wcd9306.c
@@ -514,31 +514,41 @@
 				struct snd_ctl_elem_value *ucontrol)
 {
 	u8 ear_pa_gain;
+	int rc = 0;
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 
 	ear_pa_gain = snd_soc_read(codec, TAPAN_A_RX_EAR_GAIN);
-
 	ear_pa_gain = ear_pa_gain >> 5;
 
-	if (ear_pa_gain == 0x00) {
-		ucontrol->value.integer.value[0] = 0;
-	} else if (ear_pa_gain == 0x04) {
-		ucontrol->value.integer.value[0] = 1;
-	} else  {
+	switch (ear_pa_gain) {
+	case 0:
+	case 1:
+	case 2:
+	case 3:
+	case 4:
+	case 5:
+		ucontrol->value.integer.value[0] = ear_pa_gain;
+		break;
+	case 7:
+		ucontrol->value.integer.value[0] = (ear_pa_gain - 1);
+		break;
+	default:
+		rc = -EINVAL;
 		pr_err("%s: ERROR: Unsupported Ear Gain = 0x%x\n",
-				__func__, ear_pa_gain);
-		return -EINVAL;
+		       __func__, ear_pa_gain);
+		break;
 	}
 
 	dev_dbg(codec->dev, "%s: ear_pa_gain = 0x%x\n", __func__, ear_pa_gain);
 
-	return 0;
+	return rc;
 }
 
 static int tapan_pa_gain_put(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
 	u8 ear_pa_gain;
+	int rc = 0;
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 
 	dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0]  = %ld\n",
@@ -546,17 +556,24 @@
 
 	switch (ucontrol->value.integer.value[0]) {
 	case 0:
-		ear_pa_gain = 0x00;
-		break;
 	case 1:
-		ear_pa_gain = 0x80;
+	case 2:
+	case 3:
+	case 4:
+	case 5:
+		ear_pa_gain = ucontrol->value.integer.value[0];
+		break;
+	case 6:
+		ear_pa_gain = 0x07;
 		break;
 	default:
-		return -EINVAL;
+		rc = -EINVAL;
+		break;
 	}
-
-	snd_soc_update_bits(codec, TAPAN_A_RX_EAR_GAIN, 0xE0, ear_pa_gain);
-	return 0;
+	if (!rc)
+		snd_soc_update_bits(codec, TAPAN_A_RX_EAR_GAIN,
+				    0xE0, ear_pa_gain << 5);
+	return rc;
 }
 
 static int tapan_get_iir_enable_audio_mixer(
@@ -1017,9 +1034,13 @@
 	return 0;
 }
 
-static const char * const tapan_ear_pa_gain_text[] = {"POS_6_DB", "POS_2_DB"};
+static const char * const tapan_ear_pa_gain_text[] = {"POS_6_DB", "POS_4P5_DB",
+						      "POS_3_DB", "POS_1P5_DB",
+						      "POS_0_DB", "NEG_2P5_DB",
+						      "NEG_12_DB"};
 static const struct soc_enum tapan_ear_pa_gain_enum[] = {
-		SOC_ENUM_SINGLE_EXT(2, tapan_ear_pa_gain_text),
+		SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tapan_ear_pa_gain_text),
+				    tapan_ear_pa_gain_text),
 };
 
 static const char *const tapan_anc_func_text[] = {"OFF", "ON"};
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index c62f875..f874c43 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -3404,6 +3404,7 @@
 					TAIKO_A_TX_7_MBHC_EN, 0x80, 00);
 			ret |= taiko_codec_enable_anc(w, kcontrol, event);
 		}
+		break;
 	case SND_SOC_DAPM_POST_PMD:
 		ret = taiko_hph_pa_event(w, kcontrol, event);
 		break;
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index 28d4c84..a7d1563 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -98,7 +98,7 @@
  * Invalid voltage range for the detection
  * of plug type with current source
  */
-#define WCD9XXX_CS_MEAS_INVALD_RANGE_LOW_MV 110
+#define WCD9XXX_CS_MEAS_INVALD_RANGE_LOW_MV 160
 #define WCD9XXX_CS_MEAS_INVALD_RANGE_HIGH_MV 265
 
 /*
@@ -121,7 +121,7 @@
 #define WCD9XXX_V_CS_HS_MAX 500
 #define WCD9XXX_V_CS_NO_MIC 5
 #define WCD9XXX_MB_MEAS_DELTA_MAX_MV 80
-#define WCD9XXX_CS_MEAS_DELTA_MAX_MV 10
+#define WCD9XXX_CS_MEAS_DELTA_MAX_MV 12
 
 static int impedance_detect_en;
 module_param(impedance_detect_en, int,
@@ -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,
@@ -1339,7 +1352,6 @@
 
 		vdce = __wcd9xxx_codec_sta_dce_v(mbhc, true, d->dce,
 						 dce_z, (u32)mb_mv);
-
 		d->_vdces = vdce;
 		if (d->_vdces < no_mic)
 			d->_type = PLUG_TYPE_HEADPHONE;
@@ -1373,14 +1385,6 @@
 		}
 	}
 
-	if (event_state & (1 << MBHC_EVENT_PA_HPHL)) {
-		pr_debug("%s: HPHL PA was ON\n", __func__);
-	} else if (ch != sz && ch > 0) {
-		pr_debug("%s: Invalid, inconsistent HPHL\n", __func__);
-		type = PLUG_TYPE_INVALID;
-		goto exit;
-	}
-
 	delta_thr = ((highhph_cnt == sz) || highhph) ?
 			      WCD9XXX_MB_MEAS_DELTA_MAX_MV :
 			      WCD9XXX_CS_MEAS_DELTA_MAX_MV;
@@ -1432,6 +1436,30 @@
 		}
 	}
 
+	if (type == PLUG_TYPE_HEADSET && dgnd && !dgnd->mic_bias) {
+		/* if plug type is Headphone report as GND_MIC_SWAP */
+		if (dgnd->_type == PLUG_TYPE_HEADPHONE) {
+			pr_debug("%s: GND_MIC_SWAP\n", __func__);
+			type = PLUG_TYPE_GND_MIC_SWAP;
+			/*
+			 * if type is GND_MIC_SWAP we should not check
+			 * HPHL status hence goto exit
+			 */
+			goto exit;
+		} else if (dgnd->_type != PLUG_TYPE_HEADSET && !dmicbias) {
+			pr_debug("%s: Invalid, inconsistent types\n", __func__);
+			type = PLUG_TYPE_INVALID;
+		}
+	}
+
+	if (event_state & (1 << MBHC_EVENT_PA_HPHL)) {
+		pr_debug("%s: HPHL PA was ON\n", __func__);
+	} else if (ch != sz && ch > 0) {
+		pr_debug("%s: Invalid, inconsistent HPHL..\n", __func__);
+		type = PLUG_TYPE_INVALID;
+		goto exit;
+	}
+
 	if (!(event_state & (1UL << MBHC_EVENT_PA_HPHL))) {
 		if (((type == PLUG_TYPE_HEADSET ||
 		      type == PLUG_TYPE_HEADPHONE) && ch != sz)) {
@@ -1440,17 +1468,6 @@
 			type = PLUG_TYPE_INVALID;
 		}
 	}
-	if (type == PLUG_TYPE_HEADSET && dgnd && !dgnd->mic_bias) {
-		if ((dgnd->_vdces + WCD9XXX_CS_GM_SWAP_THRES_MIN_MV <
-		     minv) &&
-		    (dgnd->_vdces + WCD9XXX_CS_GM_SWAP_THRES_MAX_MV >
-		     maxv))
-			type = PLUG_TYPE_GND_MIC_SWAP;
-		else if (dgnd->_type != PLUG_TYPE_HEADSET && !dmicbias) {
-			pr_debug("%s: Invalid, inconsistent types\n", __func__);
-			type = PLUG_TYPE_INVALID;
-		}
-	}
 exit:
 	pr_debug("%s: Plug type %d detected\n", __func__, type);
 	return type;
@@ -3148,15 +3165,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/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..4c3a72e 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -2203,6 +2203,53 @@
 		.codec_name = "snd-soc-dummy",
 	},
 	{
+		.name = "Voice2",
+		.stream_name = "Voice2",
+		.cpu_dai_name   = "Voice2",
+		.platform_name  = "msm-pcm-voice",
+		.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 dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.be_id = MSM_FRONTEND_DAI_VOICE2,
+	},
+	{
+		.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-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index 7935100..c83e623 100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -66,6 +66,7 @@
 	int32_t stream_opened[2];
 	uint32_t initial_samples_drop;
 	uint32_t trailing_samples_drop;
+	uint32_t gapless_transition;
 };
 
 struct msm_compr_pdata {
@@ -801,21 +802,10 @@
 				__func__, rc);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
-		pr_debug("%s: SNDRV_PCM_TRIGGER_STOP\n", __func__);
 		spin_lock_irqsave(&prtd->lock, flags);
-
+		pr_debug("%s: SNDRV_PCM_TRIGGER_STOP transition %d\n", __func__,
+					prtd->gapless_state.gapless_transition);
 		stream_id = ac->stream_id;
-		if (prtd->gapless_state.set_next_stream_id &&
-		    prtd->first_buffer) {
-			/*
-			 * Stream just switched for gapless, no buffers sent.
-			 * So seek needs to be applied to previous stream
-			 */
-			pr_debug("Seek previous stream as next stream hasn't started\n");
-			stream_id = stream_id^1;
-			ac->stream_id = stream_id;
-			prtd->first_buffer = 0;
-		}
 		atomic_set(&prtd->start, 0);
 		if (atomic_read(&prtd->eos)) {
 			pr_debug("%s: interrupt eos wait queues", __func__);
@@ -833,22 +823,27 @@
 		prtd->last_buffer = 0;
 		pr_debug("issue CMD_FLUSH\n");
 		prtd->cmd_ack = 0;
-		spin_unlock_irqrestore(&prtd->lock, flags);
-		rc = q6asm_stream_cmd(prtd->audio_client, CMD_FLUSH, stream_id);
-		if (rc < 0) {
-			pr_err("%s: flush cmd failed rc=%d\n",
-			       __func__, rc);
-			return rc;
-		}
-		rc = wait_event_timeout(prtd->flush_wait,
+		if (!prtd->gapless_state.gapless_transition) {
+			spin_unlock_irqrestore(&prtd->lock, flags);
+			rc = q6asm_stream_cmd(
+				prtd->audio_client, CMD_FLUSH, stream_id);
+			if (rc < 0) {
+				pr_err("%s: flush cmd failed rc=%d\n",
+							__func__, rc);
+				return rc;
+			}
+			rc = wait_event_timeout(prtd->flush_wait,
 					prtd->cmd_ack, 1 * HZ);
-		if (!rc) {
-			rc = -ETIMEDOUT;
-			pr_err("Flush cmd timeout\n");
-		} else
-			rc = 0; /* prtd->cmd_status == OK? 0 : -EPERM */
-
-		spin_lock_irqsave(&prtd->lock, flags);
+			if (!rc) {
+				rc = -ETIMEDOUT;
+				pr_err("Flush cmd timeout\n");
+			} else {
+				rc = 0; /* prtd->cmd_status == OK? 0 : -EPERM*/
+			}
+			spin_lock_irqsave(&prtd->lock, flags);
+		} else {
+			prtd->first_buffer = 0;
+		}
 		/* FIXME. only reset if flush was successful */
 		prtd->byte_offset  = 0;
 		prtd->copied_total = 0;
@@ -858,14 +853,20 @@
 		spin_unlock_irqrestore(&prtd->lock, flags);
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		pr_debug("SNDRV_PCM_TRIGGER_PAUSE_PUSH\n");
-		q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE);
-		atomic_set(&prtd->start, 0);
+		pr_debug("SNDRV_PCM_TRIGGER_PAUSE_PUSH transition %d\n",
+				prtd->gapless_state.gapless_transition);
+		if (!prtd->gapless_state.gapless_transition) {
+			q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE);
+			atomic_set(&prtd->start, 0);
+		}
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		pr_debug("SNDRV_PCM_TRIGGER_PAUSE_RELEASE\n");
-		atomic_set(&prtd->start, 1);
-		q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
+		pr_debug("SNDRV_PCM_TRIGGER_PAUSE_RELEASE transition %d\n",
+				   prtd->gapless_state.gapless_transition);
+		if (!prtd->gapless_state.gapless_transition) {
+			atomic_set(&prtd->start, 1);
+			q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
+		}
 		break;
 	case SND_COMPR_TRIGGER_PARTIAL_DRAIN:
 		pr_debug("%s: SND_COMPR_TRIGGER_PARTIAL_DRAIN\n", __func__);
@@ -926,7 +927,6 @@
 
 			/* send EOS */
 			prtd->cmd_ack = 0;
-			atomic_set(&prtd->eos, 1);
 			q6asm_cmd_nowait(prtd->audio_client, CMD_EOS);
 			pr_info("PARTIAL DRAIN, do not wait for EOS ack\n");
 
@@ -970,6 +970,7 @@
 			prtd->app_pointer  = 0;
 			prtd->first_buffer = 1;
 			prtd->last_buffer = 0;
+			prtd->gapless_state.gapless_transition = 1;
 			/*
 			Don't reset these as these vars map to
 			total_bytes_transferred and total_bytes_available
@@ -1042,7 +1043,6 @@
 			prtd->first_buffer = 1;
 			prtd->last_buffer = 0;
 			atomic_set(&prtd->drain, 0);
-			atomic_set(&prtd->xrun, 1);
 			q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
 			spin_unlock_irqrestore(&prtd->lock, flags);
 		}
@@ -1226,7 +1226,8 @@
 	 * since the available bytes fits fragment_size, copy the data right away
 	 */
 	spin_lock_irqsave(&prtd->lock, flags);
-
+	if (prtd->gapless_state.gapless_transition)
+		prtd->gapless_state.gapless_transition = 0;
 	prtd->bytes_received += count;
 	if (atomic_read(&prtd->start)) {
 		if (atomic_read(&prtd->xrun)) {
diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c
index 3f57078..ff82299 100644
--- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c
+++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c
@@ -170,6 +170,9 @@
 				 */
 				rc = -EFAULT;
 			} else {
+				if (!access_ok(VERIFY_READ, user,
+					sizeof(struct snd_lsm_event_status)))
+					rc = -EFAULT;
 				if (user->payload_size <
 				    event_status->payload_size) {
 					pr_debug("%s: provided %dbytes isn't enough, needs %dbytes\n",
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..32eaebf 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -25,6 +25,7 @@
 #include <sound/pcm.h>
 #include <sound/initval.h>
 #include <sound/control.h>
+#include <sound/q6audio-v2.h>
 #include <asm/dma.h>
 #include <linux/dma-mapping.h>
 #include <linux/msm_audio_ion.h>
@@ -109,6 +110,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 +171,32 @@
 		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));
+			prtd->pcm_irq_pos += prtd->pcm_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 +715,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 +772,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,
@@ -880,11 +918,12 @@
 	int rc;
 	int id;
 	struct msm_plat_data *pdata;
+	const char *latency_level;
 
 	rc = of_property_read_u32(pdev->dev.of_node,
-				"qcom,msm-pcm-dsp-id", &id);
+				"qti,msm-pcm-dsp-id", &id);
 	if (rc) {
-		dev_err(&pdev->dev, "%s: qcom,msm-pcm-dsp-id missing in DT node\n",
+		dev_err(&pdev->dev, "%s: qti,msm-pcm-dsp-id missing in DT node\n",
 					__func__);
 		return rc;
 	}
@@ -896,10 +935,17 @@
 	}
 
 	if (of_property_read_bool(pdev->dev.of_node,
-				"qcom,msm-pcm-low-latency"))
-		pdata->perf_mode = 1;
-	else
-		pdata->perf_mode = 0;
+				"qti,msm-pcm-low-latency")) {
+
+		pdata->perf_mode = LOW_LATENCY_PCM_MODE;
+		rc = of_property_read_string(pdev->dev.of_node,
+			"qti,latency-level", &latency_level);
+		if (!rc) {
+			if (!strcmp(latency_level, "ultra"))
+				pdata->perf_mode = ULTRA_LOW_LATENCY_PCM_MODE;
+		}
+	} else
+		pdata->perf_mode = LEGACY_PCM_MODE;
 
 	dev_set_drvdata(&pdev->dev, pdata);
 
@@ -921,7 +967,7 @@
 	return 0;
 }
 static const struct of_device_id msm_pcm_dt_match[] = {
-	{.compatible = "qcom,msm-pcm-dsp"},
+	{.compatible = "qti,msm-pcm-dsp"},
 	{}
 };
 MODULE_DEVICE_TABLE(of, msm_pcm_dt_match);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 537719f..91c0744 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -50,6 +50,12 @@
 	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
@@ -250,31 +256,41 @@
 
 
 /* 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.
  * Performance mode is only valid when session is valid.
  */
-static bool fe_dai_perf_mode[MSM_FRONTEND_DAI_MM_SIZE][2];
+static int fe_dai_perf_mode[MSM_FRONTEND_DAI_MM_SIZE][2];
 
 static uint8_t is_be_dai_extproc(int be_dai)
 {
@@ -287,7 +303,7 @@
 }
 
 static void msm_pcm_routing_build_matrix(int fedai_id, int dspst_id,
-	int path_type, bool perf_mode)
+	int path_type, int perf_mode)
 {
 	int i, port_type;
 	struct route_payload payload;
@@ -334,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) &&
@@ -349,7 +365,7 @@
 	mutex_unlock(&routing_lock);
 }
 
-void msm_pcm_routing_reg_phy_stream(int fedai_id, bool perf_mode,
+void msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode,
 					int dspst_id, int stream_type)
 {
 	int i, session_type, path_type, port_type, port_id, topology;
@@ -376,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 */
@@ -421,7 +437,7 @@
 			port_id = srs_port_id = msm_bedais[i].port_id;
 			srs_send_params(srs_port_id, 1, 0);
 			if ((DOLBY_ADM_COPP_TOPOLOGY_ID == topology) &&
-			    (!perf_mode))
+			    (perf_mode == LEGACY_PCM_MODE))
 				if (dolby_dap_init(port_id,
 						msm_bedais[i].channel) < 0)
 					pr_err("%s: Err init dolby dap\n",
@@ -435,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;
@@ -465,13 +494,14 @@
 			adm_close(msm_bedais[i].port_id,
 				  fe_dai_perf_mode[fedai_id][session_type]);
 			if ((DOLBY_ADM_COPP_TOPOLOGY_ID == topology) &&
-			    (fe_dai_perf_mode[fedai_id][session_type] == false))
+			    (fe_dai_perf_mode[fedai_id][session_type] ==
+							LEGACY_PCM_MODE))
 				dolby_dap_deinit(msm_bedais[i].port_id);
 		}
 	}
 
-	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);
 }
 
@@ -497,6 +527,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);
 
@@ -523,10 +554,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;
 
@@ -549,13 +593,20 @@
 				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);
 			if ((DOLBY_ADM_COPP_TOPOLOGY_ID == topology) &&
-			    (fe_dai_perf_mode[val][session_type] == false))
+			    (fe_dai_perf_mode[val][session_type] ==
+							LEGACY_PCM_MODE))
 				if (dolby_dap_init(port_id, channels) < 0)
 					pr_err("%s: Err init dolby dap\n",
 						__func__);
@@ -566,15 +617,17 @@
 			(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]);
 			if ((DOLBY_ADM_COPP_TOPOLOGY_ID == topology) &&
-			    (fe_dai_perf_mode[val][session_type] == false))
+			    (fe_dai_perf_mode[val][session_type] ==
+							LEGACY_PCM_MODE))
 				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]);
 		}
 	}
@@ -1203,12 +1256,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;
 	}
 
@@ -2034,6 +2087,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,
@@ -3040,6 +3102,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),
@@ -3068,6 +3131,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),
@@ -3218,6 +3285,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,
@@ -3474,6 +3543,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"},
@@ -3484,6 +3554,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"},
@@ -3516,6 +3587,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"},
@@ -3527,6 +3599,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"},
@@ -3716,6 +3789,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"},
@@ -3881,12 +3956,15 @@
 	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;
 			if ((DOLBY_ADM_COPP_TOPOLOGY_ID == topology) &&
-			    (fe_dai_perf_mode[i][session_type] == false))
+			    (fe_dai_perf_mode[i][session_type] ==
+							LEGACY_PCM_MODE))
 				dolby_dap_deinit(bedai->port_id);
 		}
 	}
@@ -3908,6 +3986,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);
@@ -3939,8 +4018,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;
@@ -3967,12 +4059,13 @@
 			}
 
 			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);
 			if ((DOLBY_ADM_COPP_TOPOLOGY_ID == topology) &&
-			    (fe_dai_perf_mode[i][session_type] == false))
+			    (fe_dai_perf_mode[i][session_type] ==
+							LEGACY_PCM_MODE))
 				if (dolby_dap_init(port_id, channels) < 0)
 					pr_err("%s: Err init dolby dap\n",
 						__func__);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
index 10be150..54f5e4a 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
@@ -133,15 +133,30 @@
 	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
  */
-void msm_pcm_routing_reg_phy_stream(int fedai_id, bool perf_mode, int dspst_id,
+void msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, int dspst_id,
 	int stream_type);
 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/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index 6cb7ce1..54b1263 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -702,7 +702,8 @@
 	return;
 }
 
-static int send_adm_cal_block(int port_id, struct acdb_cal_block *aud_cal)
+static int send_adm_cal_block(int port_id, struct acdb_cal_block *aud_cal,
+			      int perf_mode)
 {
 	s32				result = 0;
 	struct adm_cmd_set_pp_params_v5	adm_params;
@@ -731,7 +732,14 @@
 	adm_params.hdr.src_port = port_id;
 	adm_params.hdr.dest_svc = APR_SVC_ADM;
 	adm_params.hdr.dest_domain = APR_DOMAIN_ADSP;
-	adm_params.hdr.dest_port = atomic_read(&this_adm.copp_id[index]);
+
+	if (perf_mode == LEGACY_PCM_MODE)
+		adm_params.hdr.dest_port =
+			atomic_read(&this_adm.copp_id[index]);
+	else
+		adm_params.hdr.dest_port =
+			atomic_read(&this_adm.copp_low_latency_id[index]);
+
 	adm_params.hdr.token = port_id;
 	adm_params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
 	adm_params.payload_addr_lsw = aud_cal->cal_paddr;
@@ -767,7 +775,7 @@
 	return result;
 }
 
-static void send_adm_cal(int port_id, int path)
+static void send_adm_cal(int port_id, int path, int perf_mode)
 {
 	int			result = 0;
 	s32			acdb_path;
@@ -808,7 +816,7 @@
 		}
 	}
 
-	if (!send_adm_cal_block(port_id, &aud_cal))
+	if (!send_adm_cal_block(port_id, &aud_cal, perf_mode))
 		pr_debug("%s: Audproc cal sent for port id: %#x, path %d\n",
 			__func__, port_id, acdb_path);
 	else
@@ -842,7 +850,7 @@
 		}
 	}
 
-	if (!send_adm_cal_block(port_id, &aud_cal))
+	if (!send_adm_cal_block(port_id, &aud_cal, perf_mode))
 		pr_debug("%s: Audvol cal sent for port id: %#x, path %d\n",
 			__func__, port_id, acdb_path);
 	else
@@ -1048,7 +1056,7 @@
 }
 
 int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
-			bool perf_mode, uint16_t bits_per_sample)
+			int perf_mode, uint16_t bits_per_sample)
 {
 	struct adm_cmd_device_open_v5	open;
 	int ret = 0;
@@ -1079,7 +1087,7 @@
 		rtac_set_adm_handle(this_adm.apr);
 	}
 
-	if (!perf_mode) {
+	if (perf_mode == LEGACY_PCM_MODE) {
 		atomic_set(&this_adm.copp_perf_mode[index], 0);
 		send_adm_custom_topology(port_id);
 	} else {
@@ -1087,8 +1095,9 @@
 	}
 
 	/* Create a COPP if port id are not enabled */
-	if ((!perf_mode && (atomic_read(&this_adm.copp_cnt[index]) == 0)) ||
-		(perf_mode &&
+	if ((perf_mode == LEGACY_PCM_MODE &&
+		(atomic_read(&this_adm.copp_cnt[index]) == 0)) ||
+		(perf_mode != LEGACY_PCM_MODE &&
 		(atomic_read(&this_adm.copp_low_latency_cnt[index]) == 0))) {
 		pr_debug("%s:opening ADM: perf_mode: %d\n", __func__,
 			perf_mode);
@@ -1103,12 +1112,12 @@
 		open.hdr.dest_port = tmp_port;
 		open.hdr.token = port_id;
 		open.hdr.opcode = ADM_CMD_DEVICE_OPEN_V5;
-		open.flags = 0x00;
-		if (perf_mode) {
-			open.flags |= ADM_ULTRA_LOW_LATENCY_DEVICE_SESSION;
-		} else {
-			open.flags |= ADM_LEGACY_DEVICE_SESSION;
-		}
+		if (perf_mode == ULTRA_LOW_LATENCY_PCM_MODE)
+			open.flags = ADM_ULTRA_LOW_LATENCY_DEVICE_SESSION;
+		else if (perf_mode == LOW_LATENCY_PCM_MODE)
+			open.flags = ADM_LOW_LATENCY_DEVICE_SESSION;
+		else
+			open.flags = ADM_LEGACY_DEVICE_SESSION;
 
 		open.mode_of_operation = path;
 		open.endpoint_id_1 = tmp_port;
@@ -1125,7 +1134,7 @@
 			(open.topology_id == VPM_TX_DM_FLUENCE_COPP_TOPOLOGY))
 				rate = 16000;
 
-		if (perf_mode) {
+		if (perf_mode == ULTRA_LOW_LATENCY_PCM_MODE) {
 			open.topology_id = NULL_COPP_TOPOLOGY;
 			rate = ULL_SUPPORTED_SAMPLE_RATE;
 			if(channel_mode > ULL_MAX_SUPPORTED_CHANNEL)
@@ -1133,7 +1142,8 @@
 		}
 		open.dev_num_channel = channel_mode & 0x00FF;
 		open.bit_width = bits_per_sample;
-		WARN_ON(perf_mode && (rate != 48000));
+		WARN_ON(perf_mode == ULTRA_LOW_LATENCY_PCM_MODE &&
+							(rate != 48000));
 		open.sample_rate  = rate;
 		memset(open.dev_channel_mapping, 0, 8);
 
@@ -1208,7 +1218,8 @@
 			goto fail_cmd;
 		}
 	}
-	if (perf_mode) {
+	if (perf_mode == ULTRA_LOW_LATENCY_PCM_MODE ||
+			perf_mode == LOW_LATENCY_PCM_MODE) {
 		atomic_inc(&this_adm.copp_low_latency_cnt[index]);
 		pr_debug("%s: index: %d coppid: %d", __func__, index,
 			atomic_read(&this_adm.copp_low_latency_id[index]));
@@ -1225,7 +1236,7 @@
 }
 
 int adm_multi_ch_copp_open(int port_id, int path, int rate, int channel_mode,
-			int topology, bool perf_mode, uint16_t bits_per_sample)
+			int topology, int perf_mode, uint16_t bits_per_sample)
 {
 	int ret = 0;
 
@@ -1236,7 +1247,7 @@
 }
 
 int adm_matrix_map(int session_id, int path, int num_copps,
-			unsigned int *port_id, int copp_id, bool perf_mode)
+			unsigned int *port_id, int copp_id, int perf_mode)
 {
 	struct adm_cmd_matrix_map_routings_v5	*route;
 	struct adm_session_map_node_v5 *node;
@@ -1275,7 +1286,8 @@
 	route->hdr.src_port = copp_id;
 	route->hdr.dest_svc = APR_SVC_ADM;
 	route->hdr.dest_domain = APR_DOMAIN_ADSP;
-	if (perf_mode) {
+	if (perf_mode == ULTRA_LOW_LATENCY_PCM_MODE ||
+			perf_mode == LOW_LATENCY_PCM_MODE) {
 		route->hdr.dest_port =
 			atomic_read(&this_adm.copp_low_latency_id[index]);
 	} else {
@@ -1313,7 +1325,8 @@
 
 
 		if (tmp >= 0 && tmp < AFE_MAX_PORTS) {
-			if (perf_mode)
+			if (perf_mode == ULTRA_LOW_LATENCY_PCM_MODE ||
+					perf_mode == LOW_LATENCY_PCM_MODE)
 				copps_list[i] =
 				atomic_read(&this_adm.copp_low_latency_id[tmp]);
 			else
@@ -1323,8 +1336,7 @@
 		else
 			continue;
 		pr_debug("%s: port_id[%#x]: %d, index: %d act coppid[0x%x]\n",
-			__func__, i, port_id[i], tmp,
-			atomic_read(&this_adm.copp_id[tmp]));
+			__func__, i, port_id[i], tmp, copps_list[i]);
 	}
 	atomic_set(&this_adm.copp_stat[index], 0);
 
@@ -1344,25 +1356,31 @@
 		ret = -EINVAL;
 		goto fail_cmd;
 	}
-	if (!perf_mode) {
+
+	if (perf_mode != ULTRA_LOW_LATENCY_PCM_MODE) {
 		for (i = 0; i < num_copps; i++)
-			send_adm_cal(port_id[i], path);
+			send_adm_cal(port_id[i], path, perf_mode);
 
 		for (i = 0; i < num_copps; i++) {
-			int tmp;
+			int tmp, copp_id;
 			tmp = afe_get_port_index(port_id[i]);
 			if (tmp >= 0 && tmp < AFE_MAX_PORTS) {
+				if (perf_mode == LEGACY_PCM_MODE)
+					copp_id = atomic_read(
+					&this_adm.copp_id[tmp]);
+				else
+					copp_id = atomic_read(
+					&this_adm.copp_low_latency_id[tmp]);
 				rtac_add_adm_device(port_id[i],
-					atomic_read(&this_adm.copp_id[tmp]),
-					path, session_id);
-				pr_debug("%s, copp_id: %d\n", __func__,
-					atomic_read(&this_adm.copp_id[tmp]));
-			} else {
+						copp_id, path, session_id);
+				pr_debug("%s, copp_id: %d\n",
+							__func__, copp_id);
+			} else
 				pr_debug("%s: Invalid port index %d",
-					__func__, tmp);
-			}
+							__func__, tmp);
 		}
 	}
+
 fail_cmd:
 	kfree(matrix_map);
 	return ret;
@@ -1514,8 +1532,26 @@
 	return ret;
 }
 
+#ifdef CONFIG_RTAC
 int adm_get_copp_id(int port_index)
 {
+	int copp_id;
+	pr_debug("%s\n", __func__);
+
+	if (port_index < 0) {
+		pr_err("%s: invalid port_id = %d\n", __func__, port_index);
+		return -EINVAL;
+	}
+
+	copp_id = atomic_read(&this_adm.copp_id[port_index]);
+	if (copp_id == RESET_COPP_ID)
+		copp_id = atomic_read(
+			&this_adm.copp_low_latency_id[port_index]);
+	return copp_id;
+}
+
+int adm_get_lowlatency_copp_id(int port_index)
+{
 	pr_debug("%s\n", __func__);
 
 	if (port_index < 0) {
@@ -1523,8 +1559,19 @@
 		return -EINVAL;
 	}
 
-	return atomic_read(&this_adm.copp_id[port_index]);
+	return atomic_read(&this_adm.copp_low_latency_id[port_index]);
 }
+#else
+int adm_get_copp_id(int port_index)
+{
+	return -EINVAL;
+}
+
+int adm_get_lowlatency_copp_id(int port_index)
+{
+	return -EINVAL;
+}
+#endif /* #ifdef CONFIG_RTAC */
 
 void adm_ec_ref_rx_id(int port_id)
 {
@@ -1532,12 +1579,13 @@
 	pr_debug("%s ec_ref_rx:%d", __func__, this_adm.ec_ref_rx);
 }
 
-int adm_close(int port_id, bool perf_mode)
+int adm_close(int port_id, int perf_mode)
 {
 	struct apr_hdr close;
 
 	int ret = 0;
 	int index = 0;
+	int copp_id = RESET_COPP_ID;
 
 	port_id = q6audio_convert_virtual_to_portid(port_id);
 
@@ -1548,7 +1596,8 @@
 	pr_debug("%s port_id=%#x index %d perf_mode: %d\n", __func__, port_id,
 		index, perf_mode);
 
-	if (perf_mode) {
+	if (perf_mode == ULTRA_LOW_LATENCY_PCM_MODE ||
+				perf_mode == LOW_LATENCY_PCM_MODE) {
 		if (!(atomic_read(&this_adm.copp_low_latency_cnt[index]))) {
 			pr_err("%s: copp count for port[%#x]is 0\n", __func__,
 				port_id);
@@ -1563,8 +1612,9 @@
 		}
 		atomic_dec(&this_adm.copp_cnt[index]);
 	}
-	if ((!perf_mode && !(atomic_read(&this_adm.copp_cnt[index]))) ||
-		(perf_mode &&
+	if ((perf_mode == LEGACY_PCM_MODE &&
+		!(atomic_read(&this_adm.copp_cnt[index]))) ||
+		((perf_mode != LEGACY_PCM_MODE) &&
 		!(atomic_read(&this_adm.copp_low_latency_cnt[index])))) {
 
 		pr_debug("%s:Closing ADM: perf_mode: %d\n", __func__,
@@ -1577,7 +1627,8 @@
 		close.src_port = port_id;
 		close.dest_svc = APR_SVC_ADM;
 		close.dest_domain = APR_DOMAIN_ADSP;
-		if (perf_mode)
+		if (perf_mode == ULTRA_LOW_LATENCY_PCM_MODE ||
+				perf_mode == LOW_LATENCY_PCM_MODE)
 			close.dest_port =
 			     atomic_read(&this_adm.copp_low_latency_id[index]);
 		else
@@ -1587,18 +1638,23 @@
 
 		atomic_set(&this_adm.copp_stat[index], 0);
 
-		if (perf_mode) {
+		if (perf_mode == ULTRA_LOW_LATENCY_PCM_MODE ||
+				perf_mode == LOW_LATENCY_PCM_MODE) {
+			copp_id = atomic_read(
+				&this_adm.copp_low_latency_id[index]);
 			pr_debug("%s:coppid %d portid=%#x index=%d coppcnt=%d\n",
-			    __func__,
-			    atomic_read(&this_adm.copp_low_latency_id[index]),
-			    port_id, index,
-			    atomic_read(&this_adm.copp_low_latency_cnt[index]));
+				__func__,
+				copp_id,
+				port_id, index,
+				atomic_read(
+					&this_adm.copp_low_latency_cnt[index]));
 			atomic_set(&this_adm.copp_low_latency_id[index],
 				RESET_COPP_ID);
 		} else {
+			copp_id = atomic_read(&this_adm.copp_id[index]);
 			pr_debug("%s:coppid %d portid=%#x index=%d coppcnt=%d\n",
 				__func__,
-				atomic_read(&this_adm.copp_id[index]),
+				copp_id,
 				port_id, index,
 				atomic_read(&this_adm.copp_cnt[index]));
 			atomic_set(&this_adm.copp_id[index],
@@ -1623,9 +1679,9 @@
 		}
 	}
 
-	if (!perf_mode) {
+	if (perf_mode != ULTRA_LOW_LATENCY_PCM_MODE) {
 		pr_debug("%s: remove adm device from rtac\n", __func__);
-		rtac_remove_adm_device(port_id);
+		rtac_remove_adm_device(port_id, copp_id);
 	}
 
 fail_cmd:
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 95114e0..24f5f3b 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -39,6 +39,7 @@
 
 #include <sound/apr_audio-v2.h>
 #include <sound/q6asm-v2.h>
+#include <sound/q6audio-v2.h>
 
 #include "audio_acdb.h"
 
@@ -354,7 +355,7 @@
 	session[ac->session] = 0;
 	mutex_unlock(&session_lock);
 	ac->session = 0;
-	ac->perf_mode = 0;
+	ac->perf_mode = LEGACY_PCM_MODE;
 	ac->fptr_cache_ops = NULL;
 	return;
 }
@@ -810,7 +811,7 @@
 	ac->cb = cb;
 	ac->priv = priv;
 	ac->io_mode = SYNC_IO_MODE;
-	ac->perf_mode = false;
+	ac->perf_mode = LEGACY_PCM_MODE;
 	ac->fptr_cache_ops = NULL;
 	ac->apr = apr_register("ADSP", "ASM", \
 				(apr_fn)q6asm_callback,\
@@ -1256,6 +1257,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:
@@ -1694,7 +1696,7 @@
 	open.bits_per_sample = bits_per_sample;
 	open.mode_flags = 0x0;
 
-	if (ac->perf_mode) {
+	if (ac->perf_mode == LOW_LATENCY_PCM_MODE) {
 		open.mode_flags |= ASM_LOW_LATENCY_STREAM_SESSION <<
 				ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ;
 	} else {
@@ -1744,6 +1746,7 @@
 			rc);
 		goto fail_cmd;
 	}
+	ac->io_mode |= TUN_READ_IO_MODE;
 	return 0;
 fail_cmd:
 	return -EINVAL;
@@ -1779,8 +1782,10 @@
 
 	open.hdr.opcode = ASM_STREAM_CMD_OPEN_WRITE_V3;
 	open.mode_flags = 0x00;
-	if (ac->perf_mode)
+	if (ac->perf_mode == ULTRA_LOW_LATENCY_PCM_MODE)
 		open.mode_flags |= ASM_ULTRA_LOW_LATENCY_STREAM_SESSION;
+	else if (ac->perf_mode == LOW_LATENCY_PCM_MODE)
+		open.mode_flags |= ASM_LOW_LATENCY_STREAM_SESSION;
 	else {
 		open.mode_flags |= ASM_LEGACY_STREAM_SESSION;
 		if (is_gapless_mode)
@@ -1837,6 +1842,7 @@
 			rc);
 		goto fail_cmd;
 	}
+	ac->io_mode |= TUN_WRITE_IO_MODE;
 	return 0;
 fail_cmd:
 	return -EINVAL;
@@ -1977,6 +1983,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 +4266,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 +4280,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/rtac.c b/sound/soc/msm/qdsp6v2/rtac.c
index f74dbe2..701dfef 100644
--- a/sound/soc/msm/qdsp6v2/rtac.c
+++ b/sound/soc/msm/qdsp6v2/rtac.c
@@ -556,7 +556,8 @@
 	/* Check if device already added */
 	if (rtac_adm_data.num_of_dev != 0) {
 		for (; i < rtac_adm_data.num_of_dev; i++) {
-			if (rtac_adm_data.device[i].afe_port == port_id) {
+			if (rtac_adm_data.device[i].afe_port == port_id &&
+			    rtac_adm_data.device[i].copp == copp_id) {
 				add_popp(i, port_id, popp_id);
 				goto done;
 			}
@@ -609,7 +610,7 @@
 	}
 }
 
-void rtac_remove_adm_device(u32 port_id)
+void rtac_remove_adm_device(u32 port_id, u32 copp_id)
 {
 	s32 i;
 	pr_debug("%s: port_id = %d\n", __func__, port_id);
@@ -619,7 +620,8 @@
 
 	/* look for device */
 	for (i = 0; i < rtac_adm_data.num_of_dev; i++) {
-		if (rtac_adm_data.device[i].afe_port == port_id) {
+		if (rtac_adm_data.device[i].afe_port == port_id &&
+		    rtac_adm_data.device[i].copp == copp_id) {
 			memset(&rtac_adm_data.device[i], 0,
 				   sizeof(rtac_adm_data.device[i]));
 			rtac_adm_data.num_of_dev--;
@@ -870,6 +872,8 @@
 	for (port_index = 0; port_index < AFE_MAX_PORTS; port_index++) {
 		if (adm_get_copp_id(port_index) == copp_id)
 			break;
+		if (adm_get_lowlatency_copp_id(port_index) == copp_id)
+			break;
 	}
 	if (port_index >= AFE_MAX_PORTS) {
 		pr_err("%s: Could not find port index for copp = %d\n",
diff --git a/sound/usb/card.c b/sound/usb/card.c
index f453dbd..d419e2f 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -205,11 +205,24 @@
 	struct usb_device *dev = chip->dev;
 	struct usb_host_interface *host_iface;
 	struct usb_interface_descriptor *altsd;
+	struct usb_interface *usb_iface;
 	void *control_header;
 	int i, protocol;
 
+	usb_iface = usb_ifnum_to_if(dev, ctrlif);
+	if (!usb_iface) {
+		snd_printk(KERN_ERR "%d:%u : does not exist\n",
+					dev->devnum, ctrlif);
+		return -EINVAL;
+	}
+
 	/* find audiocontrol interface */
-	host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0];
+	host_iface = &usb_iface->altsetting[0];
+	if (!host_iface) {
+		snd_printk(KERN_ERR "Audio Control interface is not available.");
+		return -EINVAL;
+	}
+
 	control_header = snd_usb_find_csint_desc(host_iface->extra,
 						 host_iface->extralen,
 						 NULL, UAC_HEADER);
@@ -248,8 +261,7 @@
 
 	case UAC_VERSION_2: {
 		struct usb_interface_assoc_descriptor *assoc =
-			usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
-
+						usb_iface->intf_assoc;
 		if (!assoc) {
 			snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n");
 			return -EINVAL;
@@ -723,6 +735,11 @@
 	}
 
 	usbaudiosdev = kzalloc(sizeof(*usbaudiosdev), GFP_KERNEL);
+	if (!usbaudiosdev) {
+		pr_err("Usb audio device memory allocation failed.\n");
+		return -ENOMEM;
+	}
+
 	usbaudiosdev->name = "usb_audio";
 
 	err = switch_dev_register(usbaudiosdev);